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

📄 lpc_usb.c

📁 NXP LPC系列AMR7的开发程序源码(LCD
💻 C
📖 第 1 页 / 共 2 页
字号:
  return(FALSE);
}

/*************************************************************************
 * Function Name: USB_SetStallEP
 * Parameters: USB_Endpoint_t EndPoint, Boolean Stall
 *
 * Return: none
 *
 * Description: The endpoint stall/unstall
 *
 *************************************************************************/
void USB_SetStallEP (USB_Endpoint_t EndPoint, Boolean Stall)
{
  USB_Cmd(CMD_USB_SET_EP_STAT | EndPoint, (Stall ? bmUSB_EpStall : 0));
}

/*************************************************************************
 * Function Name: USB_GetStallEP
 * Parameters: USB_Endpoint_t EndPoint
 *
 * Return: Boolean
 *
 * Description: Get stall state of the endpoint
 *
 *************************************************************************/
Boolean USB_GetStallEP (USB_Endpoint_t EndPoint)
{
  return ((USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0) & bmUSB_EpStallStatus) != 0);
}

/*************************************************************************
 * Function Name: USB_EpWrite
 * Parameters: USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count
 *
 * Return: none
 *
 * Description: Endpoint Write (IN)
 *
 *************************************************************************/
void USB_EpWrite (USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count)
{
  // Convert EP physical address to logical and set write enable bit
  USBCTRL = ((EndPoint << 1) & 0x3C) | bmUSB_CtrlWrEna;

  // Get data size
  TPKTLEN = Count;
  // Write data to SIE buffer
  if(Count)
  {
    do
    {
      TDATA = *pData++;
    }
    while (USBCTRL_bit.WR_EN);
  }
  else
  {
    do
    {
      TDATA = 0;
    }
    while (USBCTRL_bit.WR_EN);
  }

  USBCTRL = 0;

  USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0);
  USB_Cmd(CMD_USB_VAL_BUF, 0);

}

/*************************************************************************
 * Function Name: USB_EpRead
 * Parameters: USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count
 *
 * Return: Int32
 *
 * Description: Endpoint Read (OUT)
 *
 *************************************************************************/
Int32U USB_EpRead (USB_Endpoint_t EndPoint, Int32U * pData, Int32U Count)
{
  // Convert EP physical address to logical and set read enable bit
  USBCTRL = ((EndPoint << 1) & 0x3C) | bmUSB_CtrlRdEna;
  while (RCVEPKTLEN_bit.PKT_RDY == 0);
  // Get data size
  Count = RCVEPKTLEN_bit.PKT_LNGTH;
  // Read data from SIE buffer
  while (RCVEPKTLEN_bit.DV)
  {
    *pData++ = RCVEDATA;
  }

  USBCTRL = 0;

  USB_Cmd(CMD_USB_SEL_EP | EndPoint, 0);
  if(USB_Cmd(CMD_USB_CLR_BUF, 0) & bmUSB_PacketOverWritten)
  {
    Count |= 0x80000000;
  }
  return (Count);
}

/*************************************************************************
 * Function Name: USB_ISR
 * Parameters: none
 *
 * Return: none
 *
 * Description: USB interrupt subroutine
 *
 *************************************************************************/
