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

📄 stm32f_usb.c

📁 STM32F RFID通讯源代码(支持双向发送接收)
💻 C
📖 第 1 页 / 共 5 页
字号:
Int32U EpCtrlGet_STAT_RX(volatile pInt32U pReg)
{
Int32U Data = *pReg &( 0x3UL << 12);
  return(Data >> 12);
}

/*************************************************************************
 * Function Name: EpCtrlSet_DTOG_RX
 * Parameters: volatile pInt32U pReg, Int32U Data
 *
 * Return: none
 *
 * Description: Set DTOG_RX bit
 *
 *************************************************************************/
void EpCtrlSet_DTOG_RX(volatile pInt32U pReg, Int32U Data)
{
  Data  = Data?(*pReg ^ (1UL<<14)):*pReg;
  Data &= ~0x3070;   // Clear the toggle bits without DTOG_RX (14)
  Data |= USB_CTRL_CLEAR_ONLY_MASK;
  *pReg = Data;
}

/*************************************************************************
 * Function Name: EpCtrlToggle_DTOG_RX
 * Parameters: volatile Int16U pReg
 *
 * Return: none
 *
 * Description: Toggle DTOG_RX bit
 *
 *************************************************************************/
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: 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)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

  // Init variables
  UsbEp0Ctrl.EpStatus.Status = UsbSetupPhase;
  UsbCoreT9Fun = NULL;
  UserCoreConfigure(NULL);
  USB_UserFuncRegistered(UserCoreConfigure,UsbUserConfigure);
  UsbSetDevState(UsbDevStatusUnknow);

  // Reset USB Engine
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB,ENABLE);
  // Init USB Clock
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB,ENABLE);
  // Release reset USB Engine
  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USB,DISABLE);
  // Enable 48MHz clock
  RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

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

  // GPIO assign to the USB engine
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, DISABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, DISABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
  RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, DISABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
  GPIO_PinRemapConfig(GPIO_Remap1_CAN,ENABLE);  // xxx
  // Configure PA11, PA12 as USB lines
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  // Configure PC11 USB connect.
  GPIO_WriteBit(GPIOC,GPIO_Pin_11,Bit_RESET);
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  // USB interrupt connect to NVIC
#if USB_HIGH_PRIORITY_EVENT > 0
  NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN_TX_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = IntrSlotHi;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
#endif // USB_HIGH_PRIORITY_EVENT > 0

  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = IntrSlotLo;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  // 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;

  // Clear USB Reset
  USB_CNTR_bit.FRES   = 0;
  // Exit from suspend
  USB_CNTR_bit.ESOFM  = 0;
  USB_CNTR_bit.RESUME = 0;
  USB_CNTR_bit.LPMODE = 0;
  USB_CNTR_bit.FSUSP  = 0;  // Must be 0
  // USB_Configure
  USB_Configure(FALSE);
  // Set Buffer table address
  USB_BTABLE = USB_OffsetOfDBT;
  // Init Packet memory table
  pPacketMemUse = NULL;
  // Endpoint Init
  USB_UserFuncRegistered((UserFunc_t)UsbCtrlEp,UsbEp0Out);
  USB_UserFuncRegistered((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 + -