Exemplo n.º 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;
}
Exemplo n.º 2
0
/*******************************************************************************
* Function Name  : CustomHID_Reset.
* Description    : Custom HID reset routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CustomHID_Reset(void)
{
  /* Set Joystick_DEVICE as not configured */
  pInformation->Current_Configuration = 0;
  pInformation->Current_Interface = 0;/*the default Interface*/
  
  /* Current Feature initialization */
  pInformation->Current_Feature = CustomHID_ConfigDescriptor[7];
  
  *(volatile unsigned *)(0x40005C50L)=(0x00&0xFFF8);//设置USB分组缓冲区描述表起始地址:0

  /* Initialize Endpoint 0 */
  //设置EP0控制端点	 ENDP0   ((u8)0)   EP_CONTROL     (0x0200)
  *(((volatile unsigned *)(0x40005C00L)) + ENDP0)=((_GetENDPOINT(ENDP0) & 0x898f) | EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);	  //设置EP0端点发送延迟
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);		  //设置EP0的接受地址  ENDP0_RXADDR        (0x18)
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);		  //设置EP0的发送地址  ENDP0_TXADDR        (0x58)
  _ClearEP_KIND(ENDP0);					  //设置端点EP0的类型DBL_BUF 双缓冲端点
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);	//设置EP0的计数器的值
  _SetEPRxStatus(ENDP0, EP_RX_VALID);					  //设置端点接受有效 EP_RX_VALID=0x3000

  /* Initialize Endpoint 1 */
     SetEPType(ENDP1, EP_INTERRUPT);
     SetEPRxAddr(ENDP1, ENDP1_RXADDR);	//ADDR内部寄存器被用作当前缓冲区的指针 ENDP1_RXADDR=(0x98)
     SetEPRxCount(ENDP1, 22);			//COUNT寄存器用于记录剩下未传输的字节数
     SetEPRxStatus(ENDP1, EP_RX_VALID);	//设置端点接受有效 EP_RX_VALID=0x3000

  /* Initialize Endpoint 2 */
     SetEPType(ENDP2, EP_INTERRUPT);
     SetEPTxAddr(ENDP2, ENDP2_TXADDR);
     SetEPTxCount(ENDP2, 22);
     SetEPTxStatus(ENDP2, EP_TX_NAK);//设置端点发送不应答 EP_TX_NAK=(0x0020)

  bDeviceState = ATTACHED;	//ATTACHED=1
  
  /* Set this device to response on default address */
  SetDeviceAddress(0);
}
Exemplo n.º 3
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(...) */
}
Exemplo n.º 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;
}
Exemplo n.º 5
0
/**
  * @brief  Correct Transfer interrupt's service
  * @param  None
  * @retval None
  */
