⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stm32f_usb.c

📁 STM32F RFID通讯源代码(支持双向发送接收)
💻 C
📖 第 1 页 / 共 5 页
字号:
        UsbUserFun[EpPhAddr]((void *)UsbDataOutPacket);
      }
    }
    else
    {
      // IN EP
      EpCtrlClr_CTR_TX(EpInfo[EpPhAddr].pEpCtrl);
      Status = EpCtrlGet_DTOG_RX(EpInfo[EpPhAddr].pEpCtrl);
      if(Status == EpCtrlGet_DTOG_TX(EpInfo[EpPhAddr].pEpCtrl))
      {
        // The both buffers are drained
        ++EpInfo[EpPhAddr].EpIntrFl;
      }
      if(UsbUserFun[EpPhAddr] != NULL)
      {
        UsbUserFun[EpPhAddr]((void *)UsbDataInPacket);
      }
    }
  }
}
#endif // USB_HIGH_PRIORITY_EVENT > 0

/*************************************************************************
 * Function Name: USB_ISR
 * Parameters: none
 *
 * Return: none
 *
 * Description: USB interrupt subroutine
 *
 *************************************************************************/
void USB_ISR (void)
{
IntrStatus_t IntrStatus;
Int32U EpPhAddr;
Boolean SetupPacket;

  // Get masked interrupt flags
  IntrStatus.Status  = USB_ISTR;
  IntrStatus.Status &= USB_CNTR | 0x1F;

#if USB_DOVR_EVENT > 0
  // DMA over / underrun (for speed up retry process)
  if(IntrStatus.DOVR)
  {
    USB_ISTR = ~bmDOVR;
    if(UsbUserFun[UsbDovrEvent] != NULL)
    {
      UsbUserFun[UsbDovrEvent]((void *)Val);
    }
  }
#endif

#if USB_ERROR_EVENT > 0
  // USB engine error interrupt
  if(IntrStatus.ERR)
  {
    USB_ISTR = ~bmERRM;
    if(UsbUserFun[UsbErrorEvent] != NULL)
    {
      UsbUserFun[UsbErrorEvent](NULL);
    }
  }
#endif

  // Device reset
  if(IntrStatus.RESET)
  {
    USB_ISTR = ~bmRESETM;
    USB_HwReset();
    UsbDevConnectCallback(TRUE);
    UsbDevResetCallback();
    UsbDevSuspendCallback(FALSE);
  }

#if USB_SOF_EVENT > 0
  // Frame interrupt
  if(IntrStatus.SOF)
  {
    USB_ISTR = ~bmSOFM;
    if(UsbUserFun[UsbUserSofEvent] != NULL)
    {
      UsbUserFun[UsbUserSofEvent]((void *)NULL);
    }
  }
#endif

  // Wake-up interrupt
  if(IntrStatus.WKUP)
  {
    USB_ISTR = ~(bmSUSPM | bmWKUPM);
    USB_Resume(USB_RESUME_WAKE_UP_EVENT);
  }

  // Device suspend
  if(IntrStatus.SUSP)
  {
    USB_Suspend();
    USB_ISTR = ~(bmSUSPM | bmWKUPM);
    UsbDevSuspendCallback(TRUE);
  }

  // Expected Frame interrupt
  if(IntrStatus.ESOF)
  {
    USB_ISTR = ~bmESOFM;
    USB_Resume(USB_RESUME_SOF_EVENT);
  }

  // Low priority EP interrupt
  if(IntrStatus.CTR)
  {
    // find corresponding EP
    pInt32U pReg = (pInt32U)&USB_EP0R;
    pReg += IntrStatus.EP_ID;
    EpPhAddr = ((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1);
    // The ISO and Double buffered endpoints have own interrupt (HIGH_INTR)
    if((EpInfo[EpPhAddr].EpType != EP_ISO) &&
       (EpInfo[EpPhAddr].EpType != EP_BULK_DOUB_BUF))
    {
      if(EpPhAddr == CTRL_ENP_OUT)
      {
        // determinate type of packet (only for control EP)
        SetupPacket = EpCtrlGet_SETUP(EpInfo[EpPhAddr].pEpCtrl);
        EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
        if(UsbUserFun[UsbEp0Out] != NULL)
        {
          // call appropriate callback function
          if(SetupPacket)
          {
            UsbUserFun[UsbEp0Out]((void *)UsbSetupPacket);
          }
          else
          {
            UsbUserFun[UsbEp0Out]((void *)UsbDataOutPacket);
          }
        }
      }
      else if (EpPhAddr & 1)
      {
        // OUT EP
        EpCtrlClr_CTR_TX(EpInfo[EpPhAddr].pEpCtrl);
        if(UsbUserFun[EpPhAddr] != NULL)
        {
          UsbUserFun[EpPhAddr]((void *)UsbDataInPacket);
        }
      }
      else
      {
        // IN EP
        EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
        if(UsbUserFun[EpPhAddr] != NULL)
        {
          UsbUserFun[EpPhAddr]((void *)UsbDataOutPacket);
        }
      }
    }
  }
}

/*************************************************************************
 * Function Name: UsbCtrlEp
 * Parameters:  void * pArg
 *
 * Return: none
 *
 * Description: USB Ctrl EP Callback
 *
 *************************************************************************/
static inline
void UsbCtrlEp (USB_PacketType_t Packet)
{
Int32U CurrCount;

  if(Packet == UsbSetupPacket)
  {
    // Setup packet
    UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;

    UsbEp0Ctrl.pData   = EpCtrlDataBuf;
    UsbEp0Ctrl.Counter = Ep0MaxSize;
    USB_EpRead(CTRL_ENP_OUT,EpCtrlDataBuf,&UsbEp0Ctrl.Counter);

    // Copy new setup packet int setup buffer
    memcpy((Int8U *)&UsbEp0SetupPacket,EpCtrlDataBuf,sizeof(UsbEp0SetupPacket));
    if(UsbEp0Ctrl.Counter != sizeof(UsbSetupPacket_t))
    {
      UsbEp0SetupPacket.mRequestType.Type = UsbTypeReserved;
    }
    else
    {
      // validate OUT/IN EP
      USB_EpValidate(CTRL_ENP_OUT,TRUE);
      USB_SetStallEP(CTRL_ENP_IN,FALSE);
    }

    switch(UsbEp0SetupPacket.mRequestType.Type)
    {
    // Standard
    case UsbTypeStandart:
      // Decoding standard request
      switch (UsbEp0SetupPacket.bRequest)
      {
      case GET_STATUS:
        UsbGetStatus();
        break;
      case CLEAR_FEATURE:
        UsbClearFeature();
        break;
      case SET_FEATURE:
        UsbSetFeature();
        break;
      case SET_ADDRESS:
        UsbSetAddress();
        break;
      case GET_DESCRIPTOR:
        if(UsbEp0SetupPacket.mRequestType.Recipient == UsbRecipientDevice)
        {
          UsbGetDescriptor();
        }
        // Only get descriptor for device is standard request
        else if ((UsbEp0SetupPacket.mRequestType.Dir == UsbDevice2Host) &&
                 (UsbUserFun[UsbUserGetDescriptor] != NULL) &&
                 ((Int32U)UsbUserFun[UsbUserGetDescriptor](&UsbEp0Ctrl) == UsbPass))
        {
          if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word)
          {
            UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word;
            UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
          }
          else
          {
            UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE;
          }
          UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
        }
        else
        {
          UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
        }
        break;
      case SET_DESCRIPTOR:
        // Optional (only for configuration and string descriptors)
        UsbSetDescriptor();
        break;
      case GET_CONFIGURATION:
        UsbGetConfiguration();
        break;
      case SET_CONFIGURATION:
        UsbSetConfiguration();
        break;
      case GET_INTERFACE:
        UsbGetInterface();
        break;
      case SET_INTERFACE:
        UsbSetInterface();
        break;
      case SYNCH_FRAME:
        UsbSynchFrame();
        break;
      default:
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
      }
      break;
    // Class
    case UsbTypeClass:
      if(UsbUserFun[UsbUserClass] != NULL &&
         ((Int32U)UsbUserFun[UsbUserClass](&UsbEp0Ctrl) == UsbPass))
      {
        if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word)
        {
          UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word;
          UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
        }
        else
        {
          UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE;
        }
        UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
      }
      else
      {
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
      }
      break;
    // Vendor
    case UsbTypeVendor:
      if(UsbUserFun[UsbUserVendor] != NULL &&
        ((Int32U)UsbUserFun[UsbUserVendor](&UsbEp0Ctrl) == UsbPass))
      {
        if(UsbEp0Ctrl.Counter >= UsbEp0SetupPacket.wLength.Word)
        {
          UsbEp0Ctrl.Counter = UsbEp0SetupPacket.wLength.Word;
          UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
        }
        else
        {
          UsbEp0Ctrl.EpStatus.NoZeroLength = FALSE;
        }
        UsbEp0Ctrl.EpStatus.Status = UsbDataPhase;
      }
      else
      {
        UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
      }
      break;
    // Other
    default:
      UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
    }
  }

  switch (UsbEp0Ctrl.EpStatus.Status)
  {
  case UsbDataPhase:
    if (UsbEp0SetupPacket.mRequestType.Dir == UsbHost2Device)
    {
      if (Packet == UsbDataOutPacket)
      {
        // Data receiving
        CurrCount = Ep0MaxSize;
        USB_EpRead(CTRL_ENP_OUT,UsbEp0Ctrl.pData,&CurrCount);
        UsbEp0Ctrl.pData += CurrCount;
        UsbEp0Ctrl.Counter -= CurrCount;
        // Receiving of data complete when all data was received or
        // when host send short packet
        if ((UsbEp0Ctrl.Counter == 0) ||
            (CurrCount < Ep0MaxSize))
        {
          // Find appropriate callback function depending of current request
          // after data was received
          switch (UsbEp0SetupPacket.mRequestType.Type)
          {
          case UsbTypeStandart:
            if ((UsbCoreT9Fun != NULL) &&
                ((Int32U)UsbCoreT9Fun(NULL) == UsbPass))
            {
              UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
            }
            else
            {
            // Stall EP if callback function isn't set, but host
            // send this type request or when callback function
            // return an error.
              UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
            }
            UsbCoreT9Fun = NULL;
            break;
          case UsbTypeClass:
            if ((UsbUserFun[UsbClassEp0OutPacket] != NULL) &&
                ((Int32U)UsbUserFun[UsbClassEp0OutPacket](NULL) == UsbPass))
            {
              UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
            }
            else
            {
              UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
            }
            break;
          case UsbTypeVendor:
            if ((UsbUserFun[UsbVendorEp0OutPacket] != NULL) &&
                ((Int32U)UsbUserFun[UsbVendorEp0OutPacket](NULL) == UsbPass))
            {
              UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
            }
            else
            {
              UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
            }
            break;
          default:
            UsbEp0Ctrl.EpStatus.Status = UsbEpStall;
          }
          if(UsbEp0Ctrl.EpStatus.Status == UsbStatusPhase)
          {
            CurrCount = 0;
            USB_EpWrite(CTRL_ENP_IN,NULL,&CurrCount);
            UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
          }
        }
      }
      else if (UsbEp0Ctrl.Counter == 0)
      {
        CurrCount = 0;
        USB_EpWrite(CTRL_ENP_IN,NULL,&CurrCount);
        UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
      }
    }
    else
    {
       // Data transmit
      if (Packet == UsbDataOutPacket)
      {
        USB_EpValidate(CTRL_ENP_OUT,TRUE);
        UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
        break;
      }
      CurrCount = Ep0MaxSize;
      if ((UsbEp0Ctrl.Counter == 0) && UsbEp0Ctrl.EpStatus.NoZeroLength)
      {
        UsbEp0Ctrl.EpStatus.Status = UsbStatusPhase;
        break;
      }
      else if(UsbEp0Ctrl.Counter < Ep0MaxSize)
      {
        UsbEp0Ctrl.EpStatus.NoZeroLength = TRUE;
        CurrCount = UsbEp0Ctrl.Counter;
      }
      USB_EpWrite(CTRL_ENP_IN,UsbEp0Ctrl.pData,&CurrCount);
      UsbEp0Ctrl.Counter -= CurrCount;
      UsbEp0Ctrl.pData += CurrCount;
    }
    break;
  case UsbStatusPhase:
    if (UsbEp0SetupPacket.bRequest == SET_ADDRESS)
    {
      // Device address is set after status phase of set address request
      UsbDevCtrl.DevAdd = UsbEp0SetupPacket.wValue.Lo;
      USB_SetAdd(UsbDevCtrl.DevAdd);
      if(UsbDevCtrl.DevAdd)
      {
        UsbSetDevState(UsbDevStatusAddress);
      }
      else
      {
        // when address is 0 put device int configuration state
        UsbSetDevState(UsbDevStatusDefault);
      }
    }
    if (Packet == UsbDataOutPacket)
    {
      USB_EpValidate(CTRL_ENP_OUT,TRUE);
    }
    UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
    break;
  default:
    // Error
    USB_SetStallEP(CTRL_ENP_IN,TRUE);
    USB_SetStallEP(CTRL_ENP_OUT,TRUE);
    UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -