/******************************************************************************* * Function Name : DataStageOut. * Description : Data stage of a Control Write Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageOut(void) { ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; uint32_t save_rLength; save_rLength = pEPinfo->Usb_rLength; if (pEPinfo->CopyData && save_rLength) { uint8_t *Buffer; uint32_t Length; Length = pEPinfo->PacketSize; if (Length > save_rLength) Length = save_rLength; Buffer = (*pEPinfo->CopyData)(Length); pEPinfo->Usb_rLength -= Length; pEPinfo->Usb_rOffset += Length; PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); } if (pEPinfo->Usb_rLength != 0) { vSetEPRxStatus(EP_RX_VALID); // re-enable for next data reception SetEPTxCount(ENDP0, 0); vSetEPTxStatus(EP_TX_VALID); // Expect the host to abort the data OUT stage } // Set the next State if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) { pInformation->ControlState = OUT_DATA; } else { if (pEPinfo->Usb_rLength > 0) { pInformation->ControlState = LAST_OUT_DATA; } else if (pEPinfo->Usb_rLength == 0) { pInformation->ControlState = WAIT_STATUS_IN; USB_StatusIn(); } } }
/******************************************************************************* * Function Name : DataStageOut. * Description : Data stage of a Control Write Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageOut(void) { ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; uint32_t save_rLength; save_rLength = pEPinfo->Usb_rLength; if (pEPinfo->CopyDataOut && save_rLength) { uint8_t *Buffer; uint32_t Length; Length = pEPinfo->PacketSize; if (Length > save_rLength) { Length = save_rLength; } Buffer = (*pEPinfo->CopyDataOut)(Length); pEPinfo->Usb_rLength -= Length; pEPinfo->Usb_rOffset += Length; #ifdef STM32F10X_CL PCD_EP_Read(ENDP0, Buffer, Length); #else PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); #endif /* STM32F10X_CL */ } if (pEPinfo->Usb_rLength != 0) { vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ SetEPTxCount(ENDP0, 0); vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ } /* Set the next State*/ if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) { pInformation->ControlState = OUT_DATA; } else { if (pEPinfo->Usb_rLength > 0) { pInformation->ControlState = LAST_OUT_DATA; } else if (pEPinfo->Usb_rLength == 0) { pInformation->ControlState = WAIT_STATUS_IN; USB_StatusIn(); } } }
/******************************************************************************* * Function Name : NoData_Setup0. * Description : Proceed the processing of setup request without data stage. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void NoData_Setup0(void) { RESULT Result = USB_UNSUPPORT; uint32_t RequestNo = pInformation->USBbRequest; uint32_t ControlState; if(Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { /* Device Request*/ /* SET_CONFIGURATION*/ if(RequestNo == SET_CONFIGURATION) { Result = Standard_SetConfiguration(); } /*SET ADDRESS*/ else if(RequestNo == SET_ADDRESS) { if((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) || (pInformation->USBwIndex != 0) || (pInformation->Current_Configuration != 0)) /* Device Address should be 127 or less*/ { ControlState = STALLED; goto exit_NoData_Setup0; } else { Result = USB_SUCCESS; #ifdef STM32F10X_CL SetDeviceAddress(pInformation->USBwValue0); #endif /* STM32F10X_CL */ } } /*SET FEATURE for Device*/ else if(RequestNo == SET_FEATURE) { if((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) && (pInformation->USBwIndex == 0)) { Result = Standard_SetDeviceFeature(); } else { Result = USB_UNSUPPORT; } } /*Clear FEATURE for Device */ else if(RequestNo == CLEAR_FEATURE) { if(pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP && pInformation->USBwIndex == 0 && ValBit(pInformation->Current_Feature, 5)) { Result = Standard_ClearFeature(); } else { Result = USB_UNSUPPORT; } } } /* Interface Request*/ else if(Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) { /*SET INTERFACE*/ if(RequestNo == SET_INTERFACE) { Result = Standard_SetInterface(); } } /* EndPoint Request*/ else if(Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) { /*CLEAR FEATURE for EndPoint*/ if(RequestNo == CLEAR_FEATURE) { Result = Standard_ClearFeature(); } /* SET FEATURE for EndPoint*/ else if(RequestNo == SET_FEATURE) { Result = Standard_SetEndPointFeature(); } } else { Result = USB_UNSUPPORT; } if(Result != USB_SUCCESS) { Result = (*pProperty->Class_NoData_Setup)(RequestNo); if(Result == USB_NOT_READY) { ControlState = PAUSE; goto exit_NoData_Setup0; } } if(Result != USB_SUCCESS) { ControlState = STALLED; goto exit_NoData_Setup0; } ControlState = WAIT_STATUS_IN; /* After no data stage SETUP */ USB_StatusIn(); exit_NoData_Setup0: pInformation->ControlState = ControlState; return; }