Subversion Repositories chibiosIgnition

Rev

Rev 7 | Rev 19 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 mjames 1
/*
2
    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
 
4
    Licensed under the Apache License, Version 2.0 (the "License");
5
    you may not use this file except in compliance with the License.
6
    You may obtain a copy of the License at
7
 
8
        http://www.apache.org/licenses/LICENSE-2.0
9
 
10
    Unless required by applicable law or agreed to in writing, software
11
    distributed under the License is distributed on an "AS IS" BASIS,
12
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
    See the License for the specific language governing permissions and
14
    limitations under the License.
15
*/
16
 
17
#include "hal.h"
18
 
18 mjames 19
 
20
 
7 mjames 21
/* Virtual serial port over USB.*/
22
SerialUSBDriver SDU1;
23
 
18 mjames 24
#if HAL_USE_SERIAL_USB  == TRUE
25
SerialUSBDriver SDU2;
26
#endif
27
 
28
 
7 mjames 29
/*
18 mjames 30
 * Endpoints to be used for USBD1/SDU1.
7 mjames 31
 */
32
#define USBD1_DATA_REQUEST_EP           1
33
#define USBD1_DATA_AVAILABLE_EP         1
34
#define USBD1_INTERRUPT_REQUEST_EP      2
35
 
36
/*
18 mjames 37
 * Endpoints to be used for USBD1/SDU2
38
 */
39
#if HAL_USE_USB_DUAL_CDC == TRUE
40
#define USBD1_DATA2_REQUEST_EP           3
41
#define USBD1_DATA2_AVAILABLE_EP         3
42
#define USBD1_INTERRUPT2_REQUEST_EP      4
43
#endif
44
/*
7 mjames 45
 * USB Device Descriptor.
46
 */
47
static const uint8_t vcom_device_descriptor_data[18] = {
48
  USB_DESC_DEVICE       (0x0110,        /* bcdUSB (1.1).                    */
49
                         0x02,          /* bDeviceClass (CDC).              */
50
                         0x00,          /* bDeviceSubClass.                 */
51
                         0x00,          /* bDeviceProtocol.                 */
52
                         0x40,          /* bMaxPacketSize.                  */
53
                         0x0483,        /* idVendor (ST).                   */
54
                         0x5740,        /* idProduct.                       */
55
                         0x0200,        /* bcdDevice.                       */
56
                         1,             /* iManufacturer.                   */
57
                         2,             /* iProduct.                        */
18 mjames 58
                         3,             /* iSerialNumber. */
7 mjames 59
                         1)             /* bNumConfigurations.              */
60
};
61
 
62
/*
63
 * Device Descriptor wrapper.
64
 */
65
static const USBDescriptor vcom_device_descriptor = {
66
  sizeof vcom_device_descriptor_data,
67
  vcom_device_descriptor_data
68
};
69
 
18 mjames 70
 
7 mjames 71
/* Configuration Descriptor tree for a CDC.*/
18 mjames 72
 
