2121#include <string.h>
2222#include <unicore-mx/usbd/usbd.h>
2323#include <unicore-mx/usb/class/cdc.h>
24- #include <unicore-mx/usbd/misc/string.h>
2524#include "cdcacm-target.h"
2625
2726/*
@@ -128,20 +127,7 @@ static const struct usb_interface ifaces[] = {{
128127 .altsetting = data_iface ,
129128}};
130129
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 [] = {
145131 (uint8_t * ) "Black Sphere Technologies" ,
146132 (uint8_t * ) "CDC-ACM Demo" ,
147133 (uint8_t * ) "DEMO" ,
@@ -154,52 +140,37 @@ const uint8_t *usb_string_english[] = {
154140 * CDC-ACM = सीडीसी-एसीएम
155141 * Demo, DEMO = नमूना
156142 */
157- const uint8_t * usb_string_hindi [] = {
143+ const uint8_t * usb_strings_hindi [] = {
158144 (uint8_t * ) "काला गोला प्रौद्योगिकी" ,
159145 (uint8_t * ) "सीडीसी-एसीएम नमूना" ,
160146 (uint8_t * ) "नमूना"
161147};
162148
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+ }};
188160
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 ,
200170
201- return usbd_utf8_to_utf16 (strings [arg -> index - 1 ], arg -> buf , arg -> len );
202- }
171+ .interface = ifaces ,
172+ .string = usb_strings
173+ }};
203174
204175static const struct usb_device_descriptor dev = {
205176 .bLength = USB_DT_DEVICE_SIZE ,
@@ -218,67 +189,120 @@ static const struct usb_device_descriptor dev = {
218189 .bNumConfigurations = 1 ,
219190
220191 .config = config ,
192+ .string = usb_strings
221193};
222194
223195/* Buffer to be used for control requests. */
224- uint8_t usbd_control_buffer [128 ];
196+ uint8_t usbd_control_buffer [128 ] __attribute__(( aligned ( 2 ))) ;
225197
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 )
228200{
229- (void )usbd_dev ;
201+ (void ) ep ; /* assuming ep == 0 */
230202
231203 const uint8_t bmReqMask = USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT ;
232204 const uint8_t bmReqVal = USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE ;
233205
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 ;
236210 }
237211
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 :
240214 /*
241215 * This Linux cdc_acm driver requires this to be implemented
242216 * even though it's optional in the CDC spec, and we don't
243217 * advertise it in the ACM functional descriptor.
244218 */
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 ;
259221 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 ;
262224 }
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 ;
264230 }
265- return USBD_REQ_STALL ;
231+
232+ usbd_ep0_stall (usbd_dev );
266233}
267234
268235void __attribute__((weak ))
269236cdcacm_target_data_rx_cb_before_return (void ) { /* empty */ }
270237
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 )
272285{
273- (void )ep ;
274- (void )usbd_dev ;
286+ (void ) urb_id ;
287+ (void ) transfer ;
275288
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+ }
278293
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+ }
282306 }
283307
284308 /* 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,
289313 const struct usb_config_descriptor * cfg )
290314{
291315 (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 );
292319
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 );
296321}
297322
298323void __attribute__((weak ))
299324cdcacm_target_usbd_after_init_and_before_first_poll (void ) { /* empty */ }
300325
326+ const usbd_backend_config * __attribute__ ( (weak ))
327+ cdcacm_target_usb_config (void ) { return NULL ; }
328+
301329int main (void )
302330{
303331 usbd_device * usbd_dev ;
304332
305333 cdcacm_target_init ();
306334
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 ,
308337 usbd_control_buffer , sizeof (usbd_control_buffer ));
309338
310339 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 );
313341
314342 /* on f3, here was a busy loop after usbd init and before first poll.
315343 * as the use of the busy loop is unknow,
316344 * retaining the code for compatibility */
317345 cdcacm_target_usbd_after_init_and_before_first_poll ();
318346
319347 while (1 ) {
320- usbd_poll (usbd_dev );
348+ usbd_poll (usbd_dev , 0 );
321349 }
322350}
0 commit comments