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

📄 usb_hw.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 4 页
字号:
      // Validate buffer
      if(pEP->EpType == UsbEpTransferBulk && pEP->bDoubleBuffered)
      {
        // Toggle Filled buffer bit
        EpCtrlToggle_DTOG_RX(pEP->pEpCtrl);
      }

      if (CurrentBuffer)
      {
        WriteEpDTB_CountTx(pEP->EpSlot,CountHold);
      }
      else
      {
        WriteEpDTB_CountRx(pEP->EpSlot,CountHold);
      }

      EpCtrlSet_STAT_TX(pEP->pEpCtrl,EP_VALID);

      --EpCnfg[EP].AvbBuff;
      Count = pEP->Size - pEP->Offset;
    }

    if(!pEP->bZeroPacket && !Count)
    {
      pEP->Status = COMPLETE;
      //call callback function
      if(pEP->pFn)
      {
        ((void(*)(USB_Endpoint_t))pEP->pFn)(EP);
      }
    }
  }
  else
  {
    // OUT
    while(pEP->AvbBuff)
    {
      // Get data size and buffer begin address
      switch (pEP->EpType)
      {
      case UsbEpTransferControl:
      case UsbEpTransferInterrupt:
        // Get received bytes number
        Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
        // Get address of the USB packet buffer for corresponding EP
        pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
        break;
      case UsbEpTransferBulk:
        if (!pEP->bDoubleBuffered)
        {
          // Get received bytes number
          Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
          // Get address of the USB packet buffer for corresponding EP
          pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
        }
        else
        {
          if (!(*pEP->pEpCtrl & (1UL << 6)))  // DTOGTX
          {
            // Tx Buffer
            Count = ReadEpDTB_CountTx(pEP->EpSlot) & 0x3FF;
            pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
          }
          else
          {
            // Rx Buffer
            Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
            pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
          }
        }
        break;
      case UsbEpTransferIsochronous:
        if(*pEP->pEpCtrl & (1UL <<14))  // DTOGRX
        {
          // Tx Buffer
          Count = ReadEpDTB_CountTx(pEP->EpSlot) & 0x3FF;
          pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
        }
        else
        {
          // Rx Buffer
          Count = ReadEpDTB_CountRx(pEP->EpSlot) & 0x3FF;
          pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
        }
        break;
      default:
        assert(0);
        return;
      }

      if(Count > (pEP->Size - pEP->Offset))
      {
        pEP->Status = BUFFER_OVERRUN;
        pEP->Size = EpCnfg[EP].Offset;
        break;
      }
      else if (Count < EpCnfg[EP].MaxSize)
      {
        pEP->Status = BUFFER_UNDERRUN;
        pEP->Size = EpCnfg[EP].Offset + Count;
      }
      else
      {
        pEP->Status = BEGIN_SERVICED;
      }

      Int32U Offset = pEP->Offset;
      pEP->Offset += Count;

      // Read data from SIE buffer
      while (Count)
      {
        Data = *pSrc++;
        *(pEP->pBuffer+Offset++) = Data;
        if (--Count)
        {
          Data >>= 8;
          *(pEP->pBuffer+Offset++) = Data;
          --Count;
        }
      }

      if(pEP->EpType == UsbEpTransferBulk && pEP->bDoubleBuffered)
      {
        EpCtrlToggle_DTOG_TX(pEP->pEpCtrl);
      }

      EpCtrlSet_STAT_RX(pEP->pEpCtrl,EP_VALID);

      --EpCnfg[EP].AvbBuff;

      if(*pEP->pEpCtrl & (1UL<<11))
      {
        EpCnfg[EP].Status = SETUP_OVERWRITE;
        return;
      }
      if (!(Count = (pEP->Size - pEP->Offset)))
      {
        pEP->Status = COMPLETE;
        break;
      }
    }

    if (pEP->Status != BEGIN_SERVICED && pEP->Status != NO_SERVICED)
    {
      //call callback function
      if(pEP->pFn)
      {
        ((void(*)(USB_Endpoint_t))pEP->pFn)(EP);
      }
    }
  }
}

/*************************************************************************
 * Function Name: USB_EpLogToPhysAdd
 * Parameters: Int8U EpLogAdd
 *
 * Return: USB_Endpoint_t
 *
 * Description: Convert the logical to physical address
 *
 *************************************************************************/
USB_Endpoint_t USB_EpLogToPhysAdd (Int8U EpLogAdd)
{
USB_Endpoint_t Address = (USB_Endpoint_t)((EpLogAdd & 0x0F)<<1);
  if(EpLogAdd & 0x80)
  {
    ++Address;
  }
  return(Address);
}

#if USB_SOF_EVENT > 0
/*************************************************************************
 * Function Name: USB_GetFrameNumb
 * Parameters: none
 *
 * Return: Int32U
 *
 * Description: Return current value of SOF number
 *
 *************************************************************************/
Int32U USB_GetFrameNumb (void)
{
  return(USB_FNR_bit.FN);
}
#endif // USB_SOF_EVENT > 0

/*************************************************************************
 * Function Name: USB_StatusPhase
 * Parameters: Boolean In
 *
 * Return: none
 *
 * Description: Prepare status phase
 *
 *************************************************************************/
void USB_StatusPhase (Boolean In)
{
  if(In)
  {
    USB_IO_Data(CTRL_ENP_IN,NULL,0,NULL);
  }
}

#if USB_HIGH_PRIORITY_EVENT > 0
/*************************************************************************
 * Function Name: USB_HIGH_ISR
 * Parameters: none
 *
 * Return: none
 *
 * Description: High priority USB interrupt subroutine
 *
 *************************************************************************/
