Пример #1
0
/*******************************************************************************
* 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);
}
Пример #2
0
/*******************************************************************************
* 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();
		}
	}
}
Пример #3
0
/*******************************************************************************
* 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);
}
Пример #4
0
/*******************************************************************************
* 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();
    }
  }
}
Пример #5
0
/*******************************************************************************
* 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;
}