Beispiel #1
0
/*******************************************************************************
* Function Name  : USB_Istr
* Description    : ISTR events interrupt service routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void USB_Istr(void)
{

  wIstr = _GetISTR();

#if (IMR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
  {
    /* servicing of the endpoint correct transfer interrupt */
    /* clear of the CTR flag into the sub */
    CTR_LP();
#ifdef CTR_CALLBACK
    CTR_Callback();
#endif
  }
#endif  
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_RESET);
    Device_Property.Reset();
#ifdef RESET_CALLBACK
    RESET_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_DOVR);
#ifdef DOVR_CALLBACK
    DOVR_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_ERR);
#ifdef ERR_CALLBACK
    ERR_Callback();
#endif
  }
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_WKUP);
    Resume(RESUME_EXTERNAL);
#ifdef WKUP_CALLBACK
    WKUP_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
  {

    /* check if SUSPEND is possible */
    if (fSuspendEnabled)
    {
      Suspend();
    }
    else
    {
      /* if not possible then resume after xx ms */
      Resume(RESUME_LATER);
    }
    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    _SetISTR((uint16_t)CLR_SUSP);
#ifdef SUSP_CALLBACK
    SUSP_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_SOF);
    bIntPackSOF++;

#ifdef SOF_CALLBACK
    SOF_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_ESOF);
    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request without change of the machine state */

#ifdef ESOF_CALLBACK
    ESOF_Callback();
#endif
  }
#endif
} /* USB_Istr */
Beispiel #2
0
/*******************************************************************************
* Function Name  : USB_Istr
* Description    : ISTR events interrupt service routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void USB_Istr(void)
{
    uint32_t i=0;
 __IO uint32_t EP[8];
  
  wIstr = _GetISTR();

#if (IMR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_SOF);
    bIntPackSOF++;

#ifdef SOF_CALLBACK
    SOF_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/  
  
#if (IMR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
  {
    /* servicing of the endpoint correct transfer interrupt */
    /* clear of the CTR flag into the sub */
    CTR_LP();
#ifdef CTR_CALLBACK
    CTR_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/  
#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_RESET);
    Device_Property.Reset();
#ifdef RESET_CALLBACK
    RESET_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_DOVR);
#ifdef DOVR_CALLBACK
    DOVR_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_ERR);
#ifdef ERR_CALLBACK
    ERR_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_WKUP);
    Resume(RESUME_EXTERNAL);
#ifdef WKUP_CALLBACK
    WKUP_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
  {

    /* check if SUSPEND is possible */
    if (fSuspendEnabled)
    {
      Suspend();
    }
    else
    {
      /* if not possible then resume after xx ms */
      Resume(RESUME_LATER);
    }
    /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    _SetISTR((uint16_t)CLR_SUSP);
#ifdef SUSP_CALLBACK
    SUSP_Callback();
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

#if (IMR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    /* clear ESOF flag in ISTR */
    _SetISTR((uint16_t)CLR_ESOF);
    
    if ((_GetFNR()&FNR_RXDP)!=0)
    {
      /* increment ESOF counter */
      esof_counter ++;
      
      /* test if we enter in ESOF more than 3 times with FSUSP =0 and RXDP =1=>> possible missing SUSP flag*/
      if ((esof_counter >3)&&((_GetCNTR()&CNTR_FSUSP)==0))
      {           
        /* this a sequence to apply a force RESET*/
      
        /*Store CNTR value */
        wCNTR = _GetCNTR(); 
      
        /*Store endpoints registers status */
        for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i);
      
        /*apply FRES */
        wCNTR|=CNTR_FRES;
        _SetCNTR(wCNTR);
 
        /*clear FRES*/
        wCNTR&=~CNTR_FRES;
        _SetCNTR(wCNTR);
				
				/*disable ESOF interrupt*/
				//wCNTR &= ~CNTR_ESOFM;
				//_SetCNTR(wCNTR);
				
        /*poll for RESET flag in ISTR*/
        while((_GetISTR()&ISTR_RESET) == 0);
  
        /* clear RESET flag in ISTR */
        _SetISTR((uint16_t)CLR_RESET);
   
       /*restore Enpoints*/
        for (i=0;i<8;i++)
        _SetENDPOINT(i, EP[i]);
      
        esof_counter = 0;
      }
    }
    else
    {
        esof_counter = 0;
    }
    
    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request without change of the machine state */

