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
/* Virtual serial port over USB.*/
20
SerialUSBDriver SDU1;
21
 
22
/*
23
 * Endpoints to be used for USBD1.
24
 */
25
#define USBD1_DATA_REQUEST_EP           1
26
#define USBD1_DATA_AVAILABLE_EP         1
27
#define USBD1_INTERRUPT_REQUEST_EP      2
28
 
29
/*
30
 * USB Device Descriptor.
31
 */
32
static const uint8_t vcom_device_descriptor_data[18] = {
33
  USB_DESC_DEVICE       (0x0110,        /* bcdUSB (1.1).                    */
34
                         0x02,          /* bDeviceClass (CDC).              */
35
                         0x00,          /* bDeviceSubClass.                 */
36
                         0x00,          /* bDeviceProtocol.                 */
37
                         0x40,          /* bMaxPacketSize.                  */
38
                         0x0483,        /* idVendor (ST).                   */
39
                         0x5740,        /* idProduct.                       */
40
                         0x0200,        /* bcdDevice.                       */
41
                         1,             /* iManufacturer.                   */
42
                         2,             /* iProduct.                        */
43
                         3,             /* iSerialNumber.                   */
44
                         1)             /* bNumConfigurations.              */
45
};
46
 
47
/*
48
 * Device Descriptor wrapper.
49
 */
50
static const USBDescriptor vcom_device_descriptor = {
51
  sizeof vcom_device_descriptor_data,
52
  vcom_device_descriptor_data
53
};
54
 
55
/* Configuration Descriptor tree for a CDC.*/
56
static const uint8_t vcom_configuration_descriptor_data[67] = {
57
  /* Configuration Descriptor.*/
58
  USB_DESC_CONFIGURATION(67,            /* wTotalLength.                    */
59
                         0x02,          /* bNumInterfaces.                  */
60
                         0x01,          /* bConfigurationValue.             */
61
                         0,             /* iConfiguration.                  */
62
                         0xC0,          /* bmAttributes (self powered).     */
63
                         50),           /* bMaxPower (100mA).               */
64
  /* Interface Descriptor.*/
65
  USB_DESC_INTERFACE    (0x00,          /* bInterfaceNumber.                */
66
                         0x00,          /* bAlternateSetting.               */
67
                         0x01,          /* bNumEndpoints.                   */
68
                         0x02,          /* bInterfaceClass (Communications
69
                                           Interface Class, CDC section
70
                                           4.2).                            */
71
                         0x02,          /* bInterfaceSubClass (Abstract
72
                                         Control Model, CDC section 4.3).   */
73
                         0x01,          /* bInterfaceProtocol (AT commands,
74
                                           CDC section 4.4).                */
75
                         0),            /* iInterface.                      */
76
  /* Header Functional Descriptor (CDC section 5.2.3).*/
77
  USB_DESC_BYTE         (5),            /* bLength.                         */
78
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
79
  USB_DESC_BYTE         (0x00),         /* bDescriptorSubtype (Header
80
                                           Functional Descriptor.           */
81
  USB_DESC_BCD          (0x0110),       /* bcdCDC.                          */
82
  /* Call Management Functional Descriptor. */
83
  USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
84
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
85
  USB_DESC_BYTE         (0x01),         /* bDescriptorSubtype (Call Management
86
                                           Functional Descriptor).          */
87
  USB_DESC_BYTE         (0x00),         /* bmCapabilities (D0+D1).          */
88
  USB_DESC_BYTE         (0x01),         /* bDataInterface.                  */
89
  /* ACM Functional Descriptor.*/
90
  USB_DESC_BYTE         (4),            /* bFunctionLength.                 */
91
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
92
  USB_DESC_BYTE         (0x02),         /* bDescriptorSubtype (Abstract
93
                                           Control Management Descriptor).  */
94
  USB_DESC_BYTE         (0x02),         /* bmCapabilities.                  */
95
  /* Union Functional Descriptor.*/
96
  USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
97
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
98
  USB_DESC_BYTE         (0x06),         /* bDescriptorSubtype (Union
99
                                           Functional Descriptor).          */
100
  USB_DESC_BYTE         (0x00),         /* bMasterInterface (Communication
101
                                           Class Interface).                */
102
  USB_DESC_BYTE         (0x01),         /* bSlaveInterface0 (Data Class
103
                                           Interface).                      */
104
  /* Endpoint 2 Descriptor.*/
105
  USB_DESC_ENDPOINT     (USBD1_INTERRUPT_REQUEST_EP|0x80,
106
                         0x03,          /* bmAttributes (Interrupt).        */
107
                         0x0008,        /* wMaxPacketSize.                  */
108
                         0xFF),         /* bInterval.                       */
109
  /* Interface Descriptor.*/
110
  USB_DESC_INTERFACE    (0x01,          /* bInterfaceNumber.                */
111
                         0x00,          /* bAlternateSetting.               */
112
                         0x02,          /* bNumEndpoints.                   */
113
                         0x0A,          /* bInterfaceClass (Data Class
114
                                           Interface, CDC section 4.5).     */
115
                         0x00,          /* bInterfaceSubClass (CDC section
116
                                           4.6).                            */
117
                         0x00,          /* bInterfaceProtocol (CDC section
118
                                           4.7).                            */
119
                         0x00),         /* iInterface.                      */
120
  /* Endpoint 3 Descriptor.*/
121
  USB_DESC_ENDPOINT     (USBD1_DATA_AVAILABLE_EP,       /* bEndpointAddress.*/
122
                         0x02,          /* bmAttributes (Bulk).             */
123
                         0x0040,        /* wMaxPacketSize.                  */
124
                         0x00),         /* bInterval.                       */
125
  /* Endpoint 1 Descriptor.*/
126
  USB_DESC_ENDPOINT     (USBD1_DATA_REQUEST_EP|0x80,    /* bEndpointAddress.*/
127
                         0x02,          /* bmAttributes (Bulk).             */
128
                         0x0040,        /* wMaxPacketSize.                  */
129
                         0x00)          /* bInterval.                       */
130
};
131
 
