Beispiel #1
0
//--------------------------------------------------------------
static void USBD_SetAddress(USB_OTG_CORE_HANDLE  *pdev, 
                            USB_SETUP_REQ *req)
{
  uint8_t  dev_addr; 
  
  if ((req->wIndex == 0) && (req->wLength == 0)) 
  {
    dev_addr = (uint8_t)(req->wValue) & 0x7F;     
    
    if (pdev->dev.device_status == USB_OTG_CONFIGURED) 
    {
      USBD_CtlError(pdev , req);
    } 
    else 
    {
      pdev->dev.device_address = dev_addr;
      DCD_EP_SetAddress(pdev, dev_addr);               
      USBD_CtlSendStatus(pdev);                         
      
      if (dev_addr != 0) 
      {
        pdev->dev.device_status  = USB_OTG_ADDRESSED;
      } 
      else 
      {
        pdev->dev.device_status  = USB_OTG_DEFAULT; 
      }
    }
  } 
  else 
  {
     USBD_CtlError(pdev , req);                        
  } 
}
Beispiel #2
0
/**
  * @brief  USBD_DataInStage 
  *         Handle data in stage
  * @param  pdev: device instance
  * @param  epnum: endpoint index
  * @retval status
  */
static uint8_t USBD_DataInStage(USB_CORE_HANDLE *pdev , uint8_t epnum)
{
  USB_EP *ep;
  
  if(epnum == 0) 
  {
    ep = &pdev->dev.in_ep[0];
    if ( pdev->dev.device_state == USB_EP0_DATA_IN)
    {
      if(ep->rem_data_len > ep->maxpacket)
      {
        ep->rem_data_len -=  ep->maxpacket;
        USBD_CtlContinueSendData (pdev, 
                                  ep->xfer_buff, 
                                  ep->rem_data_len);
      }
      else
      { /* last packet is MPS multiple, so send ZLP packet */
        if((ep->total_data_len % ep->maxpacket == 0) &&
           (ep->total_data_len >= ep->maxpacket) &&
             (ep->total_data_len < ep->ctl_data_len ))
        {
          
          USBD_CtlContinueSendData(pdev , NULL, 0);
          ep->ctl_data_len = 0;
        }
        else
        {
          if((pdev->dev.class_cb->EP0_TxSent != NULL)&&
             (pdev->dev.device_status == USB_CONFIGURED))
          {
            pdev->dev.class_cb->EP0_TxSent(pdev); 
          }          
          USBD_CtlReceiveStatus(pdev);
        }
      }
    }
    else  if ((pdev->dev.device_state == USB_EP0_STATUS_IN)&& (ADDRESS!=0))
    {
      
      DCD_EP_SetAddress(pdev, ADDRESS); 
      ADDRESS = 0;
    }
  }
  else if((pdev->dev.class_cb->DataIn != NULL)&& 
          (pdev->dev.device_status == USB_CONFIGURED))
  {
    pdev->dev.class_cb->DataIn(pdev, epnum); 
  }  
  return USBD_OK;
}
Beispiel #3
0
/**
* @brief  USBD_SetAddress
*         Set device address
* @param  pdev: device instance
* @param  req: usb request
* @retval status
*/
static void USBD_SetAddress(USB_OTG_CORE_HANDLE  *pdev,
                            USB_SETUP_REQ *req)
{
  uint8_t  dev_addr;

  if ((req->wIndex == 0) && (req->wLength == 0))
  {
    dev_addr = (uint8_t)(req->wValue) & 0x7F;

    if (pdev->dev.device_status == USB_OTG_CONFIGURED)
    {
      dbg_printf(DBGMODE_ERR, "USBD_SetAddress error, already configured device, file " __FILE__ ":%d\r\n", __LINE__);
      //USBD_CtlError(pdev , req);
    }
    //else
    {
      pdev->dev.device_address = dev_addr;
      DCD_EP_SetAddress(pdev, dev_addr);
      USBD_CtlSendStatus(pdev);

      if (dev_addr != 0)
      {
        pdev->dev.device_status  = USB_OTG_ADDRESSED;
      }
      else
      {
        //pdev->dev.device_status  = USB_OTG_DEFAULT;
      }
    }
  }
  else
  {
     dbg_printf(DBGMODE_ERR, "USBD_SetAddress Stall, bad wIndex 0x%04X or wLength 0x%04X, file " __FILE__ ":%d\r\n", req->wIndex, req->wLength, __LINE__);
     USBD_CtlError(pdev , req);
  }
}
Beispiel #4
0
/**
  * @brief ISTR events interrupt service routine
  * @param  None
  * @retval None
  */