void CTR(void)
{
  USB_EP *ep;
  uint16_t count=0;
  uint8_t EPindex;
  __IO uint16_t wIstr;  
  __IO uint16_t wEPVal = 0;
  /* stay in loop while pending interrupts */
  while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
  {
    /* extract highest priority endpoint number */
    EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
    
    if (EPindex == 0)
    {
      /* Decode and service control endpoint interrupt */
      
      /* 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);
        ep = &((&USB_Device_dev)->dev.in_ep[0]);
        
        ep->xfer_count = GetEPTxCount(ep->num);
        ep->xfer_buff += ep->xfer_count;
 
        /* TX COMPLETE */
        USBD_DCD_INT_fops->DataInStage(&USB_Device_dev, 0x00);
      }
      else
      {
        /* DIR = 1 */
        
        /* DIR = 1 & CTR_RX       => SETUP or OUT int */
        /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
        ep = &((&USB_Device_dev)->dev.out_ep[0]);
        wEPVal = _GetENDPOINT(ENDP0);
        
        if ((wEPVal &EP_SETUP) != 0)
        {
          /* Get SETUP Packet*/
          ep->xfer_count = GetEPRxCount(ep->num);
          PMAToUserBufferCopy(&((&USB_Device_dev)->dev.setup_packet[0]),ep->pmaadress , ep->xfer_count);       
          /* SETUP bit kept frozen while CTR_RX = 1*/ 
          _ClearEP_CTR_RX(ENDP0); 
          
          /* Process SETUP Packet*/
          USBD_DCD_INT_fops->SetupStage(&USB_Device_dev);
        }
        
        else if ((wEPVal & EP_CTR_RX) != 0)
        {
          _ClearEP_CTR_RX(ENDP0);
          /* Get Control Data OUT Packet*/
          ep->xfer_count = GetEPRxCount(ep->num);
          
          if (ep->xfer_count != 0)
          {
            PMAToUserBufferCopy(ep->xfer_buff, ep->pmaadress, ep->xfer_count);
            ep->xfer_buff+=ep->xfer_count;
          }
          
          /* Process Control Data OUT Packet*/
          USBD_DCD_INT_fops->DataOutStage(&USB_Device_dev, 0x00);
          
          _SetEPRxCount(ENDP0, ep->maxpacket);
          _SetEPRxStatus(ENDP0,EP_RX_VALID);
        }
      }
    }/* 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);
        ep = &((&USB_Device_dev)->dev.out_ep[EPindex]);
        
        /* OUT double Buffering*/
        if (ep->doublebuffer == 0)
        {
          count = GetEPRxCount(ep->num);
          if (count != 0)
          {
            PMAToUserBufferCopy(ep->xfer_buff, ep->pmaadress, count);
          }
        }
        else
        {
          if (GetENDPOINT(ep->num) & EP_DTOG_RX)
          {
            /*read from endpoint BUF0Addr buffer*/
            count = GetEPDblBuf0Count(ep->num);
            if (count != 0)
            {
              PMAToUserBufferCopy(ep->xfer_buff, ep->pmaaddr0, count);
            }
          }
          else
          {
            /*read from endpoint BUF1Addr buffer*/
            count = GetEPDblBuf1Count(ep->num);
            if (count != 0)
            {
              PMAToUserBufferCopy(ep->xfer_buff, ep->pmaaddr1, count);
            }
          }
          FreeUserBuffer(ep->num, EP_DBUF_OUT);  
        }
        /*multi-packet on the NON control OUT endpoint*/
        ep->xfer_count+=count;
        ep->xfer_buff+=count;
       
        if ((ep->xfer_len == 0) || (count < ep->maxpacket))
        {
          /* RX COMPLETE */
          USBD_DCD_INT_fops->DataOutStage(&USB_Device_dev, ep->num);
        }
        else
        {
          DCD_EP_PrepareRx (&USB_Device_dev,ep->num, ep->xfer_buff, ep->xfer_len);
        }
        
      } /* if((wEPVal & EP_CTR_RX) */
      
      if ((wEPVal & EP_CTR_TX) != 0)
      {
        ep = &((&USB_Device_dev)->dev.in_ep[EPindex]);
        
        /* clear int flag */
        _ClearEP_CTR_TX(EPindex);
        
        /* IN double Buffering*/
        if (ep->doublebuffer == 0)
        {
          ep->xfer_count = GetEPTxCount(ep->num);
          if (ep->xfer_count != 0)
          {
            UserToPMABufferCopy(ep->xfer_buff, ep->pmaadress, ep->xfer_count);
          }
        }
        else
        {
          if (GetENDPOINT(ep->num) & EP_DTOG_TX)
          {
            /*read from endpoint BUF0Addr buffer*/
            ep->xfer_count = GetEPDblBuf0Count(ep->num);
            if (ep->xfer_count != 0)
            {
              UserToPMABufferCopy(ep->xfer_buff, ep->pmaaddr0, ep->xfer_count);
            }
          }
          else
          {
            /*read from endpoint BUF1Addr buffer*/
            ep->xfer_count = GetEPDblBuf1Count(ep->num);
            if (ep->xfer_count != 0)
            {
              UserToPMABufferCopy(ep->xfer_buff, ep->pmaaddr1, ep->xfer_count);
            }
          }
          FreeUserBuffer(ep->num, EP_DBUF_IN);  
        }
        /*multi-packet on the NON control IN endpoint*/
        ep->xfer_count =GetEPTxCount(ep->num);
        ep->xfer_buff+=ep->xfer_count;
       
        /* Zero Length Packet? */
        if (ep->xfer_len == 0)
        {
          /* TX COMPLETE */
          USBD_DCD_INT_fops->DataInStage(&USB_Device_dev, ep->num);
        }
        else
        {
          DCD_EP_Tx  (&USB_Device_dev,ep->num, ep->xfer_buff, ep->xfer_len);
        }
        
      } /* if((wEPVal & EP_CTR_TX) != 0) */
      
    }/* if(EPindex == 0) else */
    
  }/* while(...) */
}
Exemplo n.º 6
0
//enable ep N valid
void ep_rx_en(int ep_nr, int count)
{
    _SetEPRxCount(ep_nr, count);
	_SetEPRxStatus(ep_nr, EP_RX_VALID);
}
Exemplo n.º 7
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(...) */
}