void USB_ISR (void)
{
Int32U EpIntr,Val,EpIntHold;
UsbDevIntrStat_t UsbDevIntrSt = {DEVINTS};

#if USB_DMA > 0
  if (USBINTS & 3)
  {
#endif
  #if USB_HIGH_PRIORITY_EVENT > 0
    // Fast EP interrupt
    if(UsbDevIntrSt.Fast)
    {
      DEVINTCLR = bmUSB_FastInterrupt;
      if(UsbUserFun[UsbHighPrioIntrEvent] != NULL)
      {
        UsbUserFun[UsbHighPrioIntrEvent]((void *)0);
      }
      // Clear Fast EP interrupt
    }
  #endif

  #if USB_ERROR_EVENT > 0
    // USB engine error interrupt
    if(UsbDevIntrSt.Error)
    {
      DEVINTCLR = bmUSB_ErrorInterrupt;
      Val = USB_Cmd(CMD_USB_RD_ERROR_STAT,0);
      if(UsbUserFun[UsbErrorEvent] != NULL)
      {
        UsbUserFun[UsbErrorEvent]((void *)Val);
      }
    }
  #endif

  #if USB_SOF_EVENT > 0
    // Frame interrupt
    if(UsbDevIntrSt.Frame)
    {
      DEVINTCLR = bmUSB_FrameInterrupt;
//      Val = USB_Cmd(CMD_USB_RD_FRAME_NUMB,0);
      if(UsbUserFun[UsbSofEvent] != NULL)
      {
        UsbUserFun[UsbSofEvent]((void *)Val);
      }
    }
  #endif

    // Device Status interrupt
    if(UsbDevIntrSt.Status)
    {
      // Clear Device status interrupt
      DEVINTCLR = bmUSB_DevStatusInterrupt;
      // Get device status
      USB_DevStatus.Data = USB_Cmd(CMD_USB_GET_DEV_STAT,0);
      // Device connection status
      if(USB_DevStatus.ConnectChange)
      {
        if(UsbUserFun[UsbConnectEvent] != NULL)
        {
          UsbUserFun[UsbConnectEvent]((void *)USB_DevStatus.Connect);
        }
      }
      // Device suspend status
      if(USB_DevStatus.SuspendChange)
      {
        if(UsbUserFun[UsbSuspendEvent] != NULL)
        {
          UsbUserFun[UsbSuspendEvent]((void *)USB_DevStatus.Suspend);
        }
      }
      // Device reset
      if(USB_DevStatus.Reset)
      {
        USB_HwReset();
        if(UsbUserFun[UsbResetEvent] != NULL)
        {
          UsbUserFun[UsbResetEvent](NULL);
        }
      }
    }

    // Slow EP interrupt
    if(UsbDevIntrSt.Slow)
    {
      // Clear Slow EP interrupt
      DEVINTCLR = bmUSB_SlowInterrupt;
      do
      {
        EpIntr = ENDPINTS;
        // First Software High priority and then low priority
        Int32U USB_EpSoftPrioHold = USB_EpSoftPrio;
        for (Int32U i = 2; i; --i, USB_EpSoftPrioHold ^= 0xFFFFFFFF)
        {
        Int32U EpIntrCurrPrio = EpIntr & USB_EpSoftPrioHold;
          // Output ctrl EP
          if(EpIntrCurrPrio & 1)
          {
            Val = USB_EpIntrClr(CTRL_ENP_OUT);
            if(UsbUserFun[UsbEp0Out] != NULL)
            {
              if(Val & bmUSB_EpSetupPacket)
              {
                UsbUserFun[UsbEp0Out]((void *)UsbSetupPacket);
              }
              else
              {
                UsbUserFun[UsbEp0Out]((void *)UsbDataOutPacket);
              }
            }
            break;
          }
          // All other endpoints
          for(Val = 1,EpIntHold = EpIntrCurrPrio >> 1; EpIntHold; ++Val,EpIntHold >>= 1)
          {
            if(EpIntHold & 1)
            {
              USB_EpIntrClr((USB_Endpoint_t)Val);
              if(UsbUserFun[Val] != NULL)
              {
                UsbUserFun[Val]((void *)((Val&1)?UsbDataInPacket:UsbDataOutPacket));
              }
              break;
            }
          }
        }
      }
      while(EpIntr);
    }
#if USB_DMA > 0
  }
  if (USBINTS_bit.USB_INT_REQ_DMA)
  {
    // First Software High priority and then low priority
    Int32U UsbDmaInt = 0,Tmp;
    Tmp = EOTINTSTAT;
    if(DMAINTEN & 1)
    {
      UsbDmaInt |= Tmp;
    }
    EOTINTCLR = Tmp;
    Tmp = NEWDDRINTSTAT;
    if(DMAINTEN & 2)
    {
      UsbDmaInt |= Tmp;
    }
    NEWDDRINTCLR = Tmp;
    Tmp = SYSERRINTSTAT;
    if(DMAINTEN & 4)
    {
      UsbDmaInt |= Tmp;
    }
    SYSERRINTCLR = Tmp;
    for (Int32U i = 2; i; --i, USB_EpSoftPrio ^= 0xFFFFFFFF)
    {
      // All endpoints without ctrl EP_In, ctrl EP_Out
      Int32U UsbDmaCurrPriorityInt = USB_EpSoftPrio & UsbDmaInt;
      for(Int32U Val = 2, EpMask = 4; UsbDmaCurrPriorityInt; ++Val,EpMask <<= 1)
      {
        Int32U EpPriorityMask = UsbDmaCurrPriorityInt & EpMask;
        if(EpPriorityMask == 0)
        {
          continue;
        }
        UsbDmaCurrPriorityInt &= ~EpMask;
        // Collect Interrupts status flags and clear interrupt flags
        if(EpPriorityMask && (UsbUserFun[Val] != NULL))
        {
          UsbUserFun[Val]((void *)UsbDmaPacket);
        }
      }
    }
  }
#endif
  VICVectAddr = 0;    // Clear interrupt in VIC.
}

