Просмотр исходного кода

synopsys: Fix odd/even frame handling for ISO

Current implementation always sets odd/even bit for ISO transactions.
This is a good strategy only if interval is 1.
For ISO endpoint interval in (micro)frames is computed as
2^(interval-1), which means that odd/frame number should stay
same for interval values > 1.
With this change only when interval is 1 odd/even bit is modified.
Jerzy Kasenberg 5 лет назад
Родитель
Сommit
642a8b00c8
1 измененных файлов с 9 добавлено и 1 удалено
  1. 9 1
      src/portable/st/synopsys/dcd_synopsys.c

+ 9 - 1
src/portable/st/synopsys/dcd_synopsys.c

@@ -136,6 +136,7 @@ typedef struct {
   uint8_t * buffer;
   uint16_t total_len;
   uint16_t max_size;
+  uint8_t interval;
 } xfer_ctl_t;
 
 // EP size and transfer type report
@@ -440,7 +441,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
 
     in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK;
     // For ISO endpoint set correct odd/even bit for next frame.
-    if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0)
+    if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
     {
       // Take odd/even bit from frame counter.
       uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos));
@@ -457,6 +458,12 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
         ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk);
 
     out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
+    if ((out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP) == USB_OTG_DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
+    {
+      // Take odd/even bit from frame counter.
+      uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos));
+      out_ep[epnum].DOEPCTL |= (odd_frame_now ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DOEPCTL_SODDFRM_Msk);
+    }
   }
 }
 
@@ -608,6 +615,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
 
   xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
   xfer->max_size = desc_edpt->wMaxPacketSize.size;
+  xfer->interval = desc_edpt->bInterval;
 
   if(dir == TUSB_DIR_OUT)
   {