示例#1
0
void CTR_HP(void)
{
	uint8_t EPindex;
	int8_t epaddr;
	uint16_t wIstr;
	uint32_t wEPVal = 0;
	
	while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
	{
		_SetISTR((uint16_t)CLR_CTR);
		
		EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
		epaddr = stm32_usbd_epaddr[EPindex];
		wEPVal = _GetENDPOINT(EPindex);
		if ((wEPVal & EP_CTR_RX) != 0)
		{
			_ClearEP_CTR_RX(EPindex);
			if ((stm32_usbd_callback.on_out != NULL) && (epaddr >= 0))
			{
				stm32_usbd_callback.on_out(stm32_usbd_callback.param, epaddr);
			}
		}
		else if ((wEPVal & EP_CTR_TX) != 0)
		{
			_ClearEP_CTR_TX(EPindex);
			if ((stm32_usbd_callback.on_in != NULL) && (epaddr >= 0))
			{
				stm32_usbd_callback.on_in(stm32_usbd_callback.param, epaddr);
			}
		}
	}
}
示例#2
0
/*******************************************************************************
* Function Name  : CTR_HP.
* Description    : High Priority Endpoint Correct Transfer interrupt's service 
*                  routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CTR_HP(void)
{
  uint32_t wEPVal = 0;

  while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
  {
    _SetISTR((uint16_t)CLR_CTR); /* clear CTR flag */
    /* extract highest priority endpoint number */
    EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
    /* 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) */
    else 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) */

  }/* while(...) */
}
示例#3
0
/*******************************************************************************
* Function Name  : CTR_HP.
* Description    : High Priority Endpoint Correct Transfer interrupt's service 
*                  routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void CTR_HP(void)
{
  u32 wEPVal = 0;

  while (((wIstr = ((u16) *(volatile unsigned *)(0x40005C44L))) & ISTR_CTR) != 0)
  {
    _SetISTR((u16)CLR_CTR); /* clear CTR flag */
    /* extract highest priority endpoint number */
    EPindex = (u8)(wIstr & ISTR_EP_ID);
    /* 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) */
    else 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) */

  }/* while(...) */
}
void USBglobalInterruptHandler() {
  uint16_t pending;

  pending = _GetCNTR() & _GetISTR();
  if (pending & ISTR_CTR) {
    uint16_t EPindex, EPflags, EPnum;

    EPindex = _GetISTR() & ISTR_EP_ID;
    EPflags = _GetENDPOINT(EPindex);
    EPnum   = EPflags & EPADDR_FIELD;
    /* The EP_SETUP bit implies the EP_CTR_RX bit. */
    if (EPflags & EP_SETUP) {
      _ClearEP_CTR_RX(EPindex);
      USBDtransfer(EPnum, PID_SETUP);
    }
    else if (EPflags & EP_CTR_RX) {
      _ClearEP_CTR_RX(EPindex);
      USBDtransfer(EPnum, PID_OUT);
    }
    else if (EPflags & EP_CTR_TX) {
      _ClearEP_CTR_TX(EPindex);
      if (EPnum != 0)
        USBDcontinueInTransfer(EPnum);
      USBDtransfer(EPnum, PID_IN);
    }
  }
  if (pending & ISTR_DOVR) {
    _SetISTR(CLR_DOVR);
  }
  if (pending & ISTR_ERR) {
    _SetISTR(CLR_ERR);
  }
  if (pending & ISTR_SUSP) {
    USBDsuspend();
    PWRreduce();
    /* The ISTR_SUSP bit must be cleared after
       setting of the CNTR_FSUSP bit. */
    _SetISTR(CLR_SUSP);
  }
  if (pending & ISTR_WKUP) {
    _SetISTR(CLR_WKUP);
    PWRresume();
    USBDwakeup();
  }
  if (pending & ISTR_RESET) {
    _SetISTR(CLR_RESET);
    USBDreset(FULL_SPEED);
  }
  if (pending & ISTR_SOF) {
    _SetISTR(CLR_SOF);
    USBDsof(_GetFNR() & FNR_FN);
  }
  if (pending & ISTR_ESOF) {
    _SetISTR(CLR_ESOF);
  }
}
示例#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)
{
  volatile 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 */
      /* calling related service routine */
      /* (Setup0_Process, In0_Process, Out0_Process) */

      /* save RX & TX status */
      /* and set both to NAK */
      
	    SaveRState = _GetENDPOINT(ENDP0);
	    SaveTState = SaveRState & EPTX_STAT;
	    SaveRState &=  EPRX_STAT;	

	    _SetEPRxTxStatus(ENDP0,EP_RX_NAK,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 */

            _SetEPRxTxStatus(ENDP0,SaveRState,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_SETUP) != 0)
        {
          _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
          Setup0_Process();
          /* before terminate set Tx & Rx status */

		      _SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
          return;
        }

        else if ((wEPVal & EP_CTR_RX) != 0)
        {
          _ClearEP_CTR_RX(ENDP0);
          Out0_Process();
          /* before terminate set Tx & Rx status */
     
		     _SetEPRxTxStatus(ENDP0,SaveRState,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(...) */
}
示例#6
0
void CTR_LP(void)
{
	uint8_t EPindex;
	int8_t epaddr;
	uint16_t wIstr;
	volatile uint16_t wEPVal = 0;
	
	while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
	{
		EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
		epaddr = stm32_usbd_epaddr[EPindex];
		
		if (epaddr == 0)
		{
			if ((wIstr & ISTR_DIR) == 0)
			{
				_ClearEP_CTR_TX(ENDP0);
				if (stm32_usbd_callback.on_in != NULL)
				{
					stm32_usbd_callback.on_in(stm32_usbd_callback.param,
												epaddr);
				}
				return;
			}
			else
			{
				wEPVal = _GetENDPOINT(ENDP0);
				_ClearEP_CTR_RX(ENDP0);
				if ((wEPVal & EP_SETUP) != 0)
				{
					if (stm32_usbd_callback.on_setup != NULL)
					{
						stm32_usbd_callback.on_setup(stm32_usbd_callback.param);
					}
				}
				else if ((wEPVal & EP_CTR_RX) != 0)
				{
					if (stm32_usbd_callback.on_out != NULL)
					{
						stm32_usbd_callback.on_out(stm32_usbd_callback.param,
													epaddr);
					}
				}
				return;
			}
		}
		else
		{
			wEPVal = _GetENDPOINT(EPindex);
			if ((wEPVal & EP_CTR_RX) != 0)
			{
				_ClearEP_CTR_RX(EPindex);
				if ((stm32_usbd_callback.on_out != NULL) && (epaddr >= 0))
				{
					stm32_usbd_callback.on_out(stm32_usbd_callback.param,
												epaddr);
				}
			}
			if ((wEPVal & EP_CTR_TX) != 0)
			{
				_ClearEP_CTR_TX(EPindex);
				if ((stm32_usbd_callback.on_in != NULL) && (epaddr >= 0))
				{
					stm32_usbd_callback.on_in(stm32_usbd_callback.param,
												epaddr);
				}
			}
		}
	}
}
示例#7
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(...) */
}
示例#8
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(...) */
}