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

📄 str91x_usb.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 5 页
字号:
 *************************************************************************/
void EpCtrlToggle_DTOG_RX(volatile pInt32U pReg)
{
Int32U Data = *pReg | (1UL << 14);
  Data &= ~0x3070;   // Clear the toggle bits without DTOG_TX (14)
  Data |= USB_CTRL_CLEAR_ONLY_MASK;
  *pReg = Data;
}

/*************************************************************************
 * Function Name: EpCtrlGet_DTOG_RX
 * Parameters: volatile pInt32U pReg
 *
 * Return: Int32U
 *
 * Description: Get EP DTOG_RX bit (OUT)
 *
 *************************************************************************/
inline
Int32U EpCtrlGet_DTOG_RX(volatile pInt32U pReg)
{
  return(((*pReg & (1UL<<14))?1:0));
}

/*************************************************************************
 * Function Name: EpCtrlClr_CTR_RX
 * Parameters: volatile pInt32U pReg
 *
 * Return: none
 *
 * Description: Clear EP CTR_RX bit (OUT)
 *
 *************************************************************************/
void EpCtrlClr_CTR_RX(volatile pInt32U pReg)
{
Int32U Data = *pReg;
  Data &= ~(USB_CTRL_TOGGLE_MASK | 1UL << 15);
  Data |= 1UL << 7;   // Set TX_CTR
  *pReg = Data;
}

/*************************************************************************
 * Function Name: EpCtrlGet_CTR_RX
 * Parameters: volatile pInt32U pReg
 *
 * Return: Int32U
 *
 * Description: Get EP CTR_RX bit (OUT)
 *
 *************************************************************************/
inline
Int32U EpCtrlGet_CTR_RX(volatile pInt32U pReg)
{
  return(*pReg & (0x1UL << 15)?1:0);
}

/*************************************************************************
 * Function Name: WriteEpDTB
 * Parameters: EpSlot_t Slot, Int32U Offset, Int32U Data
 *
 * Return: none
 *
 * Description: Write to EP Buffer descriptor table
 *
 *************************************************************************/
static
void WriteEpDTB (EpSlot_t Slot, Int32U Offset, Int32U Data)
{
pInt32U pUSB_BuffDeskTbltt;
Int32U DescTableHold;
  pUSB_BuffDeskTbltt  = (pInt32U)((Int32U)__segment_begin("USB_PACKET_MEMORY")+(Int32U)USB_OffsetOfDBT);
  pUSB_BuffDeskTbltt += (sizeof(USB_BuffDeskTbl_t)/sizeof(Int32U)) * Slot;

  switch (Offset)
  {
  case 0:
    DescTableHold  = *pUSB_BuffDeskTbltt & ~0xFFFF;
    DescTableHold |= Data & 0xFFFF;
    *pUSB_BuffDeskTbltt = DescTableHold;
    break;
  case 2:
    DescTableHold  = *pUSB_BuffDeskTbltt & 0xFFFF;
    DescTableHold |= (Data & 0xFFFF) << 16;
    *pUSB_BuffDeskTbltt = DescTableHold;
    break;
  case 4:
    DescTableHold  = *(pUSB_BuffDeskTbltt+1) & ~0xFFFF;
    DescTableHold |= Data & 0xFFFF;
    *(pUSB_BuffDeskTbltt+1) = DescTableHold;
    break;
  case 6:
    DescTableHold  = *(pUSB_BuffDeskTbltt+1) & 0xFFFF;
    DescTableHold |= (Data & 0xFFFF) << 16;
    *(pUSB_BuffDeskTbltt+1) = DescTableHold;
    break;
  }
}

/*************************************************************************
 * Function Name: USB_Init
 * Parameters: Int32U IntrSlotHi, Int32U IntrSlotLo,
 *             CommUserFpnt_t UserCoreConfigure
 *
 * Return: none
 *
 * Description: Init USB
 *
 *************************************************************************/