73
static const uint8_t vcom_configuration_descriptor_data[] = {
7 mjames 74
  /* Configuration Descriptor.*/
18 mjames 75
#if HAL_USE_USB_DUAL_CDC == FALSE
76
                                 /* the header is 9 bytes long, total has 2 EPs in use = 67 bytes */
7 mjames 77
  USB_DESC_CONFIGURATION(67,            /* wTotalLength.                    */
78
                         0x02,          /* bNumInterfaces.                  */
79
                         0x01,          /* bConfigurationValue.             */
80
                         0,             /* iConfiguration.                  */
81
                         0xC0,          /* bmAttributes (self powered).     */
82
                         50),           /* bMaxPower (100mA).               */
18 mjames 83
#else
84
                                                 /* the header is 9 bytes long, total has 4 EP in use = 67 * 2 -9 bytes */
85
  USB_DESC_CONFIGURATION(125,           /* wTotalLength.                    */
86
                                             0x04,          /* bNumInterfaces.                  */
87
                                                 0x01,          /* bConfigurationValue.             */
88
                                                 0,             /* iConfiguration.                  */
89
                                                 0xC0,          /* bmAttributes (self powered).     */
90
                                                 50),           /* bMaxPower (100mA).               */
91
#endif
92
                                                                                                 /* Interface Descriptor.*/
7 mjames 93
  USB_DESC_INTERFACE    (0x00,          /* bInterfaceNumber.                */
94
                         0x00,          /* bAlternateSetting.               */
95
                         0x01,          /* bNumEndpoints.                   */
96
                         0x02,          /* bInterfaceClass (Communications
97
                                           Interface Class, CDC section
98
                                           4.2).                            */
99
                         0x02,          /* bInterfaceSubClass (Abstract
100
                                         Control Model, CDC section 4.3).   */
101
                         0x01,          /* bInterfaceProtocol (AT commands,
102
                                           CDC section 4.4).                */
103
                         0),            /* iInterface.                      */
18 mjames 104
 
105
                                                 /* Header Functional Descriptor (CDC section 5.2.3).*/
7 mjames 106
  USB_DESC_BYTE         (5),            /* bLength.                         */
107
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
108
  USB_DESC_BYTE         (0x00),         /* bDescriptorSubtype (Header
109
                                           Functional Descriptor.           */
110
  USB_DESC_BCD          (0x0110),       /* bcdCDC.                          */
111
  /* Call Management Functional Descriptor. */
112
  USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
113
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
114
  USB_DESC_BYTE         (0x01),         /* bDescriptorSubtype (Call Management
115
                                           Functional Descriptor).          */
116
  USB_DESC_BYTE         (0x00),         /* bmCapabilities (D0+D1).          */
117
  USB_DESC_BYTE         (0x01),         /* bDataInterface.                  */
118
  /* ACM Functional Descriptor.*/
119
  USB_DESC_BYTE         (4),            /* bFunctionLength.                 */
120
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
121
  USB_DESC_BYTE         (0x02),         /* bDescriptorSubtype (Abstract
122
                                           Control Management Descriptor).  */
123
  USB_DESC_BYTE         (0x02),         /* bmCapabilities.                  */
124
  /* Union Functional Descriptor.*/
125
  USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
126
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
127
  USB_DESC_BYTE         (0x06),         /* bDescriptorSubtype (Union
128
                                           Functional Descriptor).          */
129
  USB_DESC_BYTE         (0x00),         /* bMasterInterface (Communication
130
                                           Class Interface).                */
131
  USB_DESC_BYTE         (0x01),         /* bSlaveInterface0 (Data Class
132
                                           Interface).                      */
133
  /* Endpoint 2 Descriptor.*/
134
  USB_DESC_ENDPOINT     (USBD1_INTERRUPT_REQUEST_EP|0x80,
135
                         0x03,          /* bmAttributes (Interrupt).        */
136
                         0x0008,        /* wMaxPacketSize.                  */
137
                         0xFF),         /* bInterval.                       */
138
  /* Interface Descriptor.*/
139
  USB_DESC_INTERFACE    (0x01,          /* bInterfaceNumber.                */
140
                         0x00,          /* bAlternateSetting.               */
141
                         0x02,          /* bNumEndpoints.                   */
142
                         0x0A,          /* bInterfaceClass (Data Class
143
                                           Interface, CDC section 4.5).     */
144
                         0x00,          /* bInterfaceSubClass (CDC section
145
                                           4.6).                            */
146
                         0x00,          /* bInterfaceProtocol (CDC section
147
                                           4.7).                            */
148
                         0x00),         /* iInterface.                      */
149
  /* Endpoint 3 Descriptor.*/
150
  USB_DESC_ENDPOINT     (USBD1_DATA_AVAILABLE_EP,       /* bEndpointAddress.*/
151
                         0x02,          /* bmAttributes (Bulk).             */
152
                         0x0040,        /* wMaxPacketSize.                  */
153
                         0x00),         /* bInterval.                       */
154
  /* Endpoint 1 Descriptor.*/
155
  USB_DESC_ENDPOINT     (USBD1_DATA_REQUEST_EP|0x80,    /* bEndpointAddress.*/
156
                         0x02,          /* bmAttributes (Bulk).             */
157
                         0x0040,        /* wMaxPacketSize.                  */
18 mjames 158
                         0x00),          /* bInterval.                       */
159
#if HAL_USE_USB_DUAL_CDC ==TRUE
160
/* Configuration Descriptor tree for a CDC.*/
161
USB_DESC_INTERFACE    (0x02,          /* bInterfaceNumber.                */
162
                       0x00,          /* bAlternateSetting.               */
163
                       0x01,          /* bNumEndpoints.                   */
164
                       0x02,          /* bInterfaceClass (Communications
165
                                         Interface Class, CDC section
166
                                         4.2).                            */
167
                       0x02,          /* bInterfaceSubClass (Abstract
168
                                       Control Model, CDC section 4.3).   */
169
                       0x01,          /* bInterfaceProtocol (AT commands,
170
                                         CDC section 4.4).                */
171
                       0),            /* iInterface.                      */
172
 
173
                                                 /* Header Functional Descriptor (CDC section 5.2.3).*/
174
USB_DESC_BYTE         (5),            /* bLength.                         */
175
USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
176
USB_DESC_BYTE         (0x00),         /* bDescriptorSubtype (Header
177
                                         Functional Descriptor.           */
178
USB_DESC_BCD          (0x0110),       /* bcdCDC.                          */
179
/* Call Management Functional Descriptor. */
180
USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
181
USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
182
USB_DESC_BYTE         (0x01),         /* bDescriptorSubtype (Call Management
183
                                         Functional Descriptor).          */
184
USB_DESC_BYTE         (0x00),         /* bmCapabilities (D0+D1).          */
185
USB_DESC_BYTE         (0x01),         /* bDataInterface.                  */
186
/* ACM Functional Descriptor.*/
187
USB_DESC_BYTE         (4),            /* bFunctionLength.                 */
188
USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
189
USB_DESC_BYTE         (0x02),         /* bDescriptorSubtype (Abstract
190
                                         Control Management Descriptor).  */
191
USB_DESC_BYTE         (0x02),         /* bmCapabilities.                  */
192
/* Union Functional Descriptor.*/
193
USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
194
USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
195
USB_DESC_BYTE         (0x06),         /* bDescriptorSubtype (Union
196
                                         Functional Descriptor).          */
197
USB_DESC_BYTE         (0x00),         /* bMasterInterface (Communication
198
                                         Class Interface).                */
199
USB_DESC_BYTE         (0x01),         /* bSlaveInterface0 (Data Class
200
                                         Interface).                      */
201
/* Endpoint 2 Descriptor.*/
202
USB_DESC_ENDPOINT     (USBD1_INTERRUPT2_REQUEST_EP|0x80,
203
                       0x03,          /* bmAttributes (Interrupt).        */
204
                       0x0008,        /* wMaxPacketSize.                  */
205
                       0xFF),         /* bInterval.                       */
206
/* Interface Descriptor.*/
207
USB_DESC_INTERFACE    (0x03,          /* bInterfaceNumber.                */
208
                       0x00,          /* bAlternateSetting.               */
209
                       0x02,          /* bNumEndpoints.                   */
210
                       0x0A,          /* bInterfaceClass (Data Class
211
                                         Interface, CDC section 4.5).     */
212
                       0x00,          /* bInterfaceSubClass (CDC section
213
                                         4.6).                            */
214
                       0x00,          /* bInterfaceProtocol (CDC section
215
                                         4.7).                            */
216
                       0x00),         /* iInterface.                      */
217
/* Endpoint 3 Descriptor.*/
218
USB_DESC_ENDPOINT     (USBD1_DATA2_AVAILABLE_EP,       /* bEndpointAddress.*/
219
                       0x02,          /* bmAttributes (Bulk).             */
220
                       0x0040,        /* wMaxPacketSize.                  */
221
                       0x00),         /* bInterval.                       */
222
/* Endpoint 1 Descriptor.*/
223
USB_DESC_ENDPOINT     (USBD1_DATA2_REQUEST_EP|0x80,    /* bEndpointAddress.*/
224
                       0x02,          /* bmAttributes (Bulk).             */
225
                       0x0040,        /* wMaxPacketSize.                  */
226
                       0x00)          /* bInterval.                       */
227
#endif
7 mjames 228
};
229
/*
230
 * Configuration Descriptor wrapper.
231
 */