#ifdef ESOF_CALLBACK
    ESOF_Callback();
#endif
  }
#endif
	
	/*disable ESOF interrupt*/
	wCNTR = _GetCNTR();
	wCNTR &= ~CNTR_ESOFM;
  _SetCNTR(wCNTR);
} /* USB_Istr */
Beispiel #3
0
/*******************************************************************************
* Function Name  : Suspend
* Description    : sets suspend mode operating conditions
* Input          : None.
* Output         : None.
* Return         : USB_SUCCESS.
*******************************************************************************/
void Suspend(void)
{
	uint32_t i =0;
	uint16_t wCNTR;
	uint32_t tmpreg = 0;
  __IO uint32_t savePWR_CR=0;
	/* suspend preparation */
	/* ... */

	/*Store CNTR value */
	wCNTR = _GetCNTR();

    /* This a sequence to apply a force RESET to handle a robustness case */

	/*Store endpoints registers status */
    for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i);

	/* unmask RESET flag */
	wCNTR|=CNTR_RESETM;
	_SetCNTR(wCNTR);

	/*apply FRES */
	wCNTR|=CNTR_FRES;
	_SetCNTR(wCNTR);

	/*clear FRES*/
	wCNTR&=~CNTR_FRES;
	_SetCNTR(wCNTR);

	/*poll for RESET flag in ISTR*/
	while((_GetISTR()&ISTR_RESET) == 0);

	/* clear RESET flag in ISTR */
	_SetISTR((uint16_t)CLR_RESET);

	/*restore Enpoints*/
	for (i=0;i<8;i++)
	_SetENDPOINT(i, EP[i]);

	/* Now it is safe to enter macrocell in suspend mode */
	wCNTR |= CNTR_FSUSP;
	_SetCNTR(wCNTR);

	/* force low-power mode in the macrocell */
	wCNTR = _GetCNTR();
	wCNTR |= CNTR_LPMODE;
	_SetCNTR(wCNTR);

	/*prepare entry in low power mode (STOP mode)*/
	/* Select the regulator state in STOP mode*/
	savePWR_CR = PWR->CR;
	tmpreg = PWR->CR;
	/* Clear PDDS and LPDS bits */
	tmpreg &= ((uint32_t)0xFFFFFFFC);
	/* Set LPDS bit according to PWR_Regulator value */
	tmpreg |= PWR_Regulator_LowPower;
	/* Store the new value */
	PWR->CR = tmpreg;
	/* Set SLEEPDEEP bit of Cortex System Control Register */
#if defined (STM32F30X) || defined (STM32F37X)
        SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
#else
        SCB->SCR |= SCB_SCR_SLEEPDEEP;
