Fix stall handling
This commit is contained in:
		@@ -121,7 +121,7 @@ static void prepare_next_setup_packet(uint8_t rhport)
 | 
			
		||||
  const unsigned out_odd = _dcd.endpoint[0][0].odd;
 | 
			
		||||
  const unsigned in_odd  = _dcd.endpoint[0][1].odd;
 | 
			
		||||
  if (_dcd.bdt[0][0][out_odd].own) {
 | 
			
		||||
    TU_LOG1("DCD fail to prepare the next SETUP %d %d\r\n", out_odd, in_odd);
 | 
			
		||||
    //    TU_LOG1("DCD fail to prepare the next SETUP %d %d\r\n", out_odd, in_odd);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  _dcd.bdt[0][0][out_odd].data     = 0;
 | 
			
		||||
@@ -163,9 +163,6 @@ static void process_tokdne(uint8_t rhport)
 | 
			
		||||
    KHCI->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (s >> 4) {
 | 
			
		||||
    TU_LOG1("TKDNE %x\r\n", s);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const unsigned bc = bd->bc;
 | 
			
		||||
  const unsigned remaining = ep->remaining - bc;
 | 
			
		||||
@@ -321,8 +318,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
 | 
			
		||||
  const unsigned ep_addr  = ep_desc->bEndpointAddress;
 | 
			
		||||
  const unsigned epn      = ep_addr & 0xFu;
 | 
			
		||||
  const unsigned dir      = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
 | 
			
		||||
  const unsigned epn      = tu_edpt_number(ep_addr);
 | 
			
		||||
  const unsigned dir      = tu_edpt_dir(ep_addr);
 | 
			
		||||
  const unsigned xfer     = ep_desc->bmAttributes.xfer;
 | 
			
		||||
  endpoint_state_t *ep    = &_dcd.endpoint[epn][dir];
 | 
			
		||||
  const unsigned odd      = ep->odd;
 | 
			
		||||
@@ -373,8 +370,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
 | 
			
		||||
{
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
 | 
			
		||||
  const unsigned epn      = ep_addr & 0xFu;
 | 
			
		||||
  const unsigned dir      = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
 | 
			
		||||
  const unsigned epn      = tu_edpt_number(ep_addr);
 | 
			
		||||
  const unsigned dir      = tu_edpt_dir(ep_addr);
 | 
			
		||||
  endpoint_state_t *ep    = &_dcd.endpoint[epn][dir];
 | 
			
		||||
  buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0];
 | 
			
		||||
  const unsigned msk      = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
 | 
			
		||||
@@ -388,18 +385,15 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
 | 
			
		||||
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
 | 
			
		||||
{
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
  const unsigned ie  = NVIC_GetEnableIRQ(USB0_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USB0_IRQn);
 | 
			
		||||
  const unsigned epn = ep_addr & 0xFu;
 | 
			
		||||
  const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
 | 
			
		||||
  const unsigned epn      = tu_edpt_number(ep_addr);
 | 
			
		||||
  const unsigned dir      = tu_edpt_dir(ep_addr);
 | 
			
		||||
  endpoint_state_t    *ep = &_dcd.endpoint[epn][dir];
 | 
			
		||||
  buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd];
 | 
			
		||||
  TU_ASSERT(0 == bd->own);
 | 
			
		||||
 | 
			
		||||
  const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USB0_IRQn);
 | 
			
		||||
 | 
			
		||||
  if (bd->own) {
 | 
			
		||||
    TU_LOG1("DCD XFER fail %x %d %lx %lx\r\n", ep_addr, total_bytes, ep->state, bd->head);
 | 
			
		||||
    if (ie) NVIC_EnableIRQ(USB0_IRQn);
 | 
			
		||||
    return false; /* The last transfer has not completed */
 | 
			
		||||
  }
 | 
			
		||||
  ep->length    = total_bytes;
 | 
			
		||||
  ep->remaining = total_bytes;
 | 
			
		||||
 | 
			
		||||
@@ -412,10 +406,10 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
 | 
			
		||||
    next->addr = buffer + mps;
 | 
			
		||||
    next->own  = 1;
 | 
			
		||||
  }
 | 
			
		||||
  bd->bc        = total_bytes >= mps ? mps: total_bytes;
 | 
			
		||||
  bd->addr      = buffer;
 | 
			
		||||
  bd->bc   = total_bytes >= mps ? mps: total_bytes;
 | 
			
		||||
  bd->addr = buffer;
 | 
			
		||||
  __DSB();
 | 
			
		||||
  bd->own  = 1; /* the own bit must set after addr */
 | 
			
		||||
  bd->own  = 1; /* This bit must be set last */
 | 
			
		||||
  if (ie) NVIC_EnableIRQ(USB0_IRQn);
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
@@ -423,31 +417,38 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
 | 
			
		||||
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
 | 
			
		||||
{
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
  const unsigned epn = ep_addr & 0xFu;
 | 
			
		||||
  const unsigned epn = tu_edpt_number(ep_addr);
 | 
			
		||||
  if (0 == epn) {
 | 
			
		||||
    KHCI->ENDPOINT[epn].ENDPT |=  USB_ENDPT_EPSTALL_MASK;
 | 
			
		||||
  } else {
 | 
			
		||||
    const unsigned dir      = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
 | 
			
		||||
    buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
 | 
			
		||||
    bd[0].bdt_stall = 1;
 | 
			
		||||
    bd[1].bdt_stall = 1;
 | 
			
		||||
    const unsigned dir      = tu_edpt_dir(ep_addr);
 | 
			
		||||
    endpoint_state_t    *ep = &_dcd.endpoint[epn][dir];
 | 
			
		||||
    buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd];
 | 
			
		||||
    TU_ASSERT(0 == bd->own,);
 | 
			
		||||
    const unsigned ie       = NVIC_GetEnableIRQ(USB0_IRQn);
 | 
			
		||||
    NVIC_DisableIRQ(USB0_IRQn);
 | 
			
		||||
    bd->bdt_stall = 1;
 | 
			
		||||
    __DSB();
 | 
			
		||||
    bd->own       = 1; /* This bit must be set last */
 | 
			
		||||
    if (ie) NVIC_EnableIRQ(USB0_IRQn);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
 | 
			
		||||
{
 | 
			
		||||
  (void) rhport;
 | 
			
		||||
  const unsigned epn      = ep_addr & 0xFu;
 | 
			
		||||
  const unsigned dir      = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
 | 
			
		||||
  const unsigned odd      = _dcd.endpoint[epn][dir].odd;
 | 
			
		||||
  buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
 | 
			
		||||
 | 
			
		||||
  bd[odd ^ 1].own       = 0;
 | 
			
		||||
  bd[odd ^ 1].data      = 1;
 | 
			
		||||
  bd[odd ^ 1].bdt_stall = 0;
 | 
			
		||||
  bd[odd].own           = 0;
 | 
			
		||||
  bd[odd].data          = 0;
 | 
			
		||||
  bd[odd].bdt_stall     = 0;
 | 
			
		||||
  const unsigned epn      = tu_edpt_number(ep_addr);
 | 
			
		||||
  TU_VERIFY(epn,);
 | 
			
		||||
  const unsigned dir      = tu_edpt_dir(ep_addr);
 | 
			
		||||
  endpoint_state_t    *ep = &_dcd.endpoint[epn][dir];
 | 
			
		||||
  buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd];
 | 
			
		||||
  TU_ASSERT(bd->own,);
 | 
			
		||||
  const unsigned ie       = NVIC_GetEnableIRQ(USB0_IRQn);
 | 
			
		||||
  NVIC_DisableIRQ(USB0_IRQn);
 | 
			
		||||
  bd->own       = 0;
 | 
			
		||||
  __DSB();
 | 
			
		||||
  bd->bdt_stall = 0;
 | 
			
		||||
  if (ie) NVIC_EnableIRQ(USB0_IRQn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//--------------------------------------------------------------------+
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user