void USB_Init(Int32U IntrSlotHi, Int32U IntrSlotLo,
              CommUserFpnt_t UserCoreConfigure)
{
  // Init variables
  UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
  UsbCoreT9Fun = NULL;
  UserCoreConfigure(NULL);
  USB_UserFuncRegistering(UserCoreConfigure,UsbUserConfigure);
  UsbSetDevState(UsbDevStatusUnknow);

  // Reset USB Engine
  SCU_AHBPeriphReset(__USB,ENABLE);
  // Init USB Clock
  SCU_AHBPeriphClockConfig(__USB48M,DISABLE);
  SCU_AHBPeriphClockConfig(__USB,ENABLE);
  // Release reset USB Engine
  SCU_AHBPeriphReset(__USB,DISABLE);

#if USB_CONN_CTRL > 0
GPIO_InitTypeDef  GPIO_InitStructureConnRes;
  // Enable GPIO clocks
  SCU_APBPeriphClockConfig(__GPIO7, ENABLE);
  // Release GPIO reset
  SCU_APBPeriphReset(__GPIO7, DISABLE);

  GPIO_InitStructureConnRes.GPIO_Direction = GPIO_PinOutput;
  GPIO_InitStructureConnRes.GPIO_Type = GPIO_Type_PushPull;
  GPIO_InitStructureConnRes.GPIO_IPConnected = GPIO_IPConnected_Disable;
  GPIO_InitStructureConnRes.GPIO_Alternate = GPIO_OutputAlt1;
  GPIO_InitStructureConnRes.GPIO_Pin = GPIO_Pin_0;
  GPIO_Init(GPIO7, &GPIO_InitStructureConnRes);
#endif // USB_CONN_CTRL > 0

  // Enable 48MHz clock
#if USB_EXT_CLK > 0
GPIO_InitTypeDef  GPIO_InitStructureExClk;
  // Enable GPIO clocks
  SCU_APBPeriphClockConfig(__GPIO2, ENABLE);
  // Release GPIO reset
  SCU_APBPeriphReset(__GPIO2, DISABLE);

  GPIO_InitStructureExClk.GPIO_Direction = GPIO_PinInput;
  GPIO_InitStructureExClk.GPIO_IPConnected = GPIO_IPConnected_Enable;
  GPIO_InitStructureExClk.GPIO_Alternate = GPIO_InputAlt1;
  GPIO_InitStructureExClk.GPIO_Pin = GPIO_Pin_0;
  GPIO_Init(GPIO2, &GPIO_InitStructureExClk);

  SCU_USBCLKConfig(SCU_USBCLK_EXT);
#else
  if(SCU_GetMCLKFreqValue() > 48000)
  {
    SCU_USBCLKConfig(SCU_USBCLK_MCLK2);
  }
  else
  {
    SCU_USBCLKConfig(SCU_USBCLK_MCLK);
  }
#endif // USB_EXT_CLK > 0

  // Force USB Reset &  Disable USB interrupts
  USB_CNTR = 1;

  SCU_AHBPeriphClockConfig(__USB48M,ENABLE);

  // USB interrupt connect to VIC
#if USB_HIGH_PRIORITY_EVENT > 0
  VIC_Config(USBHP_ITLine, VIC_IRQ, IntrSlotHi);
  VIC_ITCmd(USBHP_ITLine, ENABLE);
#endif // USB_HIGH_PRIORITY_EVENT > 0

  VIC_Config(USBLP_ITLine, VIC_IRQ, IntrSlotLo);
  VIC_ITCmd(USBLP_ITLine, ENABLE);

  // Disconnect device
  USB_ConnectRes(FALSE);
  // Init controls endpoints
  USB_HwReset();
  // Clear spurious pending interrupt
  USB_ISTR = 0;
  // Enable Device interrupts
  USB_CNTR = bmCTRM | bmRESETM | bmSUSPM | bmWKUPM |
         (USB_SOF_EVENT   ? bmSOFM  : 0) |
         (USB_ERROR_EVENT ? bmERRM  : 0) |
         ( USB_DOVR_EVENT ? bmDOVRM : 0) ;
}

/*************************************************************************
 * Function Name: USB_HwReset
 * Parameters: none
 *
 * Return: none
 *
 * Description: Reset Usb engine
 *
 *************************************************************************/