#endif

	/* enter system in STOP mode, only when wakeup flag in not set */
	if((_GetISTR()&ISTR_WKUP)==0)
	{
		__WFI();
		/* Reset SLEEPDEEP bit of Cortex System Control Register */
#if defined (STM32F30X) || defined (STM32F37X)
                SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
#else
                SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
#endif
	}
	else
	{
		/* Clear Wakeup flag */
		_SetISTR(CLR_WKUP);
		/* clear FSUSP to abort entry in suspend mode  */
                wCNTR = _GetCNTR();
                wCNTR&=~CNTR_FSUSP;
                _SetCNTR(wCNTR);

		/*restore sleep mode configuration */
		/* restore Power regulator config in sleep mode*/
		PWR->CR = savePWR_CR;

		/* Reset SLEEPDEEP bit of Cortex System Control Register */
#if defined (STM32F30X) || defined (STM32F37X)
                SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
#else
                SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
#endif
    }
}
/*******************************************************************************
* 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;
  /* 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();

        /* check if SETUP arrived during IN processing */
        wEPVal = _GetENDPOINT(ENDP0);
        if ((wEPVal & (EP_CTR_RX | EP_SETUP)) != 0)
        {
          _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
          Setup0_Process();
        }

      }

      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();
        }
        if ((wEPVal &EP_SETUP) != 0)
        {
          _ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
          Setup0_Process();
        }

        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);
    }/* 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(...) */
}
Beispiel #5
0
void USB_LP_CAN1_RX0_IRQHandler(void) {
  wIstr = _GetISTR();

  /* go nuts with the preproc switches since this is an ISTR and must be FAST */
#if (ISR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
    {
      _SetISTR((u16)CLR_RESET);
      Device_Property.Reset();
    }
#endif


#if (ISR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
    {
      _SetISTR((u16)CLR_DOVR);
    }
#endif


#if (ISR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
    {
      _SetISTR((u16)CLR_ERR);
    }
#endif


#if (ISR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
    {
      _SetISTR((u16)CLR_WKUP);
      usbResume(RESUME_EXTERNAL);
    }
#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (ISR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
    {

      /* check if SUSPEND is possible */
      if (F_SUSPEND_ENABLED)
	{
	  usbSuspend();
	}
      else
	{
	  /* if not possible then resume after xx ms */
	  usbResume(RESUME_LATER);
	}
      /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
      _SetISTR((u16)CLR_SUSP);
    }
#endif


#if (ISR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
    {
      _SetISTR((u16)CLR_SOF);
      bIntPackSOF++;
    }
#endif


#if (ISR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
    {
      _SetISTR((u16)CLR_ESOF);
      /* resume handling timing is made with ESOFs */
      usbResume(RESUME_ESOF); /* request without change of the machine state */
    }
#endif

  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (ISR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
    {
      /* servicing of the endpoint correct transfer interrupt */
      /* clear of the CTR flag into the sub */
      CTR_LP(); /* low priority ISR defined in the usb core lib */
    }
#endif

}
Beispiel #6
0
void USB_Istr(void)
{
	uint16_t wIstr = _GetISTR();
	
	if (wIstr & ISTR_RESET)
	{
		_SetISTR((uint16_t)CLR_RESET);
		if (stm32_usbd_callback.on_reset != NULL)
		{
			stm32_usbd_callback.on_reset(stm32_usbd_callback.param);
		}
	}
	if (wIstr & ISTR_DOVR)
	{
		_SetISTR((uint16_t)CLR_DOVR);
	}
	if (wIstr & ISTR_ERR)
	{
		_SetISTR((uint16_t)CLR_ERR);
		if (stm32_usbd_callback.on_error != NULL)
		{
			stm32_usbd_callback.on_error(stm32_usbd_callback.param,
											USBERR_ERROR);
		}
	}
	if (wIstr & ISTR_WKUP)
	{
		_SetISTR((uint16_t)CLR_WKUP);
		if (stm32_usbd_callback.on_wakeup != NULL)
		{
			stm32_usbd_callback.on_wakeup(stm32_usbd_callback.param);
		}
	}
	if (wIstr & ISTR_SUSP)
	{
		if (stm32_usbd_callback.on_suspend != NULL)
		{
			stm32_usbd_callback.on_suspend(stm32_usbd_callback.param);
		}
		_SetISTR((uint16_t)CLR_SUSP);
	}
	if (wIstr & ISTR_SOF)
	{
		_SetISTR((uint16_t)CLR_SOF);
		if (stm32_usbd_callback.on_sof != NULL)
		{
			stm32_usbd_callback.on_sof(stm32_usbd_callback.param);
		}
	}
	if (wIstr & ISTR_ESOF)
	{
		_SetISTR((uint16_t)CLR_ESOF);
		if (stm32_usbd_callback.on_error != NULL)
		{
			stm32_usbd_callback.on_error(stm32_usbd_callback.param,
											USBERR_SOF_TO);
		}
	}
	if (wIstr & ISTR_CTR)
	{
		CTR_LP();
	}
}
Beispiel #7
0
/**
  * @brief ISTR events interrupt service routine
  * @param  None
  * @retval None
  */
void USB_Istr(void)
{
  __IO uint16_t wIstr = 0; 
  
  wIstr = _GetISTR();
  
#if (IMR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
  {
    /* servicing of the endpoint correct transfer interrupt */
    /* clear of the CTR flag into the sub */
    CTR();
  }
#endif  
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_RESET);
    USBD_DCD_INT_fops->Reset(&USB_Device_dev);
    DCD_EP_SetAddress(&USB_Device_dev, 0);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_DOVR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_ERR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_WKUP);
    
    USBD_DCD_INT_fops->Resume(&USB_Device_dev);
     
    /* Handle Resume state machine */  
    Resume(RESUME_EXTERNAL);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
  {
   /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    _SetISTR((uint16_t)CLR_SUSP);
    
    /* choose to enter system in low power mode or not in user suspend callback */
    USBD_DCD_INT_fops->Suspend(&USB_Device_dev); 
    
    Suspend();   
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_SOF);
    USBD_DCD_INT_fops->SOF(&USB_Device_dev);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    /* clear ESOF flag in ISTR */
    _SetISTR((uint16_t)CLR_ESOF);
    
    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request without change of the machine state */
  }