/*************************************************************************
 * 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);
}

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

/*************************************************************************
 *                          U S B   D M A  P a r t                       *
 *************************************************************************/

#if USB_DMA > 0
#pragma segment="DMA_RAM"
#pragma location="DMA_RAM"
#pragma data_alignment=128
__no_init pUSB_DmaDesc_t USB_DDCA[ENP_MAX_NUMB];

#pragma location="DMA_RAM"
__no_init USB_DmaDesc_t USB_DmaDesc[DMA_DD_MAX_NUMB];

/*************************************************************************
 * Function Name: USB_DmaReset
 * Parameters:  Int32U IntrEna
 *
 * Return: none
 *
 * Description: Reset USB DMA
 *
 *************************************************************************/
void USB_DmaReset (Int32U IntrEna)
{
  // Disable All DMA interrupts
  DMAINTEN = 0;
  // DMA Disable
  EPDMADIS      = 0xFFFFFFFF;
  // DMA Request clear
  DMARQSTCLR    = 0xFFFFFFFF;
  // End of Transfer Interrupt Clear
  EOTINTCLR     = 0xFFFFFFFF;
  // New DD Request Interrupt Clear
  NEWDDRINTCLR  = 0xFFFFFFFF;
  // System Error Interrupt Clear
  SYSERRINTCLR  = 0xFFFFFFFF;
  for(Int32U i = 0; i < ENP_MAX_NUMB; ++i)
  {
    USB_DDCA[i] = NULL;
  }
  // Set USB UDCA Head register
  UDCAHEAD = (Int32U)&USB_DDCA;
  // Enable DMA interrupts
  DMAINTEN = IntrEna;
}

/*************************************************************************
 * Function Name: USB_DmaInitTransfer
 * Parameters: USB_Endpoint_t EndPoint, Int32U DmaDescInd,
 *             pInt32U pData, Int32U EpMaxSize, Int32U Size
 *             pDmaIsoPacket_t pDmaIsoPacket,  Boolean EpTransferType
 *
 * Return: UsbDmaStateCode_t
 *
 * Description: Init Transfer by DMA
 *
 *************************************************************************/
