|  | @@ -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;
 |