//-------------------------------------------------------------- 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); } }
/** * @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; }
/** * @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); } }
/** * @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(); }