#endif
} /* USB_Istr */
Beispiel #8
0
/*******************************************************************************
* Function Name  : USB_Istr
* Description    : ISTR events interrupt service routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void USB_Istr(void)
{

    wIstr = _GetISTR();
	#if (IMR_MSK & ISTR_RESET)  //如果设置了USB中断
    if (wIstr & ISTR_RESET & wInterrupt_Mask)
    {
  		//ISTR 程式只能清0,无法写1,
  		 //用要清除的位为0,其他位写为1
    	_SetISTR((u16)CLR_RESET); 
        Device_Property.Reset();
		#ifdef RESET_CALLBACK
    		RESET_Callback();
		#endif
    }
#endif
  	/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
    if (wIstr & ISTR_DOVR & wInterrupt_Mask)
    {
    	_SetISTR((u16)CLR_DOVR);
		#ifdef DOVR_CALLBACK
    	DOVR_Callback();
		#endif
    }
#endif
    /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
    if (wIstr & ISTR_ERR & wInterrupt_Mask)
    {
    	_SetISTR((u16)CLR_ERR);
 		#ifdef ERR_CALLBACK
    	ERR_Callback();
		#endif
    }
#endif
    /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
    if (wIstr & ISTR_WKUP & wInterrupt_Mask)
    {
   	 _SetISTR((u16)CLR_WKUP);
        Resume(RESUME_EXTERNAL);
	#ifdef WKUP_CALLBACK
    	WKUP_Callback();
	#endif
    }
#endif
    /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)//USB掛起
    {

        /* check if SUSPEND is possible */
    	if (fSuspendEnabled)  //usb掛起全能
        {
      		Suspend();  //直接硬件掛起
        }
        else
        {
    		//软件掛起
            /* if not possible then resume after xx ms */
      		Resume(RESUME_LATER); // 枚举掛起
        }
        /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    	_SetISTR((u16)CLR_SUSP);
		#ifdef SUSP_CALLBACK
    		SUSP_Callback();
		#endif
    }
#endif
    /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
	#if (IMR_MSK & ISTR_SOF) //帧首标志   //1ms enter one time
    if (wIstr & ISTR_SOF & wInterrupt_Mask)
    {
    	_SetISTR((u16)CLR_SOF);
    	bIntPackSOF++;  //帧指针加一

		#ifdef SOF_CALLBACK
    		SOF_Callback();
		#endif
    }
#endif
    /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
    if (wIstr & ISTR_ESOF & wInterrupt_Mask)
    {
    	_SetISTR((u16)CLR_ESOF); //帧期望标志
        /* resume handling timing is made with ESOFs */
        Resume(RESUME_ESOF); /* request without change of the machine state */

		#ifdef ESOF_CALLBACK
    	ESOF_Callback();
		#endif
  	}
	#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
	#if (IMR_MSK & ISTR_CTR)
  	if (wIstr & ISTR_CTR & wInterrupt_Mask)
  	{
    	/* servicing of the endpoint correct transfer interrupt */
    	/* clear of the CTR flag into the sub */
    	CTR_LP();
		#ifdef CTR_CALLBACK
    	CTR_Callback();
		#endif
    }