232
static const USBDescriptor vcom_configuration_descriptor = {
233
  sizeof vcom_configuration_descriptor_data,
234
  vcom_configuration_descriptor_data
235
};
236
 
237
/*
238
 * U.S. English language identifier.
239
 */
240
static const uint8_t vcom_string0[] = {
241
  USB_DESC_BYTE(4),                     /* bLength.                         */
242
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
243
  USB_DESC_WORD(0x0409)                 /* wLANGID (U.S. English).          */
244
};
245
 
246
/*
247
 * Vendor string.
248
 */
249
static const uint8_t vcom_string1[] = {
250
  USB_DESC_BYTE(38),                    /* bLength.                         */
251
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
252
  'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
253
  'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
254
  'c', 0, 's', 0
255
};
256
 
257
/*
258
 * Device Description string.
259
 */
260
static const uint8_t vcom_string2[] = {
261
  USB_DESC_BYTE(56),                    /* bLength.                         */
262
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
263
  'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
264
  'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
265
  'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
266
  'o', 0, 'r', 0, 't', 0
267
};
268
 
269
/*
270
 * Serial Number string.
271
 */
272
static const uint8_t vcom_string3[] = {
273
  USB_DESC_BYTE(8),                     /* bLength.                         */
274
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
275
  '0' + CH_KERNEL_MAJOR, 0,
276
  '0' + CH_KERNEL_MINOR, 0,
277
  '0' + CH_KERNEL_PATCH, 0
278
};
279
 
