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

📄 stm32f_usb.c

📁 STM32F RFID通讯源代码(支持双向发送接收)
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    else if(EpState.STATTX == EP_VALID)
    {
      // Data sending in progress
      return(USB_OK);
    }
    // Get is smaller of user buffer and received data.
    SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
    WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
    pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
    for (Count = 0; Count < SizeHold; ++Count)
    {
      Temp  = *pData++;
      if (++Count < SizeHold)
      {
        Temp |= (*pData++) << 8;
      }
      *pDst++ = Temp;
    }
    // Validate buffer
    EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
    break;
  case EP_CTRL:
    if(EpState.STATTX == EP_VALID)
    {
      // Data sending in progress
      return(USB_OK);
    }
    // Get smaller of the user buffer and the received data.
    SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
    WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
    pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
    for (Count = 0; Count < SizeHold; ++Count)
    {
      Temp  = *pData++;
      if (++Count < SizeHold)
      {
        Temp |= (*pData++) << 8;
      }
      *pDst++ = Temp;
    }
    // Validate buffer
    EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
    break;
  case EP_ISO:
    if(EpState.DTOGTX)
    {
      // Tx Buffer
      pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
      // Get smaller of the user buffer and the received data.
      SizeHold = MIN(EpInfo[EndPoint].MaxSize,SizeHold);
      for (Count = 0; Count < SizeHold; ++Count)
      {
        Temp  = *pData++;
        if (++Count < SizeHold)
        {
          Temp |= (*pData++) << 8;
        }
        *pDst++ = Temp;
      }
      WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
    }
    else
    {
      // Rx Buffer
      pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
      // Get smaller of the user buffer and the received data.
      SizeHold = MIN(EpInfo[EndPoint].MaxSize,SizeHold);
      for (Count = 0; Count < SizeHold; ++Count)
      {
        Temp  = *pData++;
        if (++Count < SizeHold)
        {
          Temp |= (*pData++) << 8;
        }
        *pDst++ = Temp;
      }
      WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,SizeHold);
    }
    break;
  case EP_BULK_SING_BUFF:
    if (EpState.STATTX == EP_STALL)
    {
      // EP stalled
      return(USB_EP_STALLED);
    }
    else if(EpState.STATTX == EP_VALID)
    {
      // Data sending in progress
      return(USB_OK);
    }
    /// Get smaller of the user buffer and the received data.
    SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
    WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);

    pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
    for (Count = 0; Count < SizeHold; ++Count)
    {
      Temp  = *pData++;
      if (++Count < SizeHold)
      {
        Temp |= (*pData++) << 8;
      }
      *pDst++ = Temp;
    }
    // Validate buffer
    EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
    break;
  case EP_BULK_DOUB_BUF:
    // Double buffered
    if (EpState.STATTX == EP_STALL)
    {
      // EP stalled
      return(USB_EP_STALLED);
    }

    SizeHold = 0;
    do
    {
      // Check for a pending TX interrupt
      if(!EpCtrlGet_CTR_TX(EpInfo[EndPoint].pEpCtrl) &&
         !EpInfo[EndPoint].EpIntrFl &&
         (EpState.DTOGRX == EpCtrlGet_DTOG_TX(EpInfo[EndPoint].pEpCtrl)))
      {
        // All buffers are filled
        break;
      }

      // Get smaller of the rest of the user buffer and the received data.
      CurrSize = MIN(EpInfo[EndPoint].MaxSize,(ActSize-SizeHold));

      if(!EpState.DTOGRX)
      {
        // Tx Buffer
        pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
        WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,CurrSize);
      }
      else
      {
        // Rx Buffer
        pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
        WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,CurrSize);
      }

      for (Count = 0; Count < CurrSize; ++Count)
      {
        Temp  = *pData++;
        if (++Count < CurrSize)
        {
          Temp |= (*pData++) << 8;
        }
        *pDst++ = Temp;
      }

      EpInfo[EndPoint].EpIntrFl = 0;
      // Clear for pending TX interrupt
      EpCtrlClr_CTR_TX(EpInfo[EndPoint].pEpCtrl);
      EpCtrlToggle_DTOG_RX(EpInfo[EndPoint].pEpCtrl);
      // Update RX toggle status
      EpState.DTOGRX ^= 1;
      EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
      SizeHold += CurrSize;
    } while(SizeHold < ActSize);
    break;
  default:
    // Fatal error (require restart of the USB)
    return(USB_EP_FATAL_ERROR);
  }

  *pCount = SizeHold;
  return(USB_OK);
}

/*************************************************************************
 * Function Name: USB_EpRead
 * Parameters: USB_Endpoint_t EndPoint, pInt8U pData, pInt32U pCount
 *
 * Return: USB_ErrorCodes_t
 *
 * Description: Endpoint Read (OUT)
 *
 *************************************************************************/
