Example #1
0
/*******************************************************************************
* 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;
    uint32_t Related_Endpoint;
    uint32_t rEP;
    uint32_t Status;

    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(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;
}
Example #2
0
/*******************************************************************************
* Function Name  : CTR_LP.
* Description    : Low priority Endpoint Correct Transfer interrupt's service
*                  routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CTR_LP(void)
{
  u32 wEPVal = 0;
  /* stay in loop while pending ints */
  while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
  {
    _SetISTR((u16)CLR_CTR); /* clear CTR flag */
    /* extract highest priority endpoint number */
    EPindex = (u8)(wIstr & ISTR_EP_ID);
    if (EPindex == 0)
    {
      /* Decode and service control endpoint interrupt */
      /* calling related service routine */
      /* (Setup0_Process, In0_Process, Out0_Process) */

      /* save RX & TX status */
      /* and set both to NAK */
      SaveRState = _GetEPRxStatus(ENDP0);
      SaveTState = _GetEPTxStatus(ENDP0);
      _SetEPRxStatus(ENDP0, EP_RX_NAK);
      _SetEPTxStatus(ENDP0, EP_TX_NAK);


      /* DIR bit = origin of the interrupt */

      if ((wIstr & ISTR_DIR) == 0)
      {
        /* DIR = 0 */

        /* DIR = 0      => IN  int */
        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */


        _ClearEP_CTR_TX(ENDP0);
        In0_Process();

           /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);
          _SetEPTxStatus(ENDP0, SaveTState);
          return;
      }
      else
      {
        /* DIR = 1 */

        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */

        wEPVal = _GetENDPOINT(ENDP0);
        if ((wEPVal & EP_CTR_TX) != 0)
        {
          _ClearEP_CTR_TX(ENDP0);
          In0_Process();
          /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);
          _SetEPTxStatus(ENDP0, SaveTState);
          return;
        }
        else if ((wEPVal &EP_SETUP) != 0)
        {
          _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
          Setup0_Process();
          /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);
          _SetEPTxStatus(ENDP0, SaveTState);
          return;
        }

        else if ((wEPVal & EP_CTR_RX) != 0)
        {
          _ClearEP_CTR_RX(ENDP0);
          Out0_Process();
          /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);
          _SetEPTxStatus(ENDP0, SaveTState);
          return;
        }
      }
    }/* if(EPindex == 0) */
    else
    {
      /* Decode and service non control endpoints interrupt  */

      /* process related endpoint register */
      wEPVal = _GetENDPOINT(EPindex);
      if ((wEPVal & EP_CTR_RX) != 0)
      {
        /* clear int flag */
        _ClearEP_CTR_RX(EPindex);

        /* call OUT service function */
        (*pEpInt_OUT[EPindex-1])();

      } /* if((wEPVal & EP_CTR_RX) */

      if ((wEPVal & EP_CTR_TX) != 0)
      {
        /* clear int flag */
        _ClearEP_CTR_TX(EPindex);

        /* call IN service function */
        (*pEpInt_IN[EPindex-1])();
      } /* if((wEPVal & EP_CTR_TX) != 0) */

    }/* if(EPindex == 0) else */

  }/* while(...) */
}
Example #3
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;
}
Example #4
0
/*******************************************************************************
* 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)) {
#ifndef STM32F10X_CL
                ClearDTOG_TX(Related_Endpoint);
#endif /* STM32F10X_CL */
                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 {
#ifndef STM32F10X_CL
                    ClearDTOG_RX(Related_Endpoint);
#endif /* STM32F10X_CL */
                    _SetEPRxStatus(Related_Endpoint, EP_RX_VALID);
                }
            }
        }
        pUser_Standard_Requests->User_ClearFeature();
        return USB_SUCCESS;
    }

    return USB_UNSUPPORT;
}
Example #5
0
/*******************************************************************************
* Function Name  : CTR_LP.
* Description    : Low priority Endpoint Correct Transfer interrupt's service
*                  routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CTR_LP(void)
{
  u32 wEPVal = 0;
//  wIstr = *ISTR;
  /* stay in loop while pending ints */
  while (((wIstr = (*ISTR)) & ISTR_CTR) != 0)	//正确传输
  {
    _SetISTR((u16)CLR_CTR); /* clear CTR flag 清正确传输中断*/
    /* extract highest priority endpoint number */
    EPindex = (u8)(wIstr & ISTR_EP_ID);//ISTR_EP_ID  (0x000F)  这个只读,所以与0X000F&
    if (EPindex == 0)					 //如果是端点0
    {
      /* Decode and service control endpoint interrupt */
      /* calling related service routine */
      /* (Setup0_Process, In0_Process, Out0_Process) */

      /* save RX & TX status */
      /* and set both to NAK */
      SaveRState = _GetEPRxStatus(ENDP0);
      SaveTState = _GetEPTxStatus(ENDP0);
      _SetEPRxStatus(ENDP0, EP_RX_NAK);	 //当一次正确的OUT或SETUP数据传输完成后(CTR_RX=1),
	  _SetEPTxStatus(ENDP0, EP_TX_NAK);	//硬件会自动设置此位为NAK状态,
									   	//使应用程序有足够的时间在处理完当前传输的数据后,
									  	 //响应下一个数据分组。
      /* DIR bit = origin of the interrupt */

      if ((wIstr & ISTR_DIR) == 0)	  //0x0010 如果是输入
      {
        /* DIR = 0 */

        /* DIR = 0      => IN  int */
        /* DIR = 0 implies that (EP_CTR_TX = 1) always  */


        _ClearEP_CTR_TX(ENDP0);
        In0_Process();

           /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);
          _SetEPTxStatus(ENDP0, SaveTState);
          return;
      }
      else						 //输出
      {
        /* DIR = 1 */

        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
		 //EP0的值
        wEPVal =(u16)(*((volatile unsigned *)(0x40005C00L) + ENDP0));
        if ((wEPVal & EP_CTR_TX) != 0)		//硬件在一个正确的IN分组传输完成后置位
        {
          _ClearEP_CTR_TX(ENDP0);
          In0_Process();
          /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);	  //SaveTState=EP_TX_STALL;	   在In0_Process()
          _SetEPTxStatus(ENDP0, SaveTState);	  //SaveTState=EP_TX_STALL;	   在In0_Process()
          return;
        }
		//控制传输由3个阶段组成,首先是主机发送SETUP分组的SETUP阶段,
		//然后是主机发送零个或多个数据的数据阶段,最后是状态阶段,由与数据阶段方向相反的数据分组构成
		//据SETUP分组的相应字段决定后面的传输是IN还是OUT。
        else if ((wEPVal &EP_SETUP) != 0)  //在USB模块收到一个正确的SETUP分组后由硬件置位
        {
          _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
          Setup0_Process();
          /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);
          _SetEPTxStatus(ENDP0, SaveTState);
          return;
        }

        else if ((wEPVal & EP_CTR_RX) != 0)
        {
          _ClearEP_CTR_RX(ENDP0);
          Out0_Process();
          /* before terminate set Tx & Rx status */
          _SetEPRxStatus(ENDP0, SaveRState);
          _SetEPTxStatus(ENDP0, SaveTState);
          return;
        }
      }
    }/* if(EPindex == 0) */
    else
    {
      /* Decode and service non control endpoints interrupt  */

      /* process related endpoint register */
      wEPVal = (u16)(*((volatile unsigned *)(0x40005C00L) + EPindex));
      if ((wEPVal & EP_CTR_RX) != 0)
      {
        /* clear int flag */
        _ClearEP_CTR_RX(EPindex);

        /* call OUT service function */
        (*pEpInt_OUT[EPindex-1])();

      } /* if((wEPVal & EP_CTR_RX) */

      if ((wEPVal & EP_CTR_TX) != 0)
      {
        /* clear int flag */
        _ClearEP_CTR_TX(EPindex);

        /* call IN service function */
//        (*pEpInt_IN[EPindex-1])();
      } /* if((wEPVal & EP_CTR_TX) != 0) */

    }/* if(EPindex == 0) else */

  }/* while(...) */
}