void USB_HwReset (void)
{
Int32U Count;

  for(Count = 0; Count < ENP_MAX_NUMB; Count++)
  {
    EpInfo[Count].pEpCtrl = NULL;
  }

  // Free entire USB packet memory
  for (Count = 0; Count < EP_MAX_SLOTS*2; Count++)
  {
    PacketMemBuff[Count].Size = 0;
  }

  // Resume delay counter
  DlyCnt = 0;

  // Filter disabled
  // Clear USB Reset
  USB_CNTR_bit.FRES   = 0;
  // Exit from suspend
  USB_CNTR_bit.ESOFM  = 0;
  USB_CNTR_bit.RESUME = 0;
  USB_CNTR_bit.LP_MODE = 0;
  USB_CNTR_bit.FSUSP  = 0;  // Must be 0
  // USB_Configure
  USB_Configure(FALSE);
  // Set Buffer table address
  USB_BTABLE = USB_OffsetOfDBT;
  pUSB_BuffDeskTbl = (pInt16U)((Int32U)__segment_begin("USB_PACKET_MEMORY") + USB_OffsetOfDBT);
  // Init Packet memory table
  pPacketMemUse = NULL;
  // Endpoint Init
  USB_UserFuncRegistering((UserFunc_t)UsbCtrlEp,UsbEp0Out);
  USB_UserFuncRegistering((UserFunc_t)UsbCtrlEp,UsbEp0In);
  USB_RealizeEp(CTRL_ENP_IN,Ep0MaxSize,EP_CTRL,EP_SLOT0);
  // Set address 0
  USB_SetDefAdd();
}

/*************************************************************************
 * Function Name: UsbMalloc
 * Parameters: none
 *
 * Return: void *
 *
 * Description: Return address of free element of the PacketMemBuff massive
 *
 *************************************************************************/
static
void * UsbMalloc(void)
{
Int32U Count;
  for (Count = 0; Count < EP_MAX_SLOTS*2; Count++)
  {
    if (PacketMemBuff[Count].Size == 0)
    {
      return(&PacketMemBuff[Count]);
    }
  }
  return(NULL);
}

/*************************************************************************
 * Function Name: UsbFree
 * Parameters: pPacketMemUse_t pPntr
 *
 * Return: none
 *
 * Description: Free element of the PacketMemBuff massive
 *
 *************************************************************************/
inline static
void UsbFree(pPacketMemUse_t pPntr)
{
  pPntr->Size = 0;
}

/*************************************************************************
 * Function Name: USB_AllocateBuffer
 * Parameters: pInt16U pOffset,Int32U PacketSize,
 *             USB_Endpoint_t EndPoint
 *
 * Return: Boolean
 *
 * Description: Allocate a new buffer
 *
 *************************************************************************/
static
Boolean USB_AllocateBuffer (pInt16U pOffset,pInt32U pPacketSize,
                            USB_Endpoint_t EndPoint)
{
pPacketMemUse_t  pPacketMem = pPacketMemUse, pPacketMemNext, pPacketMemUseNew;
//Int32U MaxPacketSize = *pPacketSize+4;  // for CRC
Int32U MaxPacketSize = *pPacketSize;
  if(MaxPacketSize > 62)
  {
    // coarse-granularity size alignment by 32
    MaxPacketSize +=  (32-1);
    MaxPacketSize &= ~(32-1);
  }
  else
  {
    // fine-granularity size alignment by 2
    MaxPacketSize +=  (2-1);
    MaxPacketSize &= ~(2-1);
  }
  *pOffset = 0;
  // Finding free memory block from the USB packet memory
  while(pPacketMem != NULL)
  {
    *pOffset = pPacketMem->Start + pPacketMem->Size;
    // Offset alignment by 4
    *pOffset += (4-1);
    *pOffset &= ~(4-1);
    pPacketMemNext = pPacketMem->pNext;
    if((pPacketMem->pNext == NULL) ||
       (pPacketMemNext->Start >= *pOffset + MaxPacketSize))
    {
      break;
    }
    pPacketMem = pPacketMem->pNext;
  }
  // Is block find?
  if((*pOffset + MaxPacketSize) >=
     (((Int32U)__segment_size("USB_PACKET_MEMORY") -
       sizeof(USB_BuffDeskTbl_t) * (MaxIndOfRealizeEp+1))&~7))
  {
    // Not enough space in the USB packet memory
    return(FALSE);
  }

  pPacketMemUseNew = UsbMalloc();
  if(pPacketMemUseNew == NULL)
  {
    // too many point are realized
    return(FALSE);
  }
  if(pPacketMemUse == NULL)
  {
    pPacketMemUse = pPacketMemUseNew;
    pPacketMemUse->pNext = NULL;
  }
  else
  {
    pPacketMemUseNew->pNext  = pPacketMem->pNext;
    pPacketMem->pNext        = pPacketMemUseNew;
  }
  pPacketMemUseNew->RpAddr = EndPoint;
  pPacketMemUseNew->Start  = *pOffset;
  pPacketMemUseNew->Size   = MaxPacketSize;
  *pPacketSize = MaxPacketSize;
  return(TRUE);
}

