This repository has been archived by the owner on Oct 3, 2023. It is now read-only.
forked from stacksmashing/tamarin-firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
usb_descriptors.c
170 lines (137 loc) · 5.7 KB
/
usb_descriptors.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
* Licensed under GNU Public License v3
* Copyright (c) 2022 Thomas Roth <[email protected]>
* Based on:
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
*/
#include "tusb.h"
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
*
* Auto ProductID layout's Bitmap:
* [MSB] MIDI | HID | MSC | CDC [LSB]
*/
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_PID 0x0004
// #define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
// _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
#define USB_VID 0x2B3E
#define USB_BCD 0x2342
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t const desc_device =
{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = USB_BCD,
// Use Interface Association Descriptor (IAD) for CDC
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USB_VID,
.idProduct = USB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const * tud_descriptor_device_cb(void)
{
return (uint8_t const *) &desc_device;
}
//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
enum
{
ITF_NUM_CDC_0 = 0,
ITF_NUM_CDC_0_DATA,
ITF_NUM_PROBE,
ITF_NUM_CDC_1,
ITF_NUM_CDC_1_DATA,
// ITF_NUM_CDC_2_DATA,
ITF_NUM_TOTAL
};
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + (CFG_TUD_CDC * TUD_CDC_DESC_LEN) + TUD_VENDOR_DESC_LEN)
#define EPNUM_CDC_0_NOTIF 0x81
#define EPNUM_CDC_0_OUT 0x02
#define EPNUM_CDC_0_IN 0x83
#define EPNUM_CDC_1_NOTIF 0x86
#define EPNUM_CDC_1_OUT 0x07
#define EPNUM_CDC_1_IN 0x88
#define EPNUM_PROBE_OUT 0x04
#define EPNUM_PROBE_IN 0x85
// #define EPNUM_CDC_2_NOTIF 0x85
// #define EPNUM_CDC_2_OUT 0x06
// #define EPNUM_CDC_2_IN 0x86
uint8_t const desc_fs_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// 1st CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_0, 4, EPNUM_CDC_0_NOTIF, 8, EPNUM_CDC_0_OUT, EPNUM_CDC_0_IN, 64),
// 2nd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
// TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
// 3rd CDC: Interface number, string index, EP notification address and size, EP data address (out, in) and size.
// TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_2, 4, EPNUM_CDC_2_NOTIF, 8, EPNUM_CDC_2_OUT, EPNUM_CDC_2_IN, 64),
// 4th Vendor: Picoprobe interface
TUD_VENDOR_DESCRIPTOR(ITF_NUM_PROBE, 0, EPNUM_PROBE_OUT, EPNUM_PROBE_IN, 64),
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC_1, 4, EPNUM_CDC_1_NOTIF, 8, EPNUM_CDC_1_OUT, EPNUM_CDC_1_IN, 64),
};
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
{
(void) index; // for multiple configurations
return desc_fs_configuration;
}
//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+
// array of pointer to string descriptors
char const* string_desc_arr [] =
{
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"stacksmashing", // 1: Manufacturer
"Tamarin Cable", // 2: Product
"31337", // 3: Serials, should use chip ID
// "Tamarin CDC", // 4: CDC Interface
};
static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{
(void) langid;
uint8_t chr_count;
if ( index == 0)
{
memcpy(&_desc_str[1], string_desc_arr[0], 2);
chr_count = 1;
}else
{
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
const char* str = string_desc_arr[index];
// Cap at max char
chr_count = strlen(str);
if ( chr_count > 31 ) chr_count = 31;
// Convert ASCII string into UTF-16
for(uint8_t i=0; i<chr_count; i++)
{
_desc_str[1+i] = str[i];
}
}
// first byte is length (including header), second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
return _desc_str;
}