/elec/audio-switcher

To get this branch, use:
bzr branch http://bzr.ed.am/elec/audio-switcher

« back to all changes in this revision

Viewing changes to src/Descriptors.c

  • Committer: Tim Marston
  • Date: 2012-11-28 23:51:05 UTC
  • Revision ID: tim@ed.am-20121128235105-t82czxu8kbp3av2j
updated notes, and added control shell script

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
             LUFA Library
3
 
     Copyright (C) Dean Camera, 2012.
4
 
 
5
 
  dean [at] fourwalledcubicle [dot] com
6
 
           www.lufa-lib.org
 
2
 
 
3
  AUDIO SWITCHER
 
4
 
 
5
  Based on a serial device demonstration from the LUFA project
 
6
  (www.lufa-lib.org).  LUFA is Copyright (C) Dean Camera, 2012.
 
7
 
 
8
  Changes made to the serial device demonstration program are
 
9
  Copyright (C) Tim Marston, 2012.
 
10
 
 
11
  For more information:
 
12
    * see README, or
 
13
    * visit http://ed.am/
 
14
 
7
15
*/
8
16
 
9
17
/*
30
38
 
31
39
/** \file
32
40
 *
33
 
 *  USB Device Descriptors, for library use when in USB device mode. Descriptors are special
34
 
 *  computer-readable structures which the host requests upon device enumeration, to determine
35
 
 *  the device's capabilities and functions.
 
41
 *  USB Device Descriptors, for library use when in USB device mode.
 
42
 *  Descriptors are special computer-readable structures which the host
 
43
 *  requests upon device enumeration, to determine the device's capabilities
 
44
 *  and functions.
36
45
 */
37
46
 
38
47
#include "Descriptors.h"
39
48
 
40
49
 
41
 
/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
42
 
 *  device characteristics, including the supported USB version, control endpoint size and the
43
 
 *  number of device configurations. The descriptor is read out by the USB host when the enumeration
44
 
 *  process begins.
 
50
/** Device descriptor structure.  This descriptor, located in FLASH memory,
 
51
 *  describes the overall device characteristics, including the supported USB
 
52
 *  version, control endpoint size and the number of device configurations.
 
53
 *  The descriptor is read out by the USB host when the enumeration process
 
54
 *  begins.
45
55
 */
46
56
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
47
57
{
48
 
        .Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
 
58
        .Header                 = {
 
59
                .Size = sizeof(USB_Descriptor_Device_t),
 
60
                .Type = DTYPE_Device
 
61
        },
49
62
 
50
63
        .USBSpecification       = VERSION_BCD(01.10),
51
64
        .Class                  = CDC_CSCP_CDCClass,
55
68
        .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
56
69
 
57
70
        .VendorID               = 0x03EB,
58
 
        .ProductID              = 0x2044,
 
71
        .ProductID              = 0xba7f, // 0x2044,
59
72
        .ReleaseNumber          = VERSION_BCD(00.01),
60
73
 
61
74
        .ManufacturerStrIndex   = 0x01,
65
78
        .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
66
79
};
67
80
 
68
 
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
69
 
 *  of the device in one of its supported configurations, including information about any device interfaces
70
 
 *  and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
71
 
 *  a configuration so that the host may correctly communicate with the USB device.
 
81
/** Configuration descriptor structure. This descriptor, located in FLASH
 
82
 *  memory, describes the usage of the device in one of its supported
 
83
 *  configurations, including information about any device interfaces and
 
84
 *  endpoints.  The descriptor is read out by the USB host during the
 
85
 *  enumeration process when selecting a configuration so that the host may
 
86
 *  correctly communicate with the USB device.
72
87
 */
