@@ -92,6 +92,8 @@ struct usb_ep_ctrl_data {
9292 u16_t out_data1 : 1 ;
9393 u16_t in_odd : 1 ;
9494 u16_t out_odd : 1 ;
95+ u16_t in_stalled : 1 ;
96+ u16_t out_stalled : 1 ;
9597 } status ;
9698 u16_t mps_in ;
9799 u16_t mps_out ;
@@ -279,6 +281,13 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)
279281 return - EINVAL ;
280282 }
281283
284+ if (ep_idx && (dev_data .ep_ctrl [ep_idx ].status .in_enabled ||
285+ dev_data .ep_ctrl [ep_idx ].status .out_enabled )) {
286+ SYS_LOG_WRN ("endpoint already configured" );
287+ return - EBUSY ;
288+ }
289+
290+
282291 SYS_LOG_DBG ("ep %x, mps %d, type %d" ,
283292 cfg -> ep_addr ,
284293 cfg -> ep_mps ,
@@ -355,30 +364,63 @@ int usb_dc_ep_configure(const struct usb_dc_ep_cfg_data * const cfg)
355364int usb_dc_ep_set_stall (const u8_t ep )
356365{
357366 u8_t ep_idx = EP_ADDR2IDX (ep );
367+ u8_t bd_idx ;
358368
359369 if (ep_idx > NUM_OF_EP_MAX ) {
360370 SYS_LOG_ERR ("Wrong endpoint index/address" );
361371 return - EINVAL ;
362372 }
363373
364- SYS_LOG_DBG ("ep %x, idx %d" , ep_idx , ep );
365- USB0 -> ENDPOINT [ep_idx ].ENDPT |= USB_ENDPT_EPSTALL_MASK ;
374+ SYS_LOG_DBG ("ep %x, idx %d" , ep , ep_idx );
375+
376+ if (EP_ADDR2DIR (ep ) == USB_EP_DIR_OUT ) {
377+ dev_data .ep_ctrl [ep_idx ].status .out_stalled = 1 ;
378+ bd_idx = get_bdt_idx (ep ,
379+ ~dev_data .ep_ctrl [ep_idx ].status .out_odd );
380+ } else {
381+ dev_data .ep_ctrl [ep_idx ].status .in_stalled = 1 ;
382+ bd_idx = get_bdt_idx (ep ,
383+ dev_data .ep_ctrl [ep_idx ].status .in_odd );
384+ }
385+
386+ bdt [bd_idx ].set .bd_ctrl = BD_STALL_MASK | BD_DTS_MASK | BD_OWN_MASK ;
366387
367388 return 0 ;
368389}
369390
370391int usb_dc_ep_clear_stall (const u8_t ep )
371392{
372393 u8_t ep_idx = EP_ADDR2IDX (ep );
394+ u8_t bd_idx ;
373395
374396 if (ep_idx > NUM_OF_EP_MAX ) {
375397 SYS_LOG_ERR ("Wrong endpoint index/address" );
376398 return - EINVAL ;
377399 }
378400
379- SYS_LOG_DBG ("ep %x, idx %d" , ep_idx , ep );
401+ SYS_LOG_DBG ("ep %x, idx %d" , ep , ep_idx );
380402 USB0 -> ENDPOINT [ep_idx ].ENDPT &= ~USB_ENDPT_EPSTALL_MASK ;
381403
404+ if (EP_ADDR2DIR (ep ) == USB_EP_DIR_OUT ) {
405+ dev_data .ep_ctrl [ep_idx ].status .out_stalled = 0 ;
406+ dev_data .ep_ctrl [ep_idx ].status .out_data1 = false;
407+ bd_idx = get_bdt_idx (ep ,
408+ ~dev_data .ep_ctrl [ep_idx ].status .out_odd );
409+ bdt [bd_idx ].set .bd_ctrl = 0 ;
410+ bdt [bd_idx ].set .bd_ctrl = BD_DTS_MASK | BD_OWN_MASK ;
411+ } else {
412+ dev_data .ep_ctrl [ep_idx ].status .in_stalled = 0 ;
413+ dev_data .ep_ctrl [ep_idx ].status .in_data1 = false;
414+ bd_idx = get_bdt_idx (ep ,
415+ dev_data .ep_ctrl [ep_idx ].status .in_odd );
416+ bdt [bd_idx ].set .bd_ctrl = 0 ;
417+ }
418+
419+ /* Resume TX token processing, see USBx_CTL field descriptions */
420+ if (ep == 0 ) {
421+ USB0 -> CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK ;
422+ }
423+
382424 return 0 ;
383425}
384426
@@ -397,8 +439,20 @@ int usb_dc_ep_is_stalled(const u8_t ep, u8_t *const stalled)
397439 }
398440
399441 * stalled = 0 ;
400- if (USB0 -> ENDPOINT [ep_idx ].ENDPT & USB_ENDPT_EPSTALL_MASK ) {
401- * stalled = 1 ;
442+ if (EP_ADDR2DIR (ep ) == USB_EP_DIR_OUT ) {
443+ * stalled = dev_data .ep_ctrl [ep_idx ].status .out_stalled ;
444+ } else {
445+ * stalled = dev_data .ep_ctrl [ep_idx ].status .in_stalled ;
446+ }
447+
448+ if (SYS_LOG_LEVEL == SYS_LOG_LEVEL_INFO ) {
449+ u8_t bd_idx = get_bdt_idx (ep ,
450+ dev_data .ep_ctrl [ep_idx ].status .in_odd );
451+ bd_idx = bd_idx ;
452+ SYS_LOG_WRN ("active bd ctrl: %x" , bdt [bd_idx ].set .bd_ctrl );
453+ bd_idx = get_bdt_idx (ep ,
454+ ~dev_data .ep_ctrl [ep_idx ].status .in_odd );
455+ SYS_LOG_WRN ("next bd ctrl: %x" , bdt [bd_idx ].set .bd_ctrl );
402456 }
403457
404458 return 0 ;
@@ -420,16 +474,24 @@ int usb_dc_ep_enable(const u8_t ep)
420474 return - EINVAL ;
421475 }
422476
477+ if (ep_idx && (dev_data .ep_ctrl [ep_idx ].status .in_enabled ||
478+ dev_data .ep_ctrl [ep_idx ].status .out_enabled )) {
479+ SYS_LOG_WRN ("endpoint 0x%x already enabled" , ep );
480+ return - EBUSY ;
481+ }
482+
423483 if (EP_ADDR2DIR (ep ) == USB_EP_DIR_OUT ) {
424484 bdt [idx_even ].set .bd_ctrl = BD_DTS_MASK | BD_OWN_MASK ;
425485 bdt [idx_odd ].set .bd_ctrl = 0 ;
426486 dev_data .ep_ctrl [ep_idx ].status .out_odd = 0 ;
487+ dev_data .ep_ctrl [ep_idx ].status .out_stalled = 0 ;
427488 dev_data .ep_ctrl [ep_idx ].status .out_data1 = false;
428489 dev_data .ep_ctrl [ep_idx ].status .out_enabled = true;
429490 } else {
430491 bdt [idx_even ].bd_fields = 0 ;
431492 bdt [idx_odd ].bd_fields = 0 ;
432493 dev_data .ep_ctrl [ep_idx ].status .in_odd = 0 ;
494+ dev_data .ep_ctrl [ep_idx ].status .in_stalled = 0 ;
433495 dev_data .ep_ctrl [ep_idx ].status .in_data1 = false;
434496 dev_data .ep_ctrl [ep_idx ].status .in_enabled = true;
435497 }
@@ -496,6 +558,11 @@ int usb_dc_ep_write(const u8_t ep, const u8_t *const data,
496558 return - EINVAL ;
497559 }
498560
561+ if (dev_data .ep_ctrl [ep_idx ].status .in_stalled ) {
562+ SYS_LOG_WRN ("endpoint is stalled" );
563+ return - EBUSY ;
564+ }
565+
499566 while (bdt [bd_idx ].get .own ) {
500567 SYS_LOG_DBG ("ep 0x%x is busy" , ep );
501568 k_yield ();
@@ -554,6 +621,11 @@ int usb_dc_ep_read_wait(u8_t ep, u8_t *data, u32_t max_data_len,
554621 return - EINVAL ;
555622 }
556623
624+ if (dev_data .ep_ctrl [ep_idx ].status .out_stalled ) {
625+ SYS_LOG_WRN ("endpoint is stalled" );
626+ return - EBUSY ;
627+ }
628+
557629 /* Allow to read 0 bytes */
558630 if (!data && max_data_len ) {
559631 SYS_LOG_ERR ("Wrong arguments" );
@@ -629,7 +701,7 @@ int usb_dc_ep_read_continue(u8_t ep)
629701 bdt [bd_idx ].set .bd_ctrl = BD_DTS_MASK | BD_OWN_MASK ;
630702 }
631703
632- /* Resume TX toke processing, see USBx_CTL field descriptions */
704+ /* Resume TX token processing, see USBx_CTL field descriptions */
633705 if (ep_idx == 0 ) {
634706 USB0 -> CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK ;
635707 }
@@ -642,8 +714,10 @@ int usb_dc_ep_read_continue(u8_t ep)
642714int usb_dc_ep_read (const u8_t ep , u8_t * const data ,
643715 const u32_t max_data_len , u32_t * const read_bytes )
644716{
645- if (usb_dc_ep_read_wait (ep , data , max_data_len , read_bytes ) != 0 ) {
646- return - EINVAL ;
717+ int retval = usb_dc_ep_read_wait (ep , data , max_data_len , read_bytes );
718+
719+ if (retval ) {
720+ return retval ;
647721 }
648722
649723 if (!data && !max_data_len ) {
@@ -745,9 +819,11 @@ static void usb_kinetis_isr_handler(void)
745819 }
746820
747821 if (istatus & USB_ISTAT_STALL_MASK ) {
748- if (istatus & USB_ISTAT_STALL_MASK ) {
749- /* STALL handshake was sent, unset STALL for EP0. */
750- USB0 -> ENDPOINT [0 ].ENDPT &= ~USB_ENDPT_EPSTALL_MASK ;
822+ if (dev_data .ep_ctrl [0 ].status .out_stalled ) {
823+ usb_dc_ep_clear_stall (0 );
824+ }
825+ if (dev_data .ep_ctrl [0 ].status .in_stalled ) {
826+ usb_dc_ep_clear_stall (0x80 );
751827 }
752828 }
753829
0 commit comments