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

📄 lpc_usb.c

📁 包含了NXP众多的MCU的例子程序
💻 C
📖 第 1 页 / 共 2 页
字号:
}

/*************************************************************************
 * 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 proirity and then low proirity
        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 proirity and then low proirity
    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: Retunr curent 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: Retur 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 + -