/*************************************************************************
 * Function Name: USB_ReleaseBuffer
 * Parameters: USB_Endpoint_t EndPoint
 *
 * Return: none
 *
 * Description: Release the buffer/s
 *
 *************************************************************************/
static
void USB_ReleaseBuffer (USB_Endpoint_t EndPoint)
{
pPacketMemUse_t  pPacketMem, pPacketMemPrev;
  pPacketMem = pPacketMemUse;
  while(pPacketMem != NULL)
  {
    if(pPacketMem->RpAddr == EndPoint)
    {
      pPacketMemPrev->pNext = pPacketMem->pNext;
      UsbFree(pPacketMem);
      pPacketMem = pPacketMemPrev->pNext;
    }
    else
    {
      pPacketMemPrev = pPacketMem;
      pPacketMem = pPacketMem->pNext;
    }
    if (pPacketMem == NULL)
    {
      break;
    }
  }
}

/*************************************************************************
 * Function Name: USB_RealizeEp
 * Parameters: USB_Endpoint_t EndPoint, Int32U MaxPacketSize,
 *             EpType_t EpKind, EpSlot_t EpSlot,
 *
 * Return: USB_ErrorCodes_t
 *
 * Description: Enable or disable endpoint
 *
 *************************************************************************/
USB_ErrorCodes_t USB_RealizeEp( USB_Endpoint_t EndPoint, Int32U MaxPacketSize,
                                EpType_t EpType, EpSlot_t EpSlot)
{
volatile pInt32U pEpCtrlBaseAddr;
Int16U Offset,Offset1;
Int32U MaxPacketSizeTmp;
  if (MaxPacketSize)
  {
    // Allocate packet memory for EP buffer/s
    // calculate actual size only for the OUT EPs
    MaxPacketSizeTmp = MaxPacketSize;
    if(!USB_AllocateBuffer(&Offset,&MaxPacketSizeTmp,EndPoint))
    {
      return(USB_MEMORY_FULL);
    }
    if((EpType == EP_ISO) || (EpType == EP_BULK_DOUB_BUF) || (EpType == EP_CTRL))
    {
      // Allocate packet second buffer
      MaxPacketSizeTmp = MaxPacketSize;
      if(!USB_AllocateBuffer(&Offset1,&MaxPacketSizeTmp,EndPoint))
      {
        // release buffer
        USB_ReleaseBuffer(EndPoint);
        return(USB_MEMORY_FULL);
      }
    }
    pEpCtrlBaseAddr  = (pInt32U)&USB_EP0R;
    pEpCtrlBaseAddr += EpSlot;
    // Set Ep Address
    EpCtrlSet_EA(pEpCtrlBaseAddr,EndPoint >> 1);

    if(EpType == EP_CTRL)
    {
      EndPoint |= 1;
    }
  sec_pass: // only for control EP, because this type realize both directions
    EpInfo[EndPoint].EpType  = EpType;
    EpInfo[EndPoint].pEpCtrl = pEpCtrlBaseAddr;
    EpInfo[EndPoint].EpSlot  = EpSlot;
    EpInfo[EndPoint].MaxSize = MaxPacketSize;
    if(EndPoint & 1)
    {
      // IN EP
      // Disable EP
      EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED);
      // Clear Tx toggle
      EpCtrlSet_DTOG_TX(pEpCtrlBaseAddr,0);
      // Clear Correct Transfer for transmission flag
      EpCtrlClr_CTR_TX(pEpCtrlBaseAddr);
      // Update EP description table
      WriteEpDTB_AddrTx(EpSlot,Offset);
      WriteEpDTB_CountTx(EpSlot,0);
      // Set EP Kind & enable
      switch(EpType)
      {
      case EP_BULK_SING_BUFF:
        EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_BULK_SING_BUFF);
        EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
        // Enable EP
        EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_NAK);
        break;
      case EP_CTRL:
        EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_CTRL);
        EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
        // Enable EP
        EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_NAK);
        // Realize OUT direction
        EndPoint &= ~1;
        Offset = Offset1;
        goto sec_pass;
      case EP_ISO:

⌨️ 快捷键说明

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