@@ -322,15 +322,15 @@ static void handle_msg_data_out(struct udc_stm32_data *priv, uint8_t epnum, uint
322322 LOG_DBG ("DataOut ep 0x%02x" , ep );
323323
324324 epcfg = udc_get_ep_cfg (dev , ep );
325- udc_ep_set_busy (epcfg , false);
326-
327325 buf = udc_buf_get (epcfg );
328326 if (unlikely (buf == NULL )) {
327+ udc_ep_set_busy (epcfg , false);
329328 LOG_ERR ("ep 0x%02x queue is empty" , ep );
330329 return ;
331330 }
332331
333332 net_buf_add (buf , rx_count );
333+ udc_ep_set_busy (epcfg , false);
334334
335335 if (ep == USB_CONTROL_EP_OUT ) {
336336 if (udc_ctrl_stage_is_status_out (dev )) {
@@ -353,6 +353,40 @@ static void handle_msg_data_out(struct udc_stm32_data *priv, uint8_t epnum, uint
353353 }
354354}
355355
356+ static void handle_msg_data_ep0_out (struct udc_stm32_data * priv , uint8_t epnum , uint16_t rx_count )
357+ {
358+ const struct device * dev = priv -> dev ;
359+ struct udc_ep_config * epcfg ;
360+ uint8_t ep = epnum | USB_EP_DIR_OUT ;
361+ struct net_buf * buf ;
362+ uint8_t * data ;
363+ uint32_t len ;
364+
365+ epcfg = udc_get_ep_cfg (dev , ep );
366+ buf = udc_buf_peek (epcfg );
367+ if (unlikely (buf == NULL )) {
368+ udc_ep_set_busy (epcfg , false);
369+ return ;
370+ }
371+
372+ len = net_buf_tailroom (buf );
373+
374+ /* Check if all data was transferred and then go back to normal flow
375+ * otherwise continue receiving data
376+ */
377+ LOG_DBG ("xfer size: %d, free: %d, size: %d" , rx_count , len , buf -> size );
378+ if (len == rx_count || rx_count < epcfg -> mps ) {
379+ /* busy will be release in handle_msg_data_out() */
380+ handle_msg_data_out (priv , epnum , rx_count );
381+ return ;
382+ }
383+
384+ net_buf_add (buf , rx_count );
385+ data = net_buf_tail (buf );
386+
387+ HAL_PCD_EP_Receive (& priv -> pcd , epcfg -> addr , data , buf -> size );
388+ }
389+
356390static void handle_msg_data_in (struct udc_stm32_data * priv , uint8_t epnum )
357391{
358392 const struct device * dev = priv -> dev ;
@@ -363,13 +397,14 @@ static void handle_msg_data_in(struct udc_stm32_data *priv, uint8_t epnum)
363397 LOG_DBG ("DataIn ep 0x%02x" , ep );
364398
365399 epcfg = udc_get_ep_cfg (dev , ep );
366- udc_ep_set_busy (epcfg , false);
367-
368400 buf = udc_buf_peek (epcfg );
369401 if (unlikely (buf == NULL )) {
402+ udc_ep_set_busy (epcfg , false);
370403 return ;
371404 }
372405
406+ udc_ep_set_busy (epcfg , false);
407+
373408 if (ep == USB_CONTROL_EP_IN && buf -> len ) {
374409 const struct udc_stm32_config * cfg = dev -> config ;
375410 uint32_t len = MIN (cfg -> ep0_mps , buf -> len );
@@ -420,22 +455,38 @@ static void handle_msg_data_in(struct udc_stm32_data *priv, uint8_t epnum)
420455 }
421456}
422457
458+ static void drop_control_transfers (const struct device * dev )
459+ {
460+ struct net_buf * buf ;
461+
462+ buf = udc_buf_get_all (udc_get_ep_cfg (dev , USB_CONTROL_EP_OUT ));
463+ if (buf != NULL ) {
464+ net_buf_unref (buf );
465+ }
466+
467+ buf = udc_buf_get_all (udc_get_ep_cfg (dev , USB_CONTROL_EP_IN ));
468+ if (buf != NULL ) {
469+ net_buf_unref (buf );
470+ }
471+ }
472+
423473static void handle_msg_setup (struct udc_stm32_data * priv )
424474{
425475 struct usb_setup_packet * setup = (void * )priv -> pcd .Setup ;
426476 const struct device * dev = priv -> dev ;
427477 struct net_buf * buf ;
428478 int err ;
429479
480+ drop_control_transfers (dev );
481+
430482 buf = udc_ctrl_alloc (dev , USB_CONTROL_EP_OUT , sizeof (struct usb_setup_packet ));
431483 if (buf == NULL ) {
432484 LOG_ERR ("Failed to allocate for setup" );
433485 return ;
434486 }
435487
488+ net_buf_add_mem (buf , setup , sizeof (struct usb_setup_packet ));
436489 udc_ep_buf_set_setup (buf );
437- memcpy (buf -> data , setup , 8 );
438- net_buf_add (buf , 8 );
439490
440491 udc_ctrl_update_stage (dev , buf );
441492
@@ -450,13 +501,16 @@ static void handle_msg_setup(struct udc_stm32_data *priv)
450501
451502 if (udc_ctrl_stage_is_data_out (dev )) {
452503 /* Allocate and feed buffer for data OUT stage */
504+ LOG_DBG ("s:%p|feed for -out-" , (void * )buf );
453505 err = usbd_ctrl_feed_dout (dev , udc_data_stage_length (buf ));
454506 if (err == - ENOMEM ) {
455507 udc_submit_ep_event (dev , buf , err );
456508 }
457509 } else if (udc_ctrl_stage_is_data_in (dev )) {
510+ LOG_DBG ("s:%p|feed for -in-status" , (void * )buf );
458511 udc_ctrl_submit_s_in_status (dev );
459512 } else {
513+ LOG_DBG ("s:%p|no data" , (void * )buf );
460514 udc_ctrl_submit_s_status (dev );
461515 }
462516}
@@ -477,7 +531,12 @@ static void udc_stm32_thread_handler(void *arg1, void *arg2, void *arg3)
477531 handle_msg_data_in (priv , msg .ep );
478532 break ;
479533 case UDC_STM32_MSG_DATA_OUT :
480- handle_msg_data_out (priv , msg .ep , msg .rx_count );
534+ /* workaround to xfer data stage on ep0 */
535+ if (msg .ep == USB_CONTROL_EP_OUT ) {
536+ handle_msg_data_ep0_out (priv , msg .ep , msg .rx_count );
537+ } else {
538+ handle_msg_data_out (priv , msg .ep , msg .rx_count );
539+ }
481540 break ;
482541 }
483542 }
0 commit comments