@@ -597,18 +597,31 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request
597
597
{
598
598
uint32_t ep_addr = (request -> wIndex );
599
599
600
+ // At this point, a transfer MAY be in progress. Based on USB spec, when clearing bulk EP HALT,
601
+ // the EP transfer buffer needs to be cleared and DTOG needs to be reset, even if
602
+ // the EP is not halted. The only USBD API interface to do this is to stall and then unstall the EP.
600
603
if (ep_addr == usbtmc_state .ep_bulk_out )
601
604
{
602
605
criticalEnter ();
606
+ usbd_edpt_stall (rhport , ep_addr );
607
+ usbd_edpt_clear_stall (rhport , ep_addr );
603
608
usbtmc_state .state = STATE_NAK ; // USBD core has placed EP in NAK state for us
604
609
criticalLeave ();
605
610
tud_usbtmc_bulkOut_clearFeature_cb ();
606
611
}
607
612
else if (ep_addr == usbtmc_state .ep_bulk_in )
608
613
{
614
+ usbd_edpt_stall (rhport , ep_addr );
615
+ usbd_edpt_clear_stall (rhport , ep_addr );
609
616
tud_usbtmc_bulkIn_clearFeature_cb ();
610
617
}
611
- else
618
+ else if ((usbtmc_state .ep_int_in != 0 ) && (ep_addr == usbtmc_state .ep_int_in ))
619
+ {
620
+ // Clearing interrupt in EP
621
+ usbd_edpt_stall (rhport , ep_addr );
622
+ usbd_edpt_clear_stall (rhport , ep_addr );
623
+ }
624
+ else
612
625
{
613
626
return false;
614
627
}
@@ -836,6 +849,7 @@ bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request
836
849
},
837
850
.StatusByte = tud_usbtmc_get_stb_cb (& (rsp .USBTMC_status ))
838
851
};
852
+ // USB488 spec states that transfer must be queued before control request response sent.
839
853
usbd_edpt_xfer (rhport , usbtmc_state .ep_int_in , (void * )& intMsg , sizeof (intMsg ));
840
854
}
841
855
else
0 commit comments