132
/*
133
 * Configuration Descriptor wrapper.
134
 */
135
static const USBDescriptor vcom_configuration_descriptor = {
136
  sizeof vcom_configuration_descriptor_data,
137
  vcom_configuration_descriptor_data
138
};
139
 
140
/*
141
 * U.S. English language identifier.
142
 */
143
static const uint8_t vcom_string0[] = {
144
  USB_DESC_BYTE(4),                     /* bLength.                         */
145
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
146
  USB_DESC_WORD(0x0409)                 /* wLANGID (U.S. English).          */
147
};
148
 
149
/*
150
 * Vendor string.
151
 */
152
static const uint8_t vcom_string1[] = {
153
  USB_DESC_BYTE(38),                    /* bLength.                         */
154
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
155
  'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
156
  'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
157
  'c', 0, 's', 0
158
};
159
 
160
/*
161
 * Device Description string.
162
 */
163
static const uint8_t vcom_string2[] = {
164
  USB_DESC_BYTE(56),                    /* bLength.                         */
165
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
166
  'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
167
  'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
168
  'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
169
  'o', 0, 'r', 0, 't', 0
170
};
171
 
172
/*
173
 * Serial Number string.
174
 */
175
static const uint8_t vcom_string3[] = {
176
  USB_DESC_BYTE(8),                     /* bLength.                         */
177
  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
178
  '0' + CH_KERNEL_MAJOR, 0,
179
  '0' + CH_KERNEL_MINOR, 0,
180
  '0' + CH_KERNEL_PATCH, 0
181
};
182
 
183
/*
184
 * Strings wrappers array.
185
 */
186
static const USBDescriptor vcom_strings[] = {
187
  {sizeof vcom_string0, vcom_string0},
188
  {sizeof vcom_string1, vcom_string1},
189
  {sizeof vcom_string2, vcom_string2},
190
  {sizeof vcom_string3, vcom_string3}
191
};
192
 
193
/*
194
 * Handles the GET_DESCRIPTOR callback. All required descriptors must be
195
 * handled here.
196
 */
