/******************************************************************************* * Function Name : Mass_Storage_In * Description : Mass Storage IN transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Mass_Storage_In (void) { USB_STATUS_REG|=0X10;//标记轮询 switch (Bot_State) { case BOT_CSW_Send: case BOT_ERROR: Bot_State = BOT_IDLE; SetEPRxStatus(ENDP2, EP_RX_VALID);/* enable the Endpoint to receive the next cmd*/ if (GetEPRxStatus(EP2_OUT) == EP_RX_STALL) { SetEPRxStatus(EP2_OUT, EP_RX_VALID);/* enable the Endpoint to receive the next cmd*/ } break; case BOT_DATA_IN: switch (CBW.CB[0]) { case SCSI_READ10: USB_STATUS_REG|=0X02;//标记正在读数据 SCSI_Read10_Cmd(CBW.bLUN , SCSI_LBA , SCSI_BlkLen); break; } break; case BOT_DATA_IN_LAST: Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE); SetEPRxStatus(ENDP2, EP_RX_VALID); break; default: break; } }
/******************************************************************************* * Function Name : Standard_SetEndPointFeature * Description : Set or enable a specific feature of EndPoint * Input : None. * Output : None. * Return : - Return USB_SUCCESS, if the request is performed. * - Return USB_UNSUPPORT, if the request is invalid. *******************************************************************************/ RESULT Standard_SetEndPointFeature(void) { uint32_t wIndex0 = pInformation->USBwIndex0; uint32_t rEP = wIndex0 & ~0x80; uint32_t Related_Endpoint = ENDP0 + rEP; uint32_t Status; 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 || pInformation->USBwValue != 0 || Status == 0 || pInformation->Current_Configuration == 0) { return USB_UNSUPPORT; } else { if (wIndex0 & 0x80) { // IN endpoint SetEPTxStatus(Related_Endpoint, EP_TX_STALL); } else { // OUT endpoint SetEPRxStatus(Related_Endpoint, EP_RX_STALL); } } pUser_Standard_Requests->User_SetEndPointFeature(); return USB_SUCCESS; }
uint32_t DCD_GetEPStatus(USB_CORE_HANDLE *pdev ,uint8_t epnum) { uint16_t Status=0; USB_EP *ep; if ((0x80 & epnum) == 0x80) { ep = &pdev->dev.in_ep[epnum & 0x7F]; } else { ep = &pdev->dev.out_ep[epnum]; } if (ep->is_in) { Status = GetEPTxStatus(ep->num); } else { Status = GetEPRxStatus(ep->num); } return Status; }
/******************************************************************************* * Function Name : Standard_ClearFeature. * Description : Clear or disable a specific feature. * Input : None. * Output : None. * Return : - Return USB_SUCCESS, if the request is performed. * - Return USB_UNSUPPORT, if the request is invalid. *******************************************************************************/ RESULT Standard_ClearFeature(void) { uint32_t Type_Rec = Type_Recipient; uint32_t Status; if (Type_Rec == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { // Device Clear Feature ClrBit(pInformation->Current_Feature, 5); return USB_SUCCESS; } else if (Type_Rec == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) { // EndPoint Clear Feature DEVICE* pDev; uint32_t Related_Endpoint; uint32_t wIndex0; uint32_t rEP; if ((pInformation->USBwValue != ENDPOINT_STALL) || (pInformation->USBwIndex1 != 0)) { return USB_UNSUPPORT; } pDev = &Device_Table; wIndex0 = pInformation->USBwIndex0; rEP = wIndex0 & ~0x80; Related_Endpoint = ENDP0 + rEP; 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 ((rEP >= pDev->Total_Endpoint) || (Status == 0) || (pInformation->Current_Configuration == 0)) { return USB_UNSUPPORT; } if (wIndex0 & 0x80) { // IN endpoint if (GetTxStallStatus(Related_Endpoint )) { ClearDTOG_TX(Related_Endpoint); SetEPTxStatus(Related_Endpoint, EP_TX_VALID); } } else { // OUT endpoint if (GetRxStallStatus(Related_Endpoint)) { if (Related_Endpoint == ENDP0) { // After clear the STALL, enable the default endpoint receiver SetEPRxCount(Related_Endpoint, Device_Property.MaxPacketSize); SetEPRxStatus(Related_Endpoint, EP_RX_VALID); } else { ClearDTOG_RX(Related_Endpoint); SetEPRxStatus(Related_Endpoint, EP_RX_VALID); } } } pUser_Standard_Requests->User_ClearFeature(); return USB_SUCCESS; } return USB_UNSUPPORT; }
/******************************************************************************* * Function Name : Mass_Storage_In * Description : Mass Storage IN transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Mass_Storage_In (void) { switch (Bot_State) { case BOT_CSW_Send: case BOT_ERROR: Bot_State = BOT_IDLE; #ifndef STM32F10X_CL SetEPRxStatus(ENDP2, EP_RX_VALID);/* enable the Endpoint to receive the next cmd*/ #else if (GetEPRxStatus(EP2_OUT) == EP_RX_STALL) { SetEPRxStatus(EP2_OUT, EP_RX_VALID);/* enable the Endpoint to receive the next cmd*/ } #endif /* STM32F10X_CL */ break; case BOT_DATA_IN: switch (CBW.CB[0]) { case SCSI_READ10: //DBG("SCSI_READ10\n"); SCSI_Read10_Cmd(CBW.bLUN , SCSI_LBA , SCSI_BlkLen); break; } break; case BOT_DATA_IN_LAST: Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE); #ifndef STM32F10X_CL SetEPRxStatus(ENDP2, EP_RX_VALID); #else if (GetEPRxStatus(EP2_OUT) == EP_RX_STALL) { SetEPRxStatus(EP2_OUT, EP_RX_VALID);/* enable the Endpoint to receive the next cmd*/ } #endif /* STM32F10X_CL */ break; default: break; } }
bool stm32_usbd_ep_is_OUT_stall(uint8_t idx) { int8_t index; index = stm32_usbd_ep(idx); if (index < 0) { return false; } idx = (uint8_t)index; return (EP_RX_STALL == GetEPRxStatus(idx)); }
static void PIOS_USB_CDC_RxStart(uintptr_t usbcdc_id, uint16_t rx_bytes_avail) { struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)usbcdc_id; bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); PIOS_Assert(valid); if (!PIOS_USB_CheckAvailable(usb_cdc_dev->lower_id)) { return; } // If endpoint was stalled and there is now space make it valid PIOS_IRQ_Disable(); if ((GetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep) != EP_RX_VALID) && (rx_bytes_avail >= sizeof(usb_cdc_dev->rx_packet_buffer))) { SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID); } PIOS_IRQ_Enable(); }
static void PIOS_USB_HID_RxStart(uint32_t usbhid_id, uint16_t rx_bytes_avail) { struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)usbhid_id; bool valid = PIOS_USB_HID_validate(usb_hid_dev); PIOS_Assert(valid); if (!PIOS_USB_CheckAvailable(usb_hid_dev->lower_id)) { return; } // If endpoint was stalled and there is now space make it valid #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1; #else uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2; #endif PIOS_IRQ_Disable(); if ((GetEPRxStatus(usb_hid_dev->cfg->data_rx_ep) != EP_RX_VALID) && (rx_bytes_avail >= max_payload_length)) { SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID); } PIOS_IRQ_Enable(); }
/******************************************************************************* * 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; }
/******************************************************************************* * Function Name : GetRxStallStatus * Description : Returns the Stall status of the Rx endpoint. * Input : bEpNum: Endpoint Number. * Output : None. * Return : Rx Stall status. *******************************************************************************/ uint16_t GetRxStallStatus(uint8_t bEpNum) { return GetEPRxStatus(bEpNum) == EP_RX_STALL; }