#endif
} /* USB_Istr */
/**
  * @brief ISTR events interrupt service routine
  * @param  None
  * @retval None
  */
void USB_Istr(void)
{
  __IO uint16_t wIstr = 0; 

  wIstr = _GetISTR();
  
#if (IMR_MSK & ISTR_CTR)
  if (wIstr & ISTR_CTR & wInterrupt_Mask)
  {
    /* servicing of the endpoint correct transfer interrupt */
    /* clear of the CTR flag into the sub */
    CTR();
  }
#endif  
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_RESET)
  if (wIstr & ISTR_RESET & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_RESET);
    USBD_DCD_INT_fops->Reset(&USB_Device_dev);
    DCD_EP_SetAddress(&USB_Device_dev, 0);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
  if (wIstr & ISTR_DOVR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_DOVR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
  if (wIstr & ISTR_ERR & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_ERR);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
  if (wIstr & ISTR_WKUP & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_WKUP);
    
    USBD_DCD_INT_fops->Resume(&USB_Device_dev);
     
    /* Handle Resume state machine */  
    Resume(RESUME_EXTERNAL);

#ifdef LPM_ENABLED    
    /* clear L1 remote wakeup flag */
    L1_remote_wakeup = 0;
#endif
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
  if (wIstr & ISTR_SUSP & wInterrupt_Mask)
  {
   /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
    _SetISTR((uint16_t)CLR_SUSP);
    
    /* process library core layer suspend routine*/
    USBD_DCD_INT_fops->Suspend(&USB_Device_dev); 
    
    /* enter macrocell in suspend and system in low power mode when 
       USB_DEVICE_LOW_PWR_MGMT_SUPPORT defined in usb_conf.h */
    Suspend();   
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
  if (wIstr & ISTR_SOF & wInterrupt_Mask)
  {
    _SetISTR((uint16_t)CLR_SOF);
    USBD_DCD_INT_fops->SOF(&USB_Device_dev);
  }
#endif
  /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
  if (wIstr & ISTR_ESOF & wInterrupt_Mask)
  {
    /* clear ESOF flag in ISTR */
    _SetISTR((uint16_t)CLR_ESOF);
    
    /* resume handling timing is made with ESOFs */
    Resume(RESUME_ESOF); /* request without change of the machine state */
  }
#endif


#ifdef LPM_ENABLED  
#if (IMR_MSK & ISTR_L1REQ)
  if (wIstr & ISTR_L1REQ & wInterrupt_Mask)
  {
     /* clear L1REQ flag in ISTR */
    _SetISTR((uint16_t)CLR_L1REQ);
    
    /* read BESL field which coressponds to HIRD parameter in LPM spec*/
    /* In your application depending on BESL value, you can choose the right 
    low power mode during L1 state, allowing wakeup time within the request time from host.*/
    BESL = (_GetLPMCSR()&LPMCSR_BESL) >>4 ;
    
    /* read REMWAKE bit which corresponding to bRemoteWake bit in LPM request*/
    /* if this bit is set then L1 remote wakeup is possible */
    L1_remote_wakeup = (_GetLPMCSR()&LPMCSR_REMWAKE) >>3;
    
    /* process library core layer suspend routine*/
    USBD_DCD_INT_fops->Suspend(&USB_Device_dev); 
    
    /* enter macrocell in suspend and system in low power mode (STOP mode) when 
    USB_DEVICE_LOW_PWR_MGMT_SUPPORT defined in usb_conf.h.*/   
    /* Please note that in this example we enter in STOP mode during L1 state independently
    from value read in BESL (even for BESL= 0 which corresponds to 50us delay) because
    STM32F072 can wakeup system from STOP mode in less than 50 us */
    Suspend();
  }
Beispiel #10
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(...) */
}