197
static const USBDescriptor *get_descriptor(USBDriver *usbp,
198
                                           uint8_t dtype,
199
                                           uint8_t dindex,
200
                                           uint16_t lang) {
201
 
202
  (void)usbp;
203
  (void)lang;
204
  switch (dtype) {
205
  case USB_DESCRIPTOR_DEVICE:
206
    return &vcom_device_descriptor;
207
  case USB_DESCRIPTOR_CONFIGURATION:
208
    return &vcom_configuration_descriptor;
209
  case USB_DESCRIPTOR_STRING:
210
    if (dindex < 4)
211
      return &vcom_strings[dindex];
212
  }
213
  return NULL;
214
}
215
 
216
/**
217
 * @brief   IN EP1 state.
218
 */
219
static USBInEndpointState ep1instate;
220
 
221
/**
222
 * @brief   OUT EP1 state.
223
 */
224
static USBOutEndpointState ep1outstate;
225
 
226
/**
227
 * @brief   EP1 initialization structure (both IN and OUT).
228
 */
229
static const USBEndpointConfig ep1config = {
230
  USB_EP_MODE_TYPE_BULK,
231
  NULL,
232
  sduDataTransmitted,
233
  sduDataReceived,
234
  0x0040,
235
  0x0040,
236
  &ep1instate,
237
  &ep1outstate,
238
  2,
239
  NULL
240
};
241
 
242
/**
243
 * @brief   IN EP2 state.
244
 */
245
static USBInEndpointState ep2instate;
246
 
247
/**
248
 * @brief   EP2 initialization structure (IN only).
249
 */
250
static const USBEndpointConfig ep2config = {
251
  USB_EP_MODE_TYPE_INTR,
252
  NULL,
253
  sduInterruptTransmitted,
254
  NULL,
255
  0x0010,
256
  0x0000,
257
  &ep2instate,
258
  NULL,
259
  1,
260
  NULL
261
};
262
 
263
/*
264
 * Handles the USB driver global events.
265
 */
266
static void usb_event(USBDriver *usbp, usbevent_t event) {
267
  extern SerialUSBDriver SDU1;
268
 
269
  switch (event) {
270
  case USB_EVENT_ADDRESS:
271
    return;
272
  case USB_EVENT_CONFIGURED:
273
    chSysLockFromISR();
274
 
275
    /* Enables the endpoints specified into the configuration.
276
       Note, this callback is invoked from an ISR so I-Class functions
277
       must be used.*/
278
    usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
279
    usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
280
 
281
    /* Resetting the state of the CDC subsystem.*/
282
    sduConfigureHookI(&SDU1);
283
 
284
    chSysUnlockFromISR();
285
    return;
286
  case USB_EVENT_RESET:
287
    /* Falls into.*/
288
  case USB_EVENT_UNCONFIGURED:
289
    /* Falls into.*/
290
  case USB_EVENT_SUSPEND:
291
    chSysLockFromISR();
292
 
293
    /* Disconnection event on suspend.*/
294
    sduSuspendHookI(&SDU1);
295
 
296
    chSysUnlockFromISR();
297
    return;
298
  case USB_EVENT_WAKEUP:
299
    chSysLockFromISR();
300
 
301
    /* Disconnection event on suspend.*/
302
    sduWakeupHookI(&SDU1);
303
 
304
    chSysUnlockFromISR();
305
    return;
306
  case USB_EVENT_STALLED:
307
    return;
308
  }
309
  return;
310
}
311
 
312
/*
313
 * Handles the USB driver global events.
314
 */
315
static void sof_handler(USBDriver *usbp) {
316
 
317
  (void)usbp;
318
 
319
  osalSysLockFromISR();
320
  sduSOFHookI(&SDU1);
321
  osalSysUnlockFromISR();
322
}
323
 
324
/*
325
 * USB driver configuration.
326
 */
327
const USBConfig usbcfg = {
328
  usb_event,
329
  get_descriptor,
330
  sduRequestsHook,
331
  sof_handler
332
};
333
 
334
/*
335
 * Serial over USB driver configuration.
336
 */
337
const SerialUSBConfig serusbcfg = {
338
  &USBD1,
339
  USBD1_DATA_REQUEST_EP,
340
  USBD1_DATA_AVAILABLE_EP,
341
  USBD1_INTERRUPT_REQUEST_EP
342
};