/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-23 15:44:20 UTC
  • Revision ID: tim@ed.am-20121123154420-pk5kxho2vbowu69h
added serial buffer reading, command handling and rewrote button press
detection

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
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
 
 
 
2
             LUFA Library
 
3
     Copyright (C) Dean Camera, 2012.
 
4
 
 
5
  dean [at] fourwalledcubicle [dot] com
 
6
           www.lufa-lib.org
15
7
*/
16
8
 
17
9
/*
38
30
 
39
31
/** \file
40
32
 *
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.
 
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.
45
36
 */
46
37
 
47
38
#include "Descriptors.h"
48
39
 
49
40
 
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.
 
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.
55
45
 */
56
46
const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
57
47
{
58
 
        .Header                 = {
59
 
                .Size = sizeof(USB_Descriptor_Device_t),
60
 
                .Type = DTYPE_Device
61
 
        },
 
48
        .Header                 = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
62
49
 
63
50
        .USBSpecification       = VERSION_BCD(01.10),
64
51
        .Class                  = CDC_CSCP_CDCClass,
68
55
        .Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
69
56
 
70
57
        .VendorID               = 0x03EB,
71
 
        .ProductID              = 0xba7f, // 0x2044,
 
58
        .ProductID              = 0x2044,
72
59
        .ReleaseNumber          = VERSION_BCD(00.01),
73
60
 
74
61
        .ManufacturerStrIndex   = 0x01,
78
65
        .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
79
66
};
80
67
 
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.
 
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.
87
72
 */
88
73
const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
89
74
{
90
75
        .Config =
91
 
        {
92
 
                .Header                 = {
93
 
                        .Size = sizeof(USB_Descriptor_Configuration_Header_t),
94
 
                        .Type = DTYPE_Configuration,
 
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)
95
88
                },
96
89
 
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
 
 
109
90
        .CDC_CCI_Interface =
110
 
        {
111
 
                .Header                 = {
112
 
                        .Size = sizeof(USB_Descriptor_Interface_t),
113
 
                        .Type = DTYPE_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
114
104
                },
115
105
 
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
 
 
128
106
        .CDC_Functional_Header =
129
 
        {
130
 
                .Header                 = {
131
 
                        .Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t),
132
 
                        .Type = DTYPE_CSInterface,
 
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),
133
112
                },
134
113
 
135
 
                .Subtype                = CDC_DSUBTYPE_CSInterface_Header,
136
 
 
137
 
                .CDCSpecification       = VERSION_BCD(01.10),
138
 
        },
139
 
 
140
114
        .CDC_Functional_ACM =
141
 
        {
142
 
                .Header                 = {
143
 
                        .Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t),
144
 
                        .Type = DTYPE_CSInterface,
 
115
                {
 
116
                        .Header                 = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
 
117
                        .Subtype                = CDC_DSUBTYPE_CSInterface_ACM,
 
118
 
 
119
                        .Capabilities           = 0x06,
145
120
                },
146
121
 
147
 
                .Subtype                = CDC_DSUBTYPE_CSInterface_ACM,
148
 
 
149
 
                .Capabilities           = 0x06,
150
 
        },
151
 
 
152
122
        .CDC_Functional_Union =
153
 
        {
154
 
                .Header                 = {
155
 
                        .Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t),
156
 
                        .Type = DTYPE_CSInterface,
 
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,
157
129
                },
158
130
 
159
 
                .Subtype                = CDC_DSUBTYPE_CSInterface_Union,
160
 
 
161
 
                .MasterInterfaceNumber  = 0,
162
 
                .SlaveInterfaceNumber   = 1,
163
 
        },
164
 
 
165
131
        .CDC_NotificationEndpoint =
166
 
        {
167
 
                .Header                 = {
168
 
                        .Size = sizeof(USB_Descriptor_Endpoint_t),
169
 
                        .Type = DTYPE_Endpoint,
 
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
170
139
                },
171
140
 
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
 
 
179
141
        .CDC_DCI_Interface =
180
 
        {
181
 
                .Header                 = {
182
 
                        .Size = sizeof(USB_Descriptor_Interface_t),
183
 
                        .Type = DTYPE_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
184
155
                },
185
156
 
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
 
 
198
157
        .CDC_DataOutEndpoint =
199
 
        {
200
 
                .Header                 = {
201
 
                        .Size = sizeof(USB_Descriptor_Endpoint_t),
202
 
                        .Type = DTYPE_Endpoint,
 
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
203
165
                },
204
166
 
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
 
 
212
167
        .CDC_DataInEndpoint =
213
 
        {
214
 
                .Header                 = {
215
 
                        .Size = sizeof(USB_Descriptor_Endpoint_t),
216
 
                        .Type = DTYPE_Endpoint,
217
 
                },
 
168
                {
 
169
                        .Header                 = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
218
170
 
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
 
        }
 
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
                }
225
176
};
226
177
 
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.
 
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.
232
181
 */
233
182
const USB_Descriptor_String_t PROGMEM LanguageString =
234
183
{
235
 
        .Header                 = {
236
 
                .Size = USB_STRING_LEN(1),
237
 
                .Type = DTYPE_String,
238
 
        },
 
184
        .Header                 = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
239
185
 
240
186
        .UnicodeString          = {LANGUAGE_ID_ENG}
241
187
};
242
188
 
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.
 
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.
247
192
 */
248
193
const USB_Descriptor_String_t PROGMEM ManufacturerString =
249
194
{
250
 
        .Header                 = {
251
 
                .Size = USB_STRING_LEN(4),
252
 
                .Type = DTYPE_String,
253
 
        },
 
195
        .Header                 = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
254
196
 
255
 
        .UnicodeString          = L"edam"
 
197
        .UnicodeString          = L"Dean Camera"
256
198
};
257
199
 
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
 
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
261
202
 *  Descriptor.
262
203
 */
263
204
const USB_Descriptor_String_t PROGMEM ProductString =
264
205
{
265
 
        .Header                 = {
266
 
                .Size = USB_STRING_LEN(14),
267
 
                .Type = DTYPE_String,
268
 
        },
 
206
        .Header                 = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
269
207
 
270
 
        .UnicodeString          = L"Audio Switcher"
 
208
        .UnicodeString          = L"LUFA CDC Demo"
271
209
};
272
210
 
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.
 
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.
280
216
 */
281
217
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
282
218
                                    const uint8_t wIndex,
290
226
 
291
227
        switch (DescriptorType)
292
228
        {
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;
 
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;
319
255
        }
320
256
 
321
257
        *DescriptorAddress = Address;