瀏覽代碼

f7 usb: Smarter rx buffer allocation.

Keir Fraser 4 年之前
父節點
當前提交
0d61c7125a
共有 1 個文件被更改,包括 35 次插入17 次删除
  1. 35 17
      src/usb/hw_dwc_otg.c

+ 35 - 17
src/usb/hw_dwc_otg.c

@@ -11,15 +11,16 @@
 
 #include "hw_dwc_otg.h"
 
-#define RX_NR 8
-#define RX_MASK(x) ((x) & (RX_NR-1))
+struct rx_buf {
+    uint32_t data[USB_FS_MPS / 4];
+    uint32_t count;
+} rx_buf0[1], rx_bufn[32];
+
+#define RX_MASK(_ep, _idx) (((_ep)->_idx) & ((_ep)->rx_nr - 1))
 
 static struct ep {
-    struct {
-        uint32_t data[USB_FS_MPS / 4];
-        uint32_t count;
-    } rx[RX_NR];
-    uint16_t rxc, rxp;
+    struct rx_buf *rx;
+    uint16_t rxc, rxp, rx_nr;
     bool_t rx_active, tx_ready;
 } eps[conf_nr_ep];
 
@@ -57,18 +58,18 @@ static bool_t is_high_speed(void)
 
 static void prepare_rx(uint8_t epnr)
 {
+    struct ep *ep = &eps[epnr];
     OTG_DOEP doep = &otg_doep[epnr];
     uint16_t mps = (epnr == 0) ? 64 : (doep->ctl & 0x7ff);
     uint32_t tsiz = doep->tsiz & 0xe0000000;
-    int pktcnt = (epnr == 0) ? 1 : RX_NR;
 
-    tsiz |= OTG_DOEPTSZ_PKTCNT(pktcnt);
-    tsiz |= OTG_DOEPTSZ_XFERSIZ(mps * pktcnt);
+    tsiz |= OTG_DOEPTSZ_PKTCNT(ep->rx_nr);
+    tsiz |= OTG_DOEPTSZ_XFERSIZ(mps * ep->rx_nr);
     doep->tsiz = tsiz;
 
     doep->ctl |= OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA;
 
-    eps[epnr].rx_active = TRUE;
+    ep->rx_active = TRUE;
 }
 
 static void read_packet(void *p, int len)
@@ -237,7 +238,7 @@ void hw_usb_deinit(void)
 int ep_rx_ready(uint8_t epnr)
 {
     struct ep *ep = &eps[epnr];
-    return (ep->rxc != ep->rxp) ? ep->rx[RX_MASK(ep->rxc)].count : -1;
+    return (ep->rxc != ep->rxp) ? ep->rx[RX_MASK(ep, rxc)].count : -1;
 }
 
 bool_t ep_tx_ready(uint8_t epnr)
@@ -248,7 +249,7 @@ bool_t ep_tx_ready(uint8_t epnr)
 void usb_read(uint8_t epnr, void *buf, uint32_t len)
 {
     struct ep *ep = &eps[epnr];
-    memcpy(buf, ep->rx[RX_MASK(ep->rxc++)].data, len);
+    memcpy(buf, ep->rx[RX_MASK(ep, rxc++)].data, len);
     if (!ep->rx_active && (ep->rxc == ep->rxp))
         prepare_rx(epnr);
 }
@@ -275,8 +276,12 @@ void usb_stall(uint8_t epnr)
 
 void usb_configure_ep(uint8_t epnr, uint8_t type, uint32_t size)
 {
+    int i;
+    struct ep *ep;
     bool_t in = !!(epnr & 0x80);
+
     epnr &= 0x7f;
+    ep = &eps[epnr];
 
     if (type == EPT_DBLBUF)
         type = EPT_BULK;
@@ -291,7 +296,7 @@ void usb_configure_ep(uint8_t epnr, uint8_t type, uint32_t size)
                 OTG_DIEPCTL_SD0PID |
                 OTG_DIEPCTL_USBAEP;
         }
-        eps[epnr].tx_ready = TRUE;
+        ep->tx_ready = TRUE;
     }
 
     if (!in) {
@@ -303,7 +308,20 @@ void usb_configure_ep(uint8_t epnr, uint8_t type, uint32_t size)
                 OTG_DIEPCTL_SD0PID |
                 OTG_DOEPCTL_USBAEP;
         }
-        eps[epnr].rxc = eps[epnr].rxp = 0;
+        ep->rxc = ep->rxp = 0;
+        if (epnr == 0) {
+            ep->rx = rx_buf0;
+            ep->rx_nr = ARRAY_SIZE(rx_buf0);
+        } else {
+            /* We have one statically-allocated multi-packet buffer. 
+             * Check we aren't trying to map it to multiple endpoints. */
+            ep->rx = NULL;
+            for (i = 0; i < conf_nr_ep; i++)
+                ASSERT(ep->rx != rx_bufn);
+            ep->rx = rx_bufn;
+            ep->rx_nr = ARRAY_SIZE(rx_bufn);
+        }
+        ep->rxc = ep->rxp = 0;
         prepare_rx(epnr);
     }
 }
@@ -371,8 +389,8 @@ static void handle_rx_transfer(void)
         bcnt = 8;
     case STS_DATA_UPDT:
         ASSERT(ep->rx_active);
-        ASSERT((uint16_t)(ep->rxp - ep->rxc) < RX_NR);
-        rxp = RX_MASK(ep->rxp++);
+        ASSERT((uint16_t)(ep->rxp - ep->rxc) < ep->rx_nr);
+        rxp = RX_MASK(ep, rxp++);
         read_packet(ep->rx[rxp].data, bcnt);
         ep->rx[rxp].count = bcnt;
         break;