void USB_HIGH_ISR (void)
{
IntrStatus_t IntrStatus;
Int32U Status;

  USB_HIGH_INTR_ENTRY_HOOK();

  IntrStatus.Status  = USB_ISTR;
  IntrStatus.Status &= USB_CNTR | 0x1F;
  // Get masked interrupt flags
  if(IntrStatus.CTR)
  {

    USB_Endpoint_t EP;
    // find corresponding EP
    pInt32U pReg = (pInt32U)&USB_EP0R;
    pReg += IntrStatus.EP_ID;
    EP = (USB_Endpoint_t)(((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1));
    // The ISO and Double buffered endpoints have own interrupt (HIGH_INTR)
    if(EpCnfg[EP].bDoubleBuffered)
    {
      if(EP & 1)
      {
        // IN EP
        assert(EpCnfg[EP].pEpCtrl);
        EpCtrlClr_CTR_TX(EpCnfg[EP].pEpCtrl);
        Status = EpCtrlGet_DTOG_RX(EpCnfg[EP].pEpCtrl);
        EpCnfg[EP].AvbBuff = 1;
        if(  (EpCnfg[EP].EpType != UsbEpTransferIsochronous)
           &&(Status == EpCtrlGet_DTOG_TX(EpCnfg[EP].pEpCtrl)))
        {
          // The both buffers are drained
          ++EpCnfg[EP].AvbBuff;
        }
        USB_EP_IO(EP);
      }
      else
      {
        // OUT EP
        assert(EpCnfg[EP].pEpCtrl);
        EpCtrlClr_CTR_RX(EpCnfg[EP].pEpCtrl);
        Status = EpCtrlGet_DTOG_TX(EpCnfg[EP].pEpCtrl);
        EpCnfg[EP].AvbBuff = 1;
        if(  (EpCnfg[EP].EpType != UsbEpTransferIsochronous)
           &&(Status == EpCtrlGet_DTOG_RX(EpCnfg[EP].pEpCtrl)))
        {
          // The both buffers are drained
          ++EpCnfg[EP].AvbBuff;
        }
        USB_EP_IO(EP);
      }
    }
  }
  USB_HIGH_INTR_EXIT_HOOK();
}
#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;

  USB_INTR_ENTRY_HOOK();

  // 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.PMAOVR)
  {
    USB_ISTR = ~bmPMAOVRM;
    USB_ERR_HOOK(PMAOVR_ERROR);
  }
#endif

#if USB_ERROR_EVENT > 0
  // USB engine error interrupt
  if(IntrStatus.ERR)
  {
    USB_ISTR = ~bmERRM;
    USB_ERR_HOOK(GENERAL_ERROR);
  }
#endif

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

#if USB_SOF_EVENT > 0
  // Frame interrupt
  if(IntrStatus.SOF)
  {
    USB_ISTR = ~bmSOFM;
  #if USB_SOF_FRAME_NUMB > 0
    USB_FRAME_HOOK(USB_GetFrameNumb());
  #else
    USB_FRAME_HOOK(0);
  #endif
  }
#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)
  {
    USB_Endpoint_t EP;
    // find corresponding EP
    pInt32U pReg = (pInt32U)&USB_EP0R;
    pReg += IntrStatus.EP_ID;
    EP = (USB_Endpoint_t)(((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1));
    // The ISO and Double buffered endpoints have own interrupt (HIGH_INTR)
    if(!EpCnfg[EP].bDoubleBuffered)
    {
      EpCnfg[EP].AvbBuff = 1;
      if (EP & 1)
      {
        assert(EpCnfg[EP].pEpCtrl);
        EpCtrlClr_CTR_TX(EpCnfg[EP].pEpCtrl);
      }
      else
      {
        assert(EpCnfg[EP].pEpCtrl);
        EpCtrlClr_CTR_RX(EpCnfg[EP].pEpCtrl);
      }
      if(EP == CTRL_ENP_OUT)
      {
        // determinate type of packet (only for control EP)
        Boolean SetupPacket = EpCtrlGet_SETUP(EpCnfg[CTRL_ENP_OUT].pEpCtrl);
        if (SetupPacket)
        {
          EpCnfg[CTRL_ENP_IN].AvbBuff  = 1;
          // init IO to receive Setup packet
          USB_IO_Data(CTRL_ENP_IN,NULL,(Int32U)-1,NULL);
          USB_IO_Data(CTRL_ENP_OUT,UsbEp0SetupPacket.Data,sizeof(UsbSetupPacket_t),NULL);

          // reset EP IO ctrl
          if (UsbEp0SetupPacket.mRequestType.Dir == UsbDevice2Host)
          {
            USB_StatusHandler(CTRL_ENP_OUT);
          }

          USB_SetupHandler();

          if(EpCnfg[CTRL_ENP_OUT].Status == STALLED)
          {
            USB_StallCtrlEP();
          }
        }
        else
        {
          if(UsbEp0SetupPacket.mRequestType.Dir == UsbDevice2Host &&
             EpCnfg[CTRL_ENP_OUT].pFn)
          {
            ((void(*)(USB_Endpoint_t))EpCnfg[CTRL_ENP_OUT].pFn)(CTRL_ENP_OUT);
          }
          else
          {
            USB_EP_IO(EP);
          }
        }
      }
      else if (EP == CTRL_ENP_IN)
      {
        if(UsbEp0SetupPacket.mRequestType.Dir == UsbHost2Device &&
           EpCnfg[CTRL_ENP_IN].pFn)
        {
          ((void(*)(USB_Endpoint_t))EpCnfg[CTRL_ENP_IN].pFn)(CTRL_ENP_IN);
        }
        else
        {
          USB_EP_IO(EP);
        }
      }
      else
      {
        USB_EP_IO(EP);
      }
    }
  }
  USB_INTR_EXIT_HOOK();
}

⌨️ 快捷键说明

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