2
2
* This file is part of the unicore-mx project.
3
3
*
4
4
* Copyright (C) 2010 Gareth McMullin <[email protected] >
5
+ * Copyright (C) 2015 Kuldeep Singh Dhaka <[email protected] >
5
6
*
6
7
* This library is free software: you can redistribute it and/or modify
7
8
* it under the terms of the GNU Lesser General Public License as published by
17
18
* along with this library. If not, see <http://www.gnu.org/licenses/>.
18
19
*/
19
20
20
- #include <stdlib.h>
21
- #include <unicore-mx/stm32/rcc.h>
22
- #include <unicore-mx/stm32/gpio.h>
21
+ #include <string.h>
23
22
#include <unicore-mx/usbd/usbd.h>
24
- #include <unicore-mx/usb/cdc.h>
25
-
26
- static const struct usb_device_descriptor dev = {
27
- .bLength = USB_DT_DEVICE_SIZE ,
28
- .bDescriptorType = USB_DT_DEVICE ,
29
- .bcdUSB = 0x0200 ,
30
- .bDeviceClass = USB_CLASS_CDC ,
31
- .bDeviceSubClass = 0 ,
32
- .bDeviceProtocol = 0 ,
33
- .bMaxPacketSize0 = 64 ,
34
- .idVendor = 0x0483 ,
35
- .idProduct = 0x5740 ,
36
- .bcdDevice = 0x0200 ,
37
- .iManufacturer = 1 ,
38
- .iProduct = 2 ,
39
- .iSerialNumber = 3 ,
40
- .bNumConfigurations = 1 ,
41
- };
23
+ #include <unicore-mx/usb/class/cdc.h>
24
+ #include <unicore-mx/usbd/misc/string.h>
25
+ #include "cdcacm-target.h"
42
26
43
27
/*
44
28
* This notification endpoint isn't implemented. According to CDC spec its
@@ -119,7 +103,7 @@ static const struct usb_interface_descriptor comm_iface[] = {{
119
103
.endpoint = comm_endp ,
120
104
121
105
.extra = & cdcacm_functional_descriptors ,
122
- .extralen = sizeof (cdcacm_functional_descriptors ),
106
+ .extra_len = sizeof (cdcacm_functional_descriptors ),
123
107
}};
124
108
125
109
static const struct usb_interface_descriptor data_iface [] = {{
@@ -144,7 +128,7 @@ static const struct usb_interface ifaces[] = {{
144
128
.altsetting = data_iface ,
145
129
}};
146
130
147
- static const struct usb_config_descriptor config = {
131
+ static const struct usb_config_descriptor config [] = { {
148
132
.bLength = USB_DT_CONFIGURATION_SIZE ,
149
133
.bDescriptorType = USB_DT_CONFIGURATION ,
150
134
.wTotalLength = 0 ,
@@ -155,25 +139,103 @@ static const struct usb_config_descriptor config = {
155
139
.bMaxPower = 0x32 ,
156
140
157
141
.interface = ifaces ,
142
+ }};
143
+
144
+ const uint8_t * usb_string_english [] = {
145
+ (uint8_t * ) "Black Sphere Technologies" ,
146
+ (uint8_t * ) "CDC-ACM Demo" ,
147
+ (uint8_t * ) "DEMO" ,
158
148
};
159
149
160
- static const char * usb_strings [] = {
161
- "Black Sphere Technologies" ,
162
- "CDC-ACM Demo" ,
163
- "DEMO" ,
150
+ /*
151
+ * Black = काला
152
+ * Sphere = गोला
153
+ * Technologies = प्रौद्योगिकी
154
+ * CDC-ACM = सीडीसी-एसीएम
155
+ * Demo, DEMO = नमूना
156
+ */
157
+ const uint8_t * usb_string_hindi [] = {
158
+ (uint8_t * ) "काला गोला प्रौद्योगिकी" ,
159
+ (uint8_t * ) "सीडीसी-एसीएम नमूना" ,
160
+ (uint8_t * ) "नमूना"
161
+ };
162
+
163
+ const uint16_t supported_lang [] = {
164
+ USB_LANGID_ENGLISH_UNITED_STATES ,
165
+ USB_LANGID_HINDI
166
+ };
167
+
168
+ static int usb_strings (usbd_device * usbd_dev , struct usbd_get_string_arg * arg )
169
+ {
170
+ (void ) usbd_dev ;
171
+
172
+ const uint8_t * * strings ;
173
+
174
+ /* supported languages */
175
+ if (!arg -> index ) {
176
+ uint16_t len = arg -> len ;
177
+ if (len > 2 ) {
178
+ len = 2 ;
179
+ }
180
+ memcpy (arg -> buf , supported_lang , len );
181
+ return len ;
182
+ }
183
+
184
+ /* we only have 3 strings */
185
+ if (arg -> index > 3 ) {
186
+ return -1 ;
187
+ }
188
+
189
+ /* language */
190
+ switch (arg -> lang_id ) {
191
+ case USB_LANGID_ENGLISH_UNITED_STATES :
192
+ strings = usb_string_english ;
193
+ break ;
194
+ case USB_LANGID_HINDI :
195
+ strings = usb_string_hindi ;
196
+ break ;
197
+ default :
198
+ return -1 ;
199
+ }
200
+
201
+ return usbd_utf8_to_utf16 (strings [arg -> index - 1 ], arg -> buf , arg -> len );
202
+ }
203
+
204
+ static const struct usb_device_descriptor dev = {
205
+ .bLength = USB_DT_DEVICE_SIZE ,
206
+ .bDescriptorType = USB_DT_DEVICE ,
207
+ .bcdUSB = 0x0200 ,
208
+ .bDeviceClass = USB_CLASS_CDC ,
209
+ .bDeviceSubClass = 0 ,
210
+ .bDeviceProtocol = 0 ,
211
+ .bMaxPacketSize0 = 64 ,
212
+ .idVendor = 0x0483 ,
213
+ .idProduct = 0x5740 ,
214
+ .bcdDevice = 0x0200 ,
215
+ .iManufacturer = 1 ,
216
+ .iProduct = 2 ,
217
+ .iSerialNumber = 3 ,
218
+ .bNumConfigurations = 1 ,
219
+
220
+ .config = config ,
164
221
};
165
222
166
223
/* Buffer to be used for control requests. */
167
224
uint8_t usbd_control_buffer [128 ];
168
225
169
- static int cdcacm_control_request ( usbd_device * usbd_dev , struct usb_setup_data * req , uint8_t * * buf ,
170
- uint16_t * len , void ( * * complete )( usbd_device * usbd_dev , struct usb_setup_data * req ) )
226
+ static enum usbd_control_result
227
+ cdcacm_control_request ( usbd_device * usbd_dev , struct usbd_control_arg * arg )
171
228
{
172
- (void )complete ;
173
- (void )buf ;
174
229
(void )usbd_dev ;
175
230
176
- switch (req -> bRequest ) {
231
+ const uint8_t bmReqMask = USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT ;
232
+ const uint8_t bmReqVal = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE ;
233
+
234
+ if ((arg -> setup .bmRequestType & bmReqMask ) != bmReqVal ) {
235
+ return USBD_REQ_NEXT ;
236
+ }
237
+
238
+ switch (arg -> setup .bRequest ) {
177
239
case USB_CDC_REQ_SET_CONTROL_LINE_STATE : {
178
240
/*
179
241
* This Linux cdc_acm driver requires this to be implemented
@@ -189,19 +251,23 @@ static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *
189
251
notif -> wValue = 0 ;
190
252
notif -> wIndex = 0 ;
191
253
notif -> wLength = 2 ;
192
- local_buf [8 ] = req -> wValue & 3 ;
254
+ local_buf [8 ] = arg -> setup . wValue & 3 ;
193
255
local_buf [9 ] = 0 ;
194
256
// usbd_ep_write_packet(0x83, buf, 10);
195
- return 1 ;
257
+ return USBD_REQ_HANDLED ;
196
258
}
197
259
case USB_CDC_REQ_SET_LINE_CODING :
198
- if (* len < sizeof (struct usb_cdc_line_coding ))
199
- return 0 ;
200
- return 1 ;
260
+ if (arg -> len < sizeof (struct usb_cdc_line_coding )) {
261
+ return USBD_REQ_STALL ;
262
+ }
263
+ return USBD_REQ_HANDLED ;
201
264
}
202
- return 0 ;
265
+ return USBD_REQ_STALL ;
203
266
}
204
267
268
+ void __attribute__((weak ))
269
+ cdcacm_target_data_rx_cb_before_return (void ) { /* empty */ }
270
+
205
271
static void cdcacm_data_rx_cb (usbd_device * usbd_dev , uint8_t ep )
206
272
{
207
273
(void )ep ;
@@ -214,53 +280,43 @@ static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
214
280
usbd_ep_write_packet (usbd_dev , 0x82 , buf , len );
215
281
buf [len ] = 0 ;
216
282
}
283
+
284
+ /* this was only found in f1/lisa-m-1/usb_cdcacm.c */
285
+ cdcacm_target_data_rx_cb_before_return ();
217
286
}
218
287
219
- static void cdcacm_set_config (usbd_device * usbd_dev , uint16_t wValue )
288
+ static void cdcacm_set_config (usbd_device * usbd_dev ,
289
+ const struct usb_config_descriptor * cfg )
220
290
{
221
- (void )wValue ;
222
- (void )usbd_dev ;
291
+ (void )cfg ;
223
292
224
293
usbd_ep_setup (usbd_dev , 0x01 , USB_ENDPOINT_ATTR_BULK , 64 , cdcacm_data_rx_cb );
225
294
usbd_ep_setup (usbd_dev , 0x82 , USB_ENDPOINT_ATTR_BULK , 64 , NULL );
226
295
usbd_ep_setup (usbd_dev , 0x83 , USB_ENDPOINT_ATTR_INTERRUPT , 16 , NULL );
227
-
228
- usbd_register_control_callback (
229
- usbd_dev ,
230
- USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE ,
231
- USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT ,
232
- cdcacm_control_request );
233
296
}
234
297
235
-
236
- static void usb_setup (void )
237
- {
238
- /* Enable clocks for GPIO port A (for GPIO_USART2_TX) and USART2. */
239
- rcc_usb_prescale_1 ();
240
- rcc_periph_clock_enable (RCC_USB );
241
- rcc_periph_clock_enable (RCC_GPIOA );
242
-
243
- /* Setup GPIO pin GPIO_USART2_TX/GPIO9 on GPIO port A for transmit. */
244
- gpio_mode_setup (GPIOA , GPIO_MODE_AF , GPIO_PUPD_NONE , GPIO11 | GPIO12 );
245
- gpio_set_af (GPIOA , GPIO_AF14 , GPIO11 | GPIO12 );
246
- }
298
+ void __attribute__((weak ))
299
+ cdcacm_target_usbd_after_init_and_before_first_poll (void ) { /* empty */ }
247
300
248
301
int main (void )
249
302
{
250
- int i ;
251
-
252
303
usbd_device * usbd_dev ;
253
304
254
- rcc_clock_setup_hsi (& rcc_hsi_8mhz [RCC_CLOCK_48MHZ ]);
255
- usb_setup ();
305
+ cdcacm_target_init ();
306
+
307
+ usbd_dev = usbd_init (cdcacm_target_usb_driver (), & dev ,
308
+ usbd_control_buffer , sizeof (usbd_control_buffer ));
256
309
257
- usbd_dev = usbd_init (& st_usbfs_v1_usb_driver , & dev , & config , usb_strings ,
258
- 3 , usbd_control_buffer , sizeof (usbd_control_buffer ));
259
310
usbd_register_set_config_callback (usbd_dev , cdcacm_set_config );
311
+ usbd_register_control_callback (usbd_dev , cdcacm_control_request );
312
+ usbd_register_get_string_callback (usbd_dev , usb_strings );
260
313
261
- for (i = 0 ; i < 0x800000 ; i ++ )
262
- __asm__("nop" );
314
+ /* on f3, here was a busy loop after usbd init and before first poll.
315
+ * as the use of the busy loop is unknow,
316
+ * retaining the code for compatibility */
317
+ cdcacm_target_usbd_after_init_and_before_first_poll ();
263
318
264
- while (1 )
319
+ while (1 ) {
265
320
usbd_poll (usbd_dev );
321
+ }
266
322
}
0 commit comments