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