73
88
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
74
89
{
75
90
        .Config =
76
 
                {
77
 
                        .Header                 = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
78
 
 
79
 
                        .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
80
 
                        .TotalInterfaces        = 2,
81
 
 
82
 
                        .ConfigurationNumber    = 1,
83
 
                        .ConfigurationStrIndex  = NO_DESCRIPTOR,
84
 
 
85
 
                        .ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
86
 
 
87
 
                        .MaxPowerConsumption    = USB_CONFIG_POWER_MA(100)
 
91
        {
 
92
                .Header                 = {
 
93
                        .Size = sizeof(USB_Descriptor_Configuration_Header_t),
 
94
                        .Type = DTYPE_Configuration,
88
95
                },
89
96
 
 
97
                .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
 
98
                .TotalInterfaces        = 2,
 
99
 
 
100
                .ConfigurationNumber    = 1,
 
101
                .ConfigurationStrIndex  = NO_DESCRIPTOR,
 
102
 
 
103
                .ConfigAttributes       = (USB_CONFIG_ATTR_RESERVED |
 
104
                                                                   USB_CONFIG_ATTR_SELFPOWERED),
 
105
 
 
106
                .MaxPowerConsumption    = USB_CONFIG_POWER_MA(100),
 
107
        },
 
108
 
90
109
        .CDC_CCI_Interface =
91
 
                {
92
 
                        .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
93
 
 
94
 
                        .InterfaceNumber        = 0,
95
 
                        .AlternateSetting       = 0,
96
 
 
97
 
                        .TotalEndpoints         = 1,
98
 
 
99
 
                        .Class                  = CDC_CSCP_CDCClass,
100
 
                        .SubClass               = CDC_CSCP_ACMSubclass,
101
 
                        .Protocol               = CDC_CSCP_ATCommandProtocol,
102
 
 
103
 
                        .InterfaceStrIndex      = NO_DESCRIPTOR
 
110
        {
 
111
                .Header                 = {
 
112
                        .Size = sizeof(USB_Descriptor_Interface_t),
 
113
                        .Type = DTYPE_Interface,
104
114
                },
105
115
 
 
116
                .InterfaceNumber        = 0,
 
117
                .AlternateSetting       = 0,
 
118
 
 
119
                .TotalEndpoints         = 1,
 
120
 
 
121
                .Class                  = CDC_CSCP_CDCClass,
 
122
                .SubClass               = CDC_CSCP_ACMSubclass,
 
123
                .Protocol               = CDC_CSCP_ATCommandProtocol,
 
124
 
 
125
                .InterfaceStrIndex      = NO_DESCRIPTOR,
 
126
        },
 
127
 
106
128
        .CDC_Functional_Header =
107
 
                {
108
 
                        .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
109
 
                        .Subtype                = CDC_DSUBTYPE_CSInterface_Header,
110
 
 
111
 
                        .CDCSpecification       = VERSION_BCD(01.10),
 
129
        {
 
130
                .Header                 = {
 
131
                        .Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t),
 
132
                        .Type = DTYPE_CSInterface,
112
133
                },
113
134
 
 
135
                .Subtype                = CDC_DSUBTYPE_CSInterface_Header,
 
136
 
 
137
                .CDCSpecification       = VERSION_BCD(01.10),
 
138
        },
 
139
 
114
140
        .CDC_Functional_ACM =
115
 
                {
116
 
                        .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
117
 
                        .Subtype                = CDC_DSUBTYPE_CSInterface_ACM,
118
 
 
119
 
                        .Capabilities           = 0x06,
 
141
        {
 
142
                .Header                 = {
 
143
                        .Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t),
 
144
                        .Type = DTYPE_CSInterface,
120
145
                },
121
146
 
 
147
                .Subtype                = CDC_DSUBTYPE_CSInterface_ACM,
 
148
 
 
149
                .Capabilities           = 0x06,
 
150
        },
 
151
 
122
152
        .CDC_Functional_Union =
123
 
                {
124
 
                        .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
125
 
                        .Subtype                = CDC_DSUBTYPE_CSInterface_Union,
126
 
 
127
 
                        .MasterInterfaceNumber  = 0,
128
 
                        .SlaveInterfaceNumber   = 1,
 
153
        {
 
154
                .Header                 = {
 
155
                        .Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t),
 
156
                        .Type = DTYPE_CSInterface,
129
157
                },
130
158
 
 
159
                .Subtype                = CDC_DSUBTYPE_CSInterface_Union,
 
160
 
 
161
                .MasterInterfaceNumber  = 0,
 
162
                .SlaveInterfaceNumber   = 1,
 
163
        },
 
164
 
131
165
        .CDC_NotificationEndpoint =
132
 
                {
133
 
                        .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
134
 
 
135
 
                        .EndpointAddress        = CDC_NOTIFICATION_EPADDR,
136
 
                        .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
137
 
                        .EndpointSize           = CDC_NOTIFICATION_EPSIZE,
138
 
                        .PollingIntervalMS      = 0xFF
 
166
        {
 
167
                .Header                 = {
 
168
                        .Size = sizeof(USB_Descriptor_Endpoint_t),
 
169
                        .Type = DTYPE_Endpoint,
139
170
                },
140
171
 
 
172
                .EndpointAddress        = CDC_NOTIFICATION_EPADDR,
 
173
                .Attributes             = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | 
 
174
                                                                   ENDPOINT_USAGE_DATA),
 
175
                .EndpointSize           = CDC_NOTIFICATION_EPSIZE,
 
176
                .PollingIntervalMS      = 0xFF,
 
177
        },
 
178
 
141
179
        .CDC_DCI_Interface =
142
 
                {
143
 
                        .Header                 = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
144
 
 
145
 
                        .InterfaceNumber        = 1,
146
 
                        .AlternateSetting       = 0,
147
 
 
148
 
                        .TotalEndpoints         = 2,
149
 
 
150
 
                        .Class                  = CDC_CSCP_CDCDataClass,
151
 
                        .SubClass               = CDC_CSCP_NoDataSubclass,
152
 
                        .Protocol               = CDC_CSCP_NoDataProtocol,
153
 
 
154
 
                        .InterfaceStrIndex      = NO_DESCRIPTOR
 
180
        {
 
181
                .Header                 = {
 
182
                        .Size = sizeof(USB_Descriptor_Interface_t),
 
183
                        .Type = DTYPE_Interface,
155
184
                },
156
185
 
 
186
                .InterfaceNumber        = 1,
 
187
                .AlternateSetting       = 0,
 
188
 
 
189
                .TotalEndpoints         = 2,
 
190
 
 
191
                .Class                  = CDC_CSCP_CDCDataClass,
 
192
                .SubClass               = CDC_CSCP_NoDataSubclass,
 
193
                .Protocol               = CDC_CSCP_NoDataProtocol,
 
194
 
 
195
                .InterfaceStrIndex      = NO_DESCRIPTOR,
 
196
        },
 
197
 
157
198
        .CDC_DataOutEndpoint =
158
 
                {
159
 
                        .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
160
 
 
161
 
                        .EndpointAddress        = CDC_RX_EPADDR,
162
 
                        .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
163
 
                        .EndpointSize           = CDC_TXRX_EPSIZE,
164
 
                        .PollingIntervalMS      = 0x05
 
199
        {
 
200
                .Header                 = {
 
201
                        .Size = sizeof(USB_Descriptor_Endpoint_t),
 
202
                        .Type = DTYPE_Endpoint,
165
203
                },
166
204
 
 
205
                .EndpointAddress        = CDC_RX_EPADDR,
 
206
                .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC |
 
207
                                                                   ENDPOINT_USAGE_DATA),
 
208
                .EndpointSize           = CDC_TXRX_EPSIZE,
 
209
                .PollingIntervalMS      = 0x05,
 
210
        },
 
211
 
167
212
        .CDC_DataInEndpoint =
168
 
                {
169
 
                        .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
 
213
        {
 
214
                .Header                 = {
 
215
                        .Size = sizeof(USB_Descriptor_Endpoint_t),
 
216
                        .Type = DTYPE_Endpoint,
 
217
                },
170
218
 
171
 
                        .EndpointAddress        = CDC_TX_EPADDR,
172
 
                        .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
173
 
                        .EndpointSize           = CDC_TXRX_EPSIZE,
174
 
                        .PollingIntervalMS      = 0x05
175
 
                }
 
219
                .EndpointAddress        = CDC_TX_EPADDR,
 
220
                .Attributes             = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC |
 
221
                                                                   ENDPOINT_USAGE_DATA),
 
222
                .EndpointSize           = CDC_TXRX_EPSIZE,
 
223
                .PollingIntervalMS      = 0x05,
 
224
        }
176
225
};
177
226
 
178
 
/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
179
 
 *  the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
180
 
 *  via the language ID table available at USB.org what languages the device supports for its string descriptors.
 
227
/** Language descriptor structure.  This descriptor, located in FLASH memory,
 
228
 *  is returned when the host requests the string descriptor with index 0 (the
 
229
 *  first index).  It is actually an array of 16-bit integers, which indicate
 
230
 *  via the language ID table available at USB.org what languages the device
 
231
 *  supports for its string descriptors.
181
232
 */
182
233
const USB_Descriptor_String_t PROGMEM LanguageString =
183
234
{
184
 
        .Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
 
235
        .Header                 = {
 
236
                .Size = USB_STRING_LEN(1),
 
237
                .Type = DTYPE_String,
 
238
        },
185
239
 
186
240
        .UnicodeString          = {LANGUAGE_ID_ENG}
187
241
};
188
242
 
189
 
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
190
 
 *  form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
191
 
 *  Descriptor.
 
243
/** Manufacturer descriptor string.  This is a Unicode string containing the
 
244
 *  manufacturer's details in human readable form, and is read out upon request
 
245
 *  by the host when the appropriate string ID is requested, listed in the
 
246
 *  Device Descriptor.
192
247
 */
193
248
const USB_Descriptor_String_t PROGMEM ManufacturerString =
194
249
{
195
 
        .Header                 = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
 
250
        .Header                 = {
 
251
                .Size = USB_STRING_LEN(4),
 
252
                .Type = DTYPE_String,
 
253
        },
196
254
 
197
 
        .UnicodeString          = L"Dean Camera"
 
255
        .UnicodeString          = L"edam"
198
256
};
199
257
 
200
 
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
201
 
 *  and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
 
258
/** Product descriptor string.  This is a Unicode string containing the
 
259
 *  product's details in human readable form, and is read out upon request by
 
260
 *  the host when the appropriate string ID is requested, listed in the Device
202
261
 *  Descriptor.
203
262
 */
204
263
const USB_Descriptor_String_t PROGMEM ProductString =
205
264
{
206
 
        .Header                 = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
 
265
        .Header                 = {
 
266
                .Size = USB_STRING_LEN(14),
 
267
                .Type = DTYPE_String,
 
268
        },
207
269
 
208
 
        .UnicodeString          = L"LUFA CDC Demo"
 
270
        .UnicodeString          = L"Audio Switcher"
209
271
};
210
272
 
211
 
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
212
 
 *  documentation) by the application code so that the address and size of a requested descriptor can be given
213
 
 *  to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
214
 
 *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
215
 
 *  USB host.
 
273
/** This function is called by the library when in device mode, and must be
 
274
 *  overridden (see library "USB Descriptors" documentation) by the application
 
275
 *  code so that the address and size of a requested descriptor can be given to
 
276
 *  the USB library.  When the device receives a Get Descriptor request on the
 
277
 *  control endpoint, this function is called so that the descriptor details
 
278
 *  can be passed back and the appropriate descriptor sent back to the USB
 
279
 *  host.
216
280
 */
217
281
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
218
282
                                    const uint8_t wIndex,
226
290
 
227
291
        switch (DescriptorType)
228
292
        {
229
 
                case DTYPE_Device:
230
 
                        Address = &DeviceDescriptor;
231
 
                        Size    = sizeof(USB_Descriptor_Device_t);
232
 
                        break;
233
 
                case DTYPE_Configuration:
234
 
                        Address = &ConfigurationDescriptor;
235
 
                        Size    = sizeof(USB_Descriptor_Configuration_t);
236
 
                        break;
237
 
                case DTYPE_String:
238
 
                        switch (DescriptorNumber)
239
 
                        {
240
 
                                case 0x00:
241
 
                                        Address = &LanguageString;
242
 
                                        Size    = pgm_read_byte(&LanguageString.Header.Size);
243
 
                                        break;
244
 
                                case 0x01:
245
 
                                        Address = &ManufacturerString;
246
 
                                        Size    = pgm_read_byte(&ManufacturerString.Header.Size);
247
 
                                        break;
248
 
                                case 0x02:
249
 
                                        Address = &ProductString;
250
 
                                        Size    = pgm_read_byte(&ProductString.Header.Size);
251
 
                                        break;
252
 
                        }
253
 
 
254
 
                        break;
 
293
        case DTYPE_Device:
 
294
                Address = &DeviceDescriptor;
 
295
                Size    = sizeof(USB_Descriptor_Device_t);
 
296
                break;
 
297
        case DTYPE_Configuration:
 
298
                Address = &ConfigurationDescriptor;
 
299
                Size    = sizeof(USB_Descriptor_Configuration_t);
 
300
                break;
 
301
        case DTYPE_String:
 
302
                switch (DescriptorNumber)
 
303
                {
 
304
                case 0x00:
 
305
                        Address = &LanguageString;
 
306
                        Size    = pgm_read_byte(&LanguageString.Header.Size);
 
307
                        break;
 
308
                case 0x01:
 
309
                        Address = &ManufacturerString;
 
310
                        Size    = pgm_read_byte(&ManufacturerString.Header.Size);
 
311
                        break;
 
312
                case 0x02:
 
313
                        Address = &ProductString;
 
314
                        Size    = pgm_read_byte(&ProductString.Header.Size);
 
315
                        break;
 
316
                }
 
317
                
 
318
                break;
255
319
        }
256
320
 
257
321
        *DescriptorAddress = Address;