21
21
#include <string.h>
22
22
#include <unicore-mx/usbd/usbd.h>
23
23
#include <unicore-mx/usb/class/cdc.h>
24
- #include <unicore-mx/usbd/misc/string.h>
25
24
#include "cdcacm-target.h"
26
25
27
26
/*
@@ -128,20 +127,7 @@ static const struct usb_interface ifaces[] = {{
128
127
.altsetting = data_iface ,
129
128
}};
130
129
131
- static const struct usb_config_descriptor config [] = {{
132
- .bLength = USB_DT_CONFIGURATION_SIZE ,
133
- .bDescriptorType = USB_DT_CONFIGURATION ,
134
- .wTotalLength = 0 ,
135
- .bNumInterfaces = 2 ,
136
- .bConfigurationValue = 1 ,
137
- .iConfiguration = 0 ,
138
- .bmAttributes = 0x80 ,
139
- .bMaxPower = 0x32 ,
140
-
141
- .interface = ifaces ,
142
- }};
143
-
144
- const uint8_t * usb_string_english [] = {
130
+ const uint8_t * usb_strings_english [] = {
145
131
(uint8_t * ) "Black Sphere Technologies" ,
146
132
(uint8_t * ) "CDC-ACM Demo" ,
147
133
(uint8_t * ) "DEMO" ,
@@ -154,52 +140,37 @@ const uint8_t *usb_string_english[] = {
154
140
* CDC-ACM = सीडीसी-एसीएम
155
141
* Demo, DEMO = नमूना
156
142
*/
157
- const uint8_t * usb_string_hindi [] = {
143
+ const uint8_t * usb_strings_hindi [] = {
158
144
(uint8_t * ) "काला गोला प्रौद्योगिकी" ,
159
145
(uint8_t * ) "सीडीसी-एसीएम नमूना" ,
160
146
(uint8_t * ) "नमूना"
161
147
};
162
148
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
- }
149
+ const struct usb_string_utf8_data usb_strings [] = {{
150
+ .data = usb_strings_english ,
151
+ .count = 3 ,
152
+ .lang_id = USB_LANGID_ENGLISH_UNITED_STATES
153
+ }, {
154
+ .data = usb_strings_hindi ,
155
+ .count = 3 ,
156
+ .lang_id = USB_LANGID_HINDI
157
+ }, {
158
+ .data = NULL
159
+ }};
188
160
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
- }
161
+ static const struct usb_config_descriptor config [] = {{
162
+ .bLength = USB_DT_CONFIGURATION_SIZE ,
163
+ .bDescriptorType = USB_DT_CONFIGURATION ,
164
+ .wTotalLength = 0 ,
165
+ .bNumInterfaces = 2 ,
166
+ .bConfigurationValue = 1 ,
167
+ .iConfiguration = 0 ,
168
+ .bmAttributes = 0x80 ,
169
+ .bMaxPower = 0x32 ,
200
170
201
- return usbd_utf8_to_utf16 (strings [arg -> index - 1 ], arg -> buf , arg -> len );
202
- }
171
+ .interface = ifaces ,
172
+ .string = usb_strings
173
+ }};
203
174
204
175
static const struct usb_device_descriptor dev = {
205
176
.bLength = USB_DT_DEVICE_SIZE ,
@@ -218,67 +189,120 @@ static const struct usb_device_descriptor dev = {
218
189
.bNumConfigurations = 1 ,
219
190
220
191
.config = config ,
192
+ .string = usb_strings
221
193
};
222
194
223
195
/* Buffer to be used for control requests. */
224
- uint8_t usbd_control_buffer [128 ];
196
+ uint8_t usbd_control_buffer [128 ] __attribute__(( aligned ( 2 ))) ;
225
197
226
- static enum usbd_control_result
227
- cdcacm_control_request ( usbd_device * usbd_dev , struct usbd_control_arg * arg )
198
+ static void cdcacm_control_request ( usbd_device * usbd_dev , uint8_t ep ,
199
+ const struct usb_setup_data * setup_data )
228
200
{
229
- (void )usbd_dev ;
201
+ (void ) ep ; /* assuming ep == 0 */
230
202
231
203
const uint8_t bmReqMask = USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT ;
232
204
const uint8_t bmReqVal = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE ;
233
205
234
- if ((arg -> setup .bmRequestType & bmReqMask ) != bmReqVal ) {
235
- return USBD_REQ_NEXT ;
206
+ if ((setup_data -> bmRequestType & bmReqMask ) != bmReqVal ) {
207
+ /* Pass on to usb stack internal */
208
+ usbd_ep0_setup (usbd_dev , setup_data );
209
+ return ;
236
210
}
237
211
238
- switch (arg -> setup . bRequest ) {
239
- case USB_CDC_REQ_SET_CONTROL_LINE_STATE : {
212
+ switch (setup_data -> bRequest ) {
213
+ case USB_CDC_REQ_SET_CONTROL_LINE_STATE :
240
214
/*
241
215
* This Linux cdc_acm driver requires this to be implemented
242
216
* even though it's optional in the CDC spec, and we don't
243
217
* advertise it in the ACM functional descriptor.
244
218
*/
245
- char local_buf [10 ];
246
- struct usb_cdc_notification * notif = (void * )local_buf ;
247
-
248
- /* We echo signals back to host as notification. */
249
- notif -> bmRequestType = 0xA1 ;
250
- notif -> bNotification = USB_CDC_NOTIFY_SERIAL_STATE ;
251
- notif -> wValue = 0 ;
252
- notif -> wIndex = 0 ;
253
- notif -> wLength = 2 ;
254
- local_buf [8 ] = arg -> setup .wValue & 3 ;
255
- local_buf [9 ] = 0 ;
256
- // usbd_ep_write_packet(0x83, buf, 10);
257
- return USBD_REQ_HANDLED ;
258
- }
219
+ usbd_ep0_transfer (usbd_dev , setup_data , NULL , 0 , NULL );
220
+ return ;
259
221
case USB_CDC_REQ_SET_LINE_CODING :
260
- if (arg -> len < sizeof (struct usb_cdc_line_coding )) {
261
- return USBD_REQ_STALL ;
222
+ if (setup_data -> wLength < sizeof (struct usb_cdc_line_coding )) {
223
+ break ;
262
224
}
263
- return USBD_REQ_HANDLED ;
225
+
226
+ /* Just read what ever host is sending and do the status stage */
227
+ usbd_ep0_transfer (usbd_dev , setup_data , usbd_control_buffer ,
228
+ setup_data -> wLength , NULL );
229
+ return ;
264
230
}
265
- return USBD_REQ_STALL ;
231
+
232
+ usbd_ep0_stall (usbd_dev );
266
233
}
267
234
268
235
void __attribute__((weak ))
269
236
cdcacm_target_data_rx_cb_before_return (void ) { /* empty */ }
270
237
271
- static void cdcacm_data_rx_cb (usbd_device * usbd_dev , uint8_t ep )
238
+ static uint8_t bulk_buf [64 ];
239
+
240
+ static void cdcacm_data_rx_cb (usbd_device * usbd_dev ,
241
+ const usbd_transfer * _transfer , usbd_transfer_status status ,
242
+ usbd_urb_id urb_id );
243
+
244
+ static void cdcacm_data_tx_cb (usbd_device * usbd_dev ,
245
+ const usbd_transfer * _transfer , usbd_transfer_status status ,
246
+ usbd_urb_id urb_id );
247
+
248
+ static void rx_from_host (usbd_device * usbd_dev )
249
+ {
250
+ const usbd_transfer transfer = {
251
+ .ep_type = USBD_EP_BULK ,
252
+ .ep_addr = 0x01 ,
253
+ .ep_size = 64 ,
254
+ .ep_interval = USBD_INTERVAL_NA ,
255
+ .buffer = bulk_buf ,
256
+ .length = 64 ,
257
+ .flags = USBD_FLAG_SHORT_PACKET ,
258
+ .timeout = USBD_TIMEOUT_NEVER ,
259
+ .callback = cdcacm_data_rx_cb
260
+ };
261
+
262
+ usbd_transfer_submit (usbd_dev , & transfer );
263
+ }
264
+
265
+ static void tx_to_host (usbd_device * usbd_dev , void * data , size_t len )
266
+ {
267
+ const usbd_transfer transfer = {
268
+ .ep_type = USBD_EP_BULK ,
269
+ .ep_addr = 0x82 ,
270
+ .ep_size = 64 ,
271
+ .ep_interval = USBD_INTERVAL_NA ,
272
+ .buffer = data ,
273
+ .length = len ,
274
+ .flags = USBD_FLAG_SHORT_PACKET ,
275
+ .timeout = USBD_TIMEOUT_NEVER ,
276
+ .callback = cdcacm_data_tx_cb
277
+ };
278
+
279
+ usbd_transfer_submit (usbd_dev , & transfer );
280
+ }
281
+
282
+ static void cdcacm_data_tx_cb (usbd_device * usbd_dev ,
283
+ const usbd_transfer * transfer , usbd_transfer_status status ,
284
+ usbd_urb_id urb_id )
272
285
{
273
- (void )ep ;
274
- (void )usbd_dev ;
286
+ (void ) urb_id ;
287
+ (void ) transfer ;
275
288
276
- char buf [64 ];
277
- int len = usbd_ep_read_packet (usbd_dev , 0x01 , buf , 64 );
289
+ if (status == USBD_SUCCESS ) {
290
+ rx_from_host (usbd_dev );
291
+ }
292
+ }
278
293
279
- if (len ) {
280
- usbd_ep_write_packet (usbd_dev , 0x82 , buf , len );
281
- buf [len ] = 0 ;
294
+ static void cdcacm_data_rx_cb (usbd_device * usbd_dev ,
295
+ const usbd_transfer * transfer , usbd_transfer_status status ,
296
+ usbd_urb_id urb_id )
297
+ {
298
+ (void ) urb_id ;
299
+
300
+ if (status == USBD_SUCCESS ) {
301
+ if (transfer -> transferred ) {
302
+ tx_to_host (usbd_dev , transfer -> buffer , transfer -> transferred );
303
+ } else {
304
+ usbd_transfer_submit (usbd_dev , transfer ); /* re-submit */
305
+ }
282
306
}
283
307
284
308
/* this was only found in f1/lisa-m-1/usb_cdcacm.c */
@@ -289,34 +313,38 @@ static void cdcacm_set_config(usbd_device *usbd_dev,
289
313
const struct usb_config_descriptor * cfg )
290
314
{
291
315
(void )cfg ;
316
+ usbd_ep_prepare (usbd_dev , 0x01 , USBD_EP_BULK , 64 , USBD_INTERVAL_NA , USBD_EP_NONE );
317
+ usbd_ep_prepare (usbd_dev , 0x82 , USBD_EP_BULK , 64 , USBD_INTERVAL_NA , USBD_EP_NONE );
318
+ usbd_ep_prepare (usbd_dev , 0x83 , USBD_EP_INTERRUPT , 16 , USBD_INTERVAL_NA , USBD_EP_NONE );
292
319
293
- usbd_ep_setup (usbd_dev , 0x01 , USB_ENDPOINT_ATTR_BULK , 64 , cdcacm_data_rx_cb );
294
- usbd_ep_setup (usbd_dev , 0x82 , USB_ENDPOINT_ATTR_BULK , 64 , NULL );
295
- usbd_ep_setup (usbd_dev , 0x83 , USB_ENDPOINT_ATTR_INTERRUPT , 16 , NULL );
320
+ rx_from_host (usbd_dev );
296
321
}
297
322
298
323
void __attribute__((weak ))
299
324
cdcacm_target_usbd_after_init_and_before_first_poll (void ) { /* empty */ }
300
325
326
+ const usbd_backend_config * __attribute__ ( (weak ))
327
+ cdcacm_target_usb_config (void ) { return NULL ; }
328
+
301
329
int main (void )
302
330
{
303
331
usbd_device * usbd_dev ;
304
332
305
333
cdcacm_target_init ();
306
334
307
- usbd_dev = usbd_init (cdcacm_target_usb_driver (), & dev ,
335
+ usbd_dev = usbd_init (cdcacm_target_usb_driver (),
336
+ cdcacm_target_usb_config (), & dev ,
308
337
usbd_control_buffer , sizeof (usbd_control_buffer ));
309
338
310
339
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 );
340
+ usbd_register_setup_callback (usbd_dev , cdcacm_control_request );
313
341
314
342
/* on f3, here was a busy loop after usbd init and before first poll.
315
343
* as the use of the busy loop is unknow,
316
344
* retaining the code for compatibility */
317
345
cdcacm_target_usbd_after_init_and_before_first_poll ();
318
346
319
347
while (1 ) {
320
- usbd_poll (usbd_dev );
348
+ usbd_poll (usbd_dev , 0 );
321
349
}
322
350
}
0 commit comments