280
/*
281
 * Strings wrappers array.
282
 */
283
static const USBDescriptor vcom_strings[] = {
284
  {sizeof vcom_string0, vcom_string0},
285
  {sizeof vcom_string1, vcom_string1},
286
  {sizeof vcom_string2, vcom_string2},
287
  {sizeof vcom_string3, vcom_string3}
288
};
289
 
290
/*
291
 * Handles the GET_DESCRIPTOR callback. All required descriptors must be
292
 * handled here.
293
 */
294
static const USBDescriptor *get_descriptor(USBDriver *usbp,
295
                                           uint8_t dtype,
296
                                           uint8_t dindex,
297
                                           uint16_t lang) {
298
 
299
  (void)usbp;
300
  (void)lang;
301
  switch (dtype) {
302
  case USB_DESCRIPTOR_DEVICE:
303
    return &vcom_device_descriptor;
304
  case USB_DESCRIPTOR_CONFIGURATION:
305
    return &vcom_configuration_descriptor;
306
  case USB_DESCRIPTOR_STRING:
307
    if (dindex < 4)
308
      return &vcom_strings[dindex];
309
  }
310
  return NULL;
311
}
312
 
313
/**
314
 * @brief   IN EP1 state.
315
 */
316
static USBInEndpointState ep1instate;
317
 
318
/**
319
 * @brief   OUT EP1 state.
320
 */
321
static USBOutEndpointState ep1outstate;
322
 
323
/**
324
 * @brief   EP1 initialization structure (both IN and OUT).
325
 */
326
static const USBEndpointConfig ep1config = {
327
  USB_EP_MODE_TYPE_BULK,
328
  NULL,
329
  sduDataTransmitted,
330
  sduDataReceived,
331
  0x0040,
332
  0x0040,
333
  &ep1instate,
334
  &ep1outstate,
335
  2,
336
  NULL
337
};
338
 
339
/**
340
 * @brief   IN EP2 state.
341
 */
342
static USBInEndpointState ep2instate;
343
 
344
/**
345
 * @brief   EP2 initialization structure (IN only).
346
 */
347
static const USBEndpointConfig ep2config = {
348
  USB_EP_MODE_TYPE_INTR,
349
  NULL,
350
  sduInterruptTransmitted,
351
  NULL,
352
  0x0010,
353
  0x0000,
354
  &ep2instate,
355
  NULL,
356
  1,
357
  NULL
358
};
359
 
18 mjames 360
 
361
#if DUAL_CDC_EP ==TRUE
362
/**
363
 * @brief   IN EP3 state.
364
 */
365
static USBInEndpointState ep3instate;
366
 
367
/**
368
 * @brief   OUT EP3 state.
369
 */
