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

📄 str91x_usb.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    // Validate buffer
    EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
    break;
  case EP_CTRL:
    if(EpState.STAT_TX == 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)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
                     (Int32U)__segment_begin("USB_PACKET_MEMORY"));
    for (Count = 0; Count < SizeHold; ++Count)
    {
      Temp  = *pData++;
      if (++Count < SizeHold)
      {
        Temp |= (*pData++) << 8;
        if (++Count < SizeHold)
        {
          Temp |= (*pData++) << 16;
          if (++Count < SizeHold)
          {
            Temp |= (*pData++) << 24;
          }
        }
      }
      *pDst++ = Temp;
    }
    // Validate buffer
    EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
    break;
  case EP_ISO:
    if(EpState.DTOG_TX)
    {
      // Tx Buffer
      pDst = (pInt32U)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
                      (Int32U)__segment_begin("USB_PACKET_MEMORY"));
      // Get smaller of the user buffer and the received data.
      SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
      for (Count = 0; Count < SizeHold; ++Count)
      {
        Temp  = *pData++;
        if (++Count < SizeHold)
        {
          Temp |= (*pData++) << 8;
          if (++Count < SizeHold)
          {
            Temp |= (*pData++) << 16;
            if (++Count < SizeHold)
            {
              Temp |= (*pData++) << 24;
            }
          }
        }
        *pDst++ = Temp;
      }
      WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,SizeHold);
    }
    else
    {
      // Rx Buffer
      pDst = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot) +\
                      (Int32U)__segment_begin("USB_PACKET_MEMORY"));
      // Get smaller of the user buffer and the received data.
      SizeHold = MIN(EpInfo[EndPoint].MaxSize,ActSize);
      for (Count = 0; Count < SizeHold; ++Count)
      {
        Temp  = *pData++;
        if (++Count < SizeHold)
        {
          Temp |= (*pData++) << 8;
          if (++Count < SizeHold)
          {
            Temp |= (*pData++) << 16;
            if (++Count < SizeHold)
            {
              Temp |= (*pData++) << 24;
            }
          }
        }
        *pDst++ = Temp;
      }
      WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,SizeHold);
    }
    break;
  case EP_BULK_SING_BUFF:
    if (EpState.STAT_TX == EP_STALL)
    {
      // EP stalled
      return(USB_EP_STALLED);
    }
    else if(EpState.STAT_TX == 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)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
                     (Int32U)__segment_begin("USB_PACKET_MEMORY"));

    for (Count = 0; Count < SizeHold; ++Count)
    {
      Temp  = *pData++;
      if (++Count < SizeHold)
      {
        Temp |= (*pData++) << 8;
        if (++Count < SizeHold)
        {
          Temp |= (*pData++) << 16;
          if (++Count < SizeHold)
          {
            Temp |= (*pData++) << 24;
          }
        }
      }
      *pDst++ = Temp;
    }
    // Validate buffer
    EpCtrlSet_STAT_TX(EpInfo[EndPoint].pEpCtrl,EP_VALID);
    break;
  case EP_BULK_DOUB_BUF:
    // Double buffered
    if (EpState.STAT_TX == 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.DTOG_RX == 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.DTOG_RX)
      {
        // Tx Buffer
        pDst = (pInt32U)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot) +\
                         (Int32U)__segment_begin("USB_PACKET_MEMORY"));
        WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,CurrSize);
      }
      else
      {
        // Rx Buffer
        pDst = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot) +\
                         (Int32U)__segment_begin("USB_PACKET_MEMORY"));
        WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,CurrSize);
      }

      for (Count = 0; Count < CurrSize; ++Count)
      {
        Temp  = *pData++;
        if (++Count < CurrSize)
        {
          Temp |= (*pData++) << 8;
          if (++Count < CurrSize)
          {
            Temp |= (*pData++) << 16;
            if (++Count < CurrSize)
            {
              Temp |= (*pData++) << 24;
            }
          }
        }
        *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.DTOG_RX ^= 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.STAT_RX == EP_DISABLED)
  {
    return(USB_EP_FATAL_ERROR);
  }

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

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

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

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

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

    for(Count = 0; Count < SizeHold; ++Count)
    {
      Temp = *pSrc++;
      *pData++ = Temp;
      // fix overwrite problem with odd number of bytes
      if(++Count <= SizeHold)
      {
        *pData++ = Temp>>8;
        if(++Count <= SizeHold)
        {
          *pData++ = Temp>>16;
          if(++Count <= SizeHold)
          {
            *pData++ = Temp>>24;
          }
        }
      }
    }
    break;
  case EP_BULK_DOUB_BUF:
    if (EpState.STAT_RX == EP_STALL)
    {
      return(USB_EP_STALLED);
    }
    SizeHold = 0;
    do
    {
      if(!EpInfo[EndPoint].EpIntrFl)
      {
        // Buffers are empties
        break;
      }
      if(!EpState.DTOG_TX)
      {
        EpCount = ReadEpDTB_CountTx(EpInfo[EndPoint].EpSlot);
        WriteEpDTB_CountTx(EpInfo[EndPoint].EpSlot,EpCount & ~0x3FF);
        EpCount &= 0x3FF;
        pSrc = (pInt32U)(ReadEpDTB_AddrTx(EpInfo[EndPoint].EpSlot)+\
                (Int32U)__segment_begin("USB_PACKET_MEMORY"));
      }
      else
      {
        EpCount = ReadEpDTB_CountRx(EpInfo[EndPoint].EpSlot);
        WriteEpDTB_CountRx(EpInfo[EndPoint].EpSlot,EpCount & ~0x3FF);
        EpCount &= 0x3FF;
        pSrc = (pInt32U)(ReadEpDTB_AddrRx(EpInfo[EndPoint].EpSlot)+\
                (Int32U)__segment_begin("USB_PACKET_MEMORY"));
      }
      // Get smaller of the rest of the user buffer and the received data.
      CurrSize = MIN(EpCount,(ActSize-SizeHold));
      for(Count = 0; Count < CurrSize; ++Count)
      {
        Temp = *pSrc++;
        *pData++ = Temp;
        // fix overwrite problem with odd number of bytes
        if(++Count <= CurrSize)
        {
          *pData++ = Temp>>8;
          if(++Count <= CurrSize)
          {
            *pData++ = Temp>>16;
            if(++Count <= CurrSize)
            {
              *pData++ = Temp>>24;
            }
          }
        }
      }

      EpCtrlToggle_DTOG_TX(EpInfo[EndPoint].pEpCtrl);
      EpState.DTOG_TX ^= 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

⌨️ 快捷键说明

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