USB_ErrorCodes_t USB_EpRead (USB_Endpoint_t EndPoint, pInt8U pData,
                             pInt32U pCount)
{
volatile pInt32U pSrc;
Int32U ActSize = *pCount, EpCount;
__usb_epr_bits EpState;
Int32U Temp;
Int32U CurrSize,SizeHold;
Int32U Count;

  *pCount = 0;

  if(EpInfo[EndPoint].pEpCtrl == NULL)
  {
    return(USB_EP_NOT_VALID);
  }

  EpState = *(__usb_epr_bits *)EpInfo[EndPoint].pEpCtrl;
  if(EpState.STATRX == EP_DISABLED)
  {
    return(USB_EP_FATAL_ERROR);
  }

  switch (EpInfo[EndPoint].EpType)
  {
  case EP_CTRL:
    if(EpState.STATRX == EP_VALID)
    {
      // Data is not received yet.
      return(UB_EP_SETUP_UNDERRUN);
    }
    // Get received bytes number
    EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
    // Get address of the USB packet buffer for corresponding EP
    pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
    // Get smaller of the user buffer and the received data.
    SizeHold = MIN(EpCount,ActSize);

    for(Count = 0; Count < SizeHold; ++Count)
    {
      Temp = *pSrc++;
      *pData++ = Temp;
      if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
      {
        *pData++ = Temp>>8;
      }
    }
    *pCount = SizeHold;
    if(EpCtrlGet_SETUP(EpInfo[EndPoint].pEpCtrl))
    {
      return(UB_EP_SETUP_OVERWRITE);
    }

    break;
  case EP_ISO:
    if(EpState.DTOGRX)
    {
      EpCount = ReadEpDTB_CountTx(EpInfo[EndPoint].EpSlot) & 0x3FF;
      pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
    }
    else
    {
      EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
      pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
    }
    // Get smaller of the user buffer and the received data.
    SizeHold = MIN(EpCount,ActSize);

    for(Count = 0; Count < SizeHold; ++Count)
    {
      Temp = *pSrc++;
      *pData++ = Temp;
      if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
      {
        *pData++ = Temp>>8;
      }
    }
    break;
  case EP_INTERRUPT:
    if (EpState.STATRX == EP_STALL)
    {
      return(USB_EP_STALLED);
    }
    else if (EpState.STATRX == EP_VALID)
    {
      return(UB_EP_SETUP_UNDERRUN);
    }
    EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
    pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
    // Get smaller of the user buffer and the received data.
    SizeHold = MIN(EpCount,ActSize);

    for(Count = 0; Count < SizeHold; ++Count)
    {
      Temp = *pSrc++;
      *pData++ = Temp;
      if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
      {
        *pData++ = Temp>>8;
      }
    }
    break;
  case EP_BULK_SING_BUFF:
    // Single buffer
    if (EpState.STATRX == EP_STALL)
    {
      return(USB_EP_STALLED);
    }
    else if (EpState.STATRX == EP_VALID)
    {
      return(UB_EP_SETUP_UNDERRUN);
    }
    EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
    pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
    // Get smaller of the user buffer and the received data.
    SizeHold = MIN(EpCount,ActSize);

    for(Count = 0; Count < SizeHold; ++Count)
    {
      Temp = *pSrc++;
      *pData++ = Temp;
      if(++Count <= SizeHold) // fix overwrite problem with odd number of bytes
      {
        *pData++ = Temp>>8;
      }
    }
    break;
  case EP_BULK_DOUB_BUF:
    if (EpState.STATRX == EP_STALL)
    {
      return(USB_EP_STALLED);
    }
    SizeHold = 0;
    do
    {
      if(!EpInfo[EndPoint].EpIntrFl)
      {
        // Buffers are empties
        break;
      }
      if(!EpState.DTOGTX)
      {
        EpCount = ReadEpDTB_CountTx(EpInfo[EndPoint].EpSlot) & 0x3FF;
        pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot));
      }
      else
      {
        EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot) & 0x3FF;
        pSrc = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot));
      }

      // the buffer size must be enough bigger to get all available data from
      // the EP in other case remaining data will be lost
      if(EpCount > (ActSize-SizeHold))
      {
        *pCount = SizeHold;
        return (USB_BUF_OVERFLOW);
      }
      CurrSize = EpCount;
      for(Count = 0; Count < CurrSize; ++Count)
      {
        Temp = *pSrc++;
        *pData++ = Temp;
        if(++Count <= CurrSize) // fix overwrite problem with odd number of bytes
        {
          *pData++ = Temp>>8;
        }
      }
      EpCtrlToggle_DTOG_TX(EpInfo[EndPoint].pEpCtrl);
      EpState.DTOGTX ^= 1;
      SizeHold += CurrSize;
      --EpInfo[EndPoint].EpIntrFl;
    } while(SizeHold < ActSize);
    break;
  default:
    return(USB_EP_FATAL_ERROR);
  }
  *pCount = SizeHold;
  return (USB_OK);
}

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

#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 EpPhAddr;
Int32U Status;
  IntrStatus.Status  = USB_ISTR;
  IntrStatus.Status &= USB_CNTR | 0x1F;
  // Get masked interrupt flags
  if(IntrStatus.CTR)
  {
    // find corresponding EP
    pInt32U pReg = (pInt32U)&USB_EP0R;
    pReg += IntrStatus.EP_ID;
    EpPhAddr = ((*pReg & 0xF) << 1) + (IntrStatus.DIR?0:1);
    if(EpInfo[EpPhAddr].EpType == EP_BULK_DOUB_BUF)
    {
      EpInfo[EpPhAddr].EpIntrFl = 1;
    }
    if(IntrStatus.DIR == 1)
    {
      // OUT EP
      EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
      Status = EpCtrlGet_DTOG_TX(EpInfo[EpPhAddr].pEpCtrl);
      if(Status == EpCtrlGet_DTOG_RX(EpInfo[EpPhAddr].pEpCtrl))
      {
        // The both buffers are filled
        ++EpInfo[EpPhAddr].EpIntrFl;
      }
      // Some times USB engine receive second packet
      // after resetting of interrupt flag and before testing of
      // toggle bits
      if(EpCtrlGet_CTR_RX(EpInfo[EpPhAddr].pEpCtrl))
      {
        // Now both buffers are filled.
        EpCtrlClr_CTR_RX(EpInfo[EpPhAddr].pEpCtrl);
        EpInfo[EpPhAddr].EpIntrFl = 2;
      }
      if(UsbUserFun[EpPhAddr] != NULL)
      {

⌨️ 快捷键说明

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