370
static USBOutEndpointState ep3outstate;
371
 
372
/**
373
 * @brief   EP3 initialization structure (both IN and OUT).
374
 */
375
static const USBEndpointConfig ep3config = {
376
  USB_EP_MODE_TYPE_BULK,
377
  NULL,
378
  sduDataTransmitted,
379
  sduDataReceived,
380
  0x0040,
381
  0x0040,
382
  &ep3instate,
383
  &ep3outstate,
384
  2,
385
  NULL
386
};
387
 
388
/**
389
 * @brief   IN EP4 state.
390
 */
391
static USBInEndpointState ep4instate;
392
 
393
/**
394
 * @brief   EP4 initialization structure (IN only).
395
 */
396
static const USBEndpointConfig ep4config = {
397
  USB_EP_MODE_TYPE_INTR,
398
  NULL,
399
  sduInterruptTransmitted,
400
  NULL,
401
  0x0010,
402
  0x0000,
403
  &ep4instate,
404
  NULL,
405
  1,
406
  NULL
407
};
408
 
409
 
410
#endif
7 mjames 411
/*
412
 * Handles the USB driver global events.
413
 */
414
static void usb_event(USBDriver *usbp, usbevent_t event) {
415
  extern SerialUSBDriver SDU1;
416
 
417
  switch (event) {
418
  case USB_EVENT_ADDRESS:
419
    return;
420
  case USB_EVENT_CONFIGURED:
421
    chSysLockFromISR();
422
 
423
    /* Enables the endpoints specified into the configuration.
424
       Note, this callback is invoked from an ISR so I-Class functions
425
       must be used.*/
426
    usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
427
    usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
18 mjames 428
#if DUAL_CDC_EP == TRUE
429
    usbInitEndpointI(usbp, USBD1_DATA2_REQUEST_EP, &ep3config);
430
    usbInitEndpointI(usbp, USBD1_INTERRUPT2_REQUEST_EP, &ep4config);
431
#endif
7 mjames 432
    /* Resetting the state of the CDC subsystem.*/
433
    sduConfigureHookI(&SDU1);
434
 
435
    chSysUnlockFromISR();
436
    return;
437
  case USB_EVENT_RESET:
438
    /* Falls into.*/
439
  case USB_EVENT_UNCONFIGURED:
440
    /* Falls into.*/
441
  case USB_EVENT_SUSPEND:
442
    chSysLockFromISR();
443
 
444
    /* Disconnection event on suspend.*/
445
    sduSuspendHookI(&SDU1);
446
 
447
    chSysUnlockFromISR();
448
    return;
449
  case USB_EVENT_WAKEUP:
450
    chSysLockFromISR();
451
 
452
    /* Disconnection event on suspend.*/
453
    sduWakeupHookI(&SDU1);
454
 
455
    chSysUnlockFromISR();
456
    return;
457
  case USB_EVENT_STALLED:
458
    return;
459
  }
460
  return;
461
}
462
 
463
/*
464
 * Handles the USB driver global events.
465
 */
466
static void sof_handler(USBDriver *usbp) {
467
 
468
  (void)usbp;
469
 
470
  osalSysLockFromISR();
471
  sduSOFHookI(&SDU1);
472
  osalSysUnlockFromISR();
473
}
474
 
475
/*
476
 * USB driver configuration.
477
 */
478
const USBConfig usbcfg = {
479
  usb_event,
480
  get_descriptor,
481
  sduRequestsHook,
482
  sof_handler
483
};
484
 
485
/*
486
 * Serial over USB driver configuration.
487
 */
488
const SerialUSBConfig serusbcfg = {
489
  &USBD1,
490
  USBD1_DATA_REQUEST_EP,
491
  USBD1_DATA_AVAILABLE_EP,
492
  USBD1_INTERRUPT_REQUEST_EP
493
};
18 mjames 494
 
495
#if HAL_USE_USB_DUAL_CDC == TRUE
496
const SerialUSBConfig serusbcfg2 = {
497
  &USBD1,
498
  USBD1_DATA2_REQUEST_EP,
499
  USBD1_DATA2_AVAILABLE_EP,
500
  USBD1_INTERRUPT2_REQUEST_EP
501
};
502
#endif