void USB_Istr(void)
{
  __IO uint16_t wIstr = 0; 
  
  wIstr = _GetISTR();
  
#if (IMR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
  {
    /* servicing of the endpoint correct transfer interrupt */
    /* clear of the CTR flag into the sub */
    CTR();
  }
#endif  
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_RESET);
    USBD_DCD_INT_fops->Reset(&USB_Device_dev);
    DCD_EP_SetAddress(&USB_Device_dev, 0);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_DOVR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_ERR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_WKUP);
    
    USBD_DCD_INT_fops->Resume(&USB_Device_dev);
     
    /* Handle Resume state machine */  
    Resume(RESUME_EXTERNAL);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
  {
   /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    _SetISTR((uint16_t)CLR_SUSP);
    
    /* choose to enter system in low power mode or not in user suspend callback */
    USBD_DCD_INT_fops->Suspend(&USB_Device_dev); 
    
    Suspend();   
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_SOF);
    USBD_DCD_INT_fops->SOF(&USB_Device_dev);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    /* clear ESOF flag in ISTR */
    _SetISTR((uint16_t)CLR_ESOF);
    
    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request without change of the machine state */
  }
#endif
} /* USB_Istr */
/**
  * @brief ISTR events interrupt service routine
  * @param  None
  * @retval None
  */
void USB_Istr(void)
{
  __IO uint16_t wIstr = 0; 

  wIstr = _GetISTR();
  
#if (IMR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
  {
    /* servicing of the endpoint correct transfer interrupt */
    /* clear of the CTR flag into the sub */
    CTR();
  }
#endif  
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_RESET);
    USBD_DCD_INT_fops->Reset(&USB_Device_dev);
    DCD_EP_SetAddress(&USB_Device_dev, 0);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_DOVR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_ERR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_WKUP);
    
    USBD_DCD_INT_fops->Resume(&USB_Device_dev);
     
    /* Handle Resume state machine */  
    Resume(RESUME_EXTERNAL);

#ifdef LPM_ENABLED    
    /* clear L1 remote wakeup flag */
    L1_remote_wakeup = 0;
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
  {
   /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    _SetISTR((uint16_t)CLR_SUSP);
    
    /* process library core layer suspend routine*/
    USBD_DCD_INT_fops->Suspend(&USB_Device_dev); 
    
    /* enter macrocell in suspend and system in low power mode when 
       USB_DEVICE_LOW_PWR_MGMT_SUPPORT defined in usb_conf.h */
    Suspend();   
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_SOF);
    USBD_DCD_INT_fops->SOF(&USB_Device_dev);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    /* clear ESOF flag in ISTR */
    _SetISTR((uint16_t)CLR_ESOF);
    
    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request without change of the machine state */
  }
#endif


#ifdef LPM_ENABLED  
#if (IMR_MSK & ISTR_L1REQ)
  if (wIstr & ISTR_L1REQ & wInterrupt_Mask)
  {
     /* clear L1REQ flag in ISTR */
    _SetISTR((uint16_t)CLR_L1REQ);
    
    /* read BESL field which coressponds to HIRD parameter in LPM spec*/
    /* In your application depending on BESL value, you can choose the right 
    low power mode during L1 state, allowing wakeup time within the request time from host.*/
    BESL = (_GetLPMCSR()&LPMCSR_BESL) >>4 ;
    
    /* read REMWAKE bit which corresponding to bRemoteWake bit in LPM request*/
    /* if this bit is set then L1 remote wakeup is possible */
    L1_remote_wakeup = (_GetLPMCSR()&LPMCSR_REMWAKE) >>3;
    
    /* process library core layer suspend routine*/
    USBD_DCD_INT_fops->Suspend(&USB_Device_dev); 
    
    /* enter macrocell in suspend and system in low power mode (STOP mode) when 
    USB_DEVICE_LOW_PWR_MGMT_SUPPORT defined in usb_conf.h.*/   
    /* Please note that in this example we enter in STOP mode during L1 state independently
    from value read in BESL (even for BESL= 0 which corresponds to 50us delay) because
    STM32F072 can wakeup system from STOP mode in less than 50 us */
    Suspend();
  }