UsbDmaStateCode_t USB_DmaInitTransfer (USB_Endpoint_t EndPoint,
          Int32U DmaDescInd, pInt32U pData, Int32U EpMaxSize, Int32U Size,
          pDmaIsoPacket_t pDmaIsoPacket, Boolean EpTransferType)
{
Int32U EpReg;

  if ((EndPoint == CTRL_ENP_OUT) || (EndPoint == CTRL_ENP_IN))
  {
    return(UsbDmaParametersError);
  }
  if (USB_DmaDesc[DmaDescInd].Status == UsbDmaBeingServiced)
  {
    return(UsbDmaBeingServiced);
  }

  // Init DMA Descriptor
  USB_DmaDesc[DmaDescInd].pNextDD        = NULL;
  USB_DmaDesc[DmaDescInd].NextDDValid    = FALSE;
  USB_DmaDesc[DmaDescInd].pDmaIsoPacket  = pDmaIsoPacket;
  USB_DmaDesc[DmaDescInd].DmaMode        = UsbDmaNormalMode;
  USB_DmaDesc[DmaDescInd].Isochronous    = EpTransferType;
  USB_DmaDesc[DmaDescInd].pDmaBuffer     = pData;
  USB_DmaDesc[DmaDescInd].DmaBufferLegtn = Size;
  USB_DmaDesc[DmaDescInd].MaxPacketSize  = EpMaxSize;
  USB_DmaDesc[DmaDescInd].Status         = UsbDmaNoServiced;

  // Set DD
  USB_DDCA[EndPoint] = &USB_DmaDesc[DmaDescInd];

  // Enable DMA Transfer
  EPDMAEN = 1 << EndPoint;

  // Check state of IN/OUT Ep buffer
  EpReg = USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);

  if( ((EndPoint & 1) && !(EpReg & 0x60)) ||
     (!(EndPoint & 1) && ((EpReg & 0x60) == 0x60)))
  {
    if((USB_DmaDesc[DmaDescInd].DdState != UsbDmaBeingServiced))
    {
      // Retrigger DMA Transfer
      DMARQSTSET = 1 << EndPoint;
    }
  }

  return(UsbDmaNoServiced);
}

/*************************************************************************
 * Function Name: USB_DmaGetDesc
 * Parameters: Int32U DmaDescInd
 *
 * Return: pUSB_DmaDesc_t
 *
 * Description: Return pointer to DMA descriptor
 *
 *************************************************************************/
pUSB_DmaDesc_t USB_DmaGetDesc (Int32U DmaDescInd)
{
  return(&USB_DmaDesc[DmaDescInd]);
}

/*************************************************************************
 * Function Name: USB_DmaDisable
 * Parameters: USB_Endpoint_t EndPoint
 *
 * Return: none
 *
 * Description: Disable DMA transfer for the EP
 *
 *************************************************************************/
void USB_DmaDisable (USB_Endpoint_t EndPoint)
{
  EPDMADIS = 1 << EndPoint;
}

/*************************************************************************
 * Function Name: USB_DmaRestattTransfer
 * Parameters: USB_Endpoint_t EndPoint, Int32U DmaDescInd,
 *             pInt32U pData, Int32U EpMaxSize, Int32U Size
 *             pDmaIsoPacket_t pDmaIsoPacket,  Boolean EpTransferType
 *
 * Return: none
 *
 * Description: Restart DMA Transfer
 *
 *************************************************************************/
void USB_DmaRestattTransfer (USB_Endpoint_t EndPoint,Int32U DmaDescInd)
{
  // Init DD DMA status
  USB_DmaDesc[DmaDescInd].Status = UsbDmaNoServiced;
  // Enable DMA Transfer
  EPDMAEN = 1 << EndPoint;
  // Check state of IN/OUT Ep buffer
  Int32U EpReg = USB_Cmd(CMD_USB_SEL_EP | EndPoint,0);
  if(!(EndPoint & 1) && ((EpReg & 0x60) == 0x60))
  {
    // Retrigger DMA Transfer
    DMARQSTSET = 1 << EndPoint;
  }
  else if ((EndPoint & 1) && !(EpReg & 0x60))
  {
    // Retrigger DMA Transfer
    DMARQSTSET = 1 << EndPoint;   // 

⌨️ 快捷键说明

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