Subversion Repositories ChibiGauge

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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