STM32F1两个USB中断入口详解

发布时间:
来源: 电子工程世界

1 STM32F1两个USB中断入口


STM32中断入口有两个,分别是USB_HP_CAN1_TX_IRQHandler和USB_LP_CAN1_RX0_IRQHandler。


其中USB_Istr函数调用了CTR_LP函数,代码如下。


/*******************************************************************************

* Function Name  : USB_HP_CAN1_TX_IRQHandler

* Description    : This function handles USB High Priority or CAN TX interrupts

*                  requests.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void USB_HP_CAN1_TX_IRQHandler(void)

{

  CTR_HP();

}


/*******************************************************************************

* Function Name  : USB_LP_CAN1_RX0_IRQHandler

* Description    : This function handles USB Low Priority or CAN RX0 interrupts

*                  requests.

* Input          : None

* Output         : None

* Return         : None

*******************************************************************************/

void USB_LP_CAN1_RX0_IRQHandler(void)

{

  USB_Istr();

}

2 CTR_LP


CTR_LP为低优先级端点传输正常时的中断服务函数,控制传输只能在CTR_LP里面处理,代码如下。


/*******************************************************************************

* Function Name  : CTR_LP.

* Description    : Low priority Endpoint Correct Transfer interrupt's service

*                  routine.

* Input          : None.

* Output         : None.

* Return         : None.

*******************************************************************************/

void CTR_LP(void)

{

  uint32_t wEPVal = 0;

  /* stay in loop while pending ints */

  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);

    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(...) */

}

3 CTR_HP


CTR_HP为高优先级端点传输正常时的中断服务函数,代码如下。


/*******************************************************************************

* 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(...) */

}

4 CTR_LP和CTR_HP各自处理的事务类型


这两个函数定义在usb_int.c中,用法如下。


CTR_LP(低优先级中断Low-priority interrupt),用于控制传输、中断传输、批量传输( 单缓冲模式)。


CTR_HP(高优先级中断 High-priority interrupt),用于快速大数据量传输处理,比如同步传输、批量传输,但是都是处理双缓冲模式。


5 核心注意要点


如果把只初始化了USB_LP_CAN1_RX0_IRQn中断向量,则所有的正确传输中断只会进入USB_LP_CAN1_RX0_IRQHandler->CTR_LP,所以要想进入CTR_HP必须对其中断向量进行初始化,否则会使用默认的CTR_LP路径进行处理。


文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。