/******************************************************************************* * Function Name : Post0_Process * Description : Stall the Endpoint 0 in case of error. * Input : None. * Output : None. * Return : - 0 if the control State is in PAUSE * - 1 if not. *******************************************************************************/ uint8_t Post0_Process(void) { #ifdef STM32F10X_CL USB_OTG_EP* ep; #endif /* STM32F10X_CL */ SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); if(pInformation->ControlState == STALLED) { vSetEPRxStatus(EP_RX_STALL); vSetEPTxStatus(EP_TX_STALL); } #ifdef STM32F10X_CL else if((pInformation->ControlState == OUT_DATA) || (pInformation->ControlState == WAIT_STATUS_OUT)) { ep = PCD_GetInEP(0); ep->is_in = 0; OTGD_FS_EP0StartXfer(ep); vSetEPTxStatus(EP_TX_VALID); } else if((pInformation->ControlState == IN_DATA) || (pInformation->ControlState == WAIT_STATUS_IN)) { ep = PCD_GetInEP(0); ep->is_in = 1; OTGD_FS_EP0StartXfer(ep); } #endif /* STM32F10X_CL */ return (pInformation->ControlState == PAUSE); }
/******************************************************************************* * 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 : Post0_Process * Description : Stall the Endpoint 0 in case of error. * Input : None. * Output : None. * Return : - 0 if the control State is in PAUSE * - 1 if not. *******************************************************************************/ uint8_t Post0_Process(void) { SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); if (pInformation->ControlState == STALLED) { vSetEPRxStatus(EP_RX_STALL); vSetEPTxStatus(EP_TX_STALL); } return (pInformation->ControlState == PAUSE); }
/******************************************************************************* * 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 : Data_Setup0. * Description : Proceed the processing of setup request with data stage. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Data_Setup0(void) { uint8_t* (*CopyRoutine)(uint16_t); RESULT Result; uint32_t Request_No = pInformation->USBbRequest; uint32_t Related_Endpoint, Reserved; uint32_t wOffset, Status; CopyRoutine = NULL; wOffset = 0; /*GET DESCRIPTOR*/ if(Request_No == GET_DESCRIPTOR) { if(Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { uint8_t wValue1 = pInformation->USBwValue1; if(wValue1 == DEVICE_DESCRIPTOR) { CopyRoutine = pProperty->GetDeviceDescriptor; } else if(wValue1 == CONFIG_DESCRIPTOR) { CopyRoutine = pProperty->GetConfigDescriptor; } else if(wValue1 == STRING_DESCRIPTOR) { CopyRoutine = pProperty->GetStringDescriptor; } /* End of GET_DESCRIPTOR */ } } /*GET STATUS*/ else if((Request_No == GET_STATUS) && (pInformation->USBwValue == 0) && (pInformation->USBwLength == 0x0002) && (pInformation->USBwIndex1 == 0)) { /* GET STATUS for Device*/ if((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) && (pInformation->USBwIndex == 0)) { CopyRoutine = Standard_GetStatus; } /* GET STATUS for Interface*/ else if(Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) { if(((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS) && (pInformation->Current_Configuration != 0)) { CopyRoutine = Standard_GetStatus; } } /* GET STATUS for EndPoint*/ else if(Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) { Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); Reserved = pInformation->USBwIndex0 & 0x70; if(ValBit(pInformation->USBwIndex0, 7)) { /*Get Status of endpoint & stall the request if the related_ENdpoint is Disabled*/ Status = _GetEPTxStatus(Related_Endpoint); } else { Status = _GetEPRxStatus(Related_Endpoint); } if((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0) && (Status != 0)) { CopyRoutine = Standard_GetStatus; } } } /*GET CONFIGURATION*/ else if(Request_No == GET_CONFIGURATION) { if(Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { CopyRoutine = Standard_GetConfiguration; } } /*GET INTERFACE*/ else if(Request_No == GET_INTERFACE) { if((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0) && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001) && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)) { CopyRoutine = Standard_GetInterface; } } if(CopyRoutine) { pInformation->Ctrl_Info.Usb_wOffset = wOffset; pInformation->Ctrl_Info.CopyData = CopyRoutine; /* sb in the original the cast to word was directly */ /* now the cast is made step by step */ (*CopyRoutine)(0); Result = USB_SUCCESS; } else { Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest); if(Result == USB_NOT_READY) { pInformation->ControlState = PAUSE; return; } } if(pInformation->Ctrl_Info.Usb_wLength == 0xFFFF) { /* Data is not ready, wait it */ pInformation->ControlState = PAUSE; return; } if((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0)) { /* Unsupported request */ pInformation->ControlState = STALLED; return; } if(ValBit(pInformation->USBbmRequestType, 7)) { /* Device ==> Host */ __IO uint32_t wLength = pInformation->USBwLength; /* Restrict the data length to be the one host asks for */ if(pInformation->Ctrl_Info.Usb_wLength > wLength) { pInformation->Ctrl_Info.Usb_wLength = wLength; } else if(pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength) { if(pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize) { Data_Mul_MaxPacketSize = FALSE; } else if((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0) { Data_Mul_MaxPacketSize = TRUE; } } pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize; DataStageIn(); } else { pInformation->ControlState = OUT_DATA; vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */ } return; }