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

📄 usb_hw.c

📁 最新版IAR FOR ARM(EWARM)5.11中的代码例子
💻 C
📖 第 1 页 / 共 4 页
字号:
    else
    {
      RxCount_t RxCount = {0};
      // OUT EP
      // Disable EP
      EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED);
      // Clear Rx toggle
      EpCtrlSet_DTOG_RX(pEpCtrlBaseAddr,0);
      // Clear Correct Transfer for reception flag
      EpCtrlClr_CTR_RX(pEpCtrlBaseAddr);
      // Update EP description table
      MaxPacketSizeTmp = pEP_Desc->wMaxPacketSize;
      RxCount.BlSizeField = (MaxPacketSizeTmp > 62);
      RxCount.NubBlockField = (MaxPacketSizeTmp > 62) ? (MaxPacketSizeTmp>>5)-1:MaxPacketSizeTmp>>1;
      WriteEpDTB_AddrRx(pEP->EpSlot,Offset);
      WriteEpDTB_CountRx(pEP->EpSlot,RxCount.Count);

      // Set EP Kind & enable
      switch(pEP->EpType)
      {
      case UsbEpTransferControl:
        EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_CTRL);
        EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
        // Enable EP
        EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_NAK);
        break;
      case UsbEpTransferIsochronous:
        WriteEpDTB_CountTx(pEP->EpSlot,RxCount.Count);
        // Disable transmitting (only singe direction is possible)
        EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED);
        WriteEpDTB_AddrTx(pEP->EpSlot,Offset1);
        EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_ISO);
        EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
        // Enable EP
        EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID);
        break;
      case UsbEpTransferBulk:
        EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_BULK);
        EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,pEP->bDoubleBuffered);
        if (pEP->bDoubleBuffered)
        {
          // EP_BULK_DOUB_BUF
          // Disable transmitting (only singe direction is possible)
          EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED);
          WriteEpDTB_CountTx(pEP->EpSlot,RxCount.Count);
          WriteEpDTB_AddrTx(pEP->EpSlot,Offset1);
          EpCtrlSet_DTOG_TX(pEpCtrlBaseAddr,0);
        }
        // Enable EP
        EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID);
        break;
      case UsbEpTransferInterrupt:
        EpCtrlSet_EP_TYPE(pEpCtrlBaseAddr,EP_INTERRUPT);
        EpCtrlSet_EP_KIND(pEpCtrlBaseAddr,0);
        // Enable EP
        EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_VALID);
        break;
      default:
        assert(0);
      }
    }
  }
  else
  {
    if (EpCnfg[EP].pEpCtrl)
    {
      pEpCtrlBaseAddr  = (pInt32U)&USB_EP0R;
      pEpCtrlBaseAddr += EpCnfg[EP].EpSlot;

      if(EP & 1)
      {
        // Disable IN EP
        EpCtrlSet_STAT_TX(pEpCtrlBaseAddr,EP_DISABLED);
        // Clear Correct Transfer for reception flag
        EpCtrlClr_CTR_TX(pEpCtrlBaseAddr);
      }
      else
      {
        // Disable OUT EP
        EpCtrlSet_STAT_RX(pEpCtrlBaseAddr,EP_DISABLED);
        // Clear Correct Transfer for reception flag
        EpCtrlClr_CTR_RX(pEpCtrlBaseAddr);
      }
      // release buffer
      USB_ReleaseBuffer(EP);
      EpCnfg[EP].pEpCtrl = NULL;
    }
  }
  return(USB_OK);
}

/*************************************************************************
 * Function Name: USB_SetAdd
 * Parameters: Int32U DevAdd - device address between 0 - 127
 *
 * Return: none
 *
 * Description: Set device address
 *
 *************************************************************************/
void USB_SetAdd(Int32U DevAdd)
{
  USB_DADDR = DevAdd | 0x80;
}

/*************************************************************************
 * Function Name: USB_ConnectRes
 * Parameters: Boolean Conn
 *
 * Return: none
 *
 * Description: Enable Pull-Up resistor
 *
 *************************************************************************/
void USB_ConnectRes (Boolean Conn)
{
  GPIO_WriteBit(GPIOB,GPIO_Pin_1,((Conn)?Bit_RESET:Bit_SET));
}

/*************************************************************************
 * Function Name: USB_Suspend
 * Parameters: void
 *
 * Return: none
 *
 * Description: Suspend the USB engine
 *
 *************************************************************************/
static
void USB_Suspend(void)
{
  USB_CNTR_bit.FSUSP  = 1;
  USB_CNTR_bit.LPMODE = 1;
}

#if USB_REMOTE_WAKEUP != 0
/*************************************************************************
 * Function Name: USB_WakeUp
 * Parameters: none
 *
 * Return: none
 *
 * Description: Wake up Usb
 *
 *************************************************************************/
void USB_WakeUp (void)
{
  USB_Resume(USB_RESUME_SOFT_EVENT);
}
#endif // USB_REMOTE_WAKEUP != 0

/*************************************************************************
 * Function Name: USB_Resume
 * Parameters: UsbResumeEvent_t UsbResumeEvent
 *
 * Return: none
 *
 * Description: USB Resume implement
 *
 *************************************************************************/
static
void USB_Resume (UsbResumeEvent_t UsbResumeEvent)
{
Int32U LineStates;
  switch(UsbResumeEvent)
  {
  case USB_RESUME_SOF_EVENT:
    if(DlyCnt)
    {
      // Waiting 8ms (not take more than 10ms) before release signal to host
      if(--DlyCnt == 0)
      {
        USB_CNTR_bit.ESOFM  = 0;
        USB_CNTR_bit.RESUME = 0;
        USB_CNTR_bit.FSUSP  = 0;  // Must be 0
      }
    }
    break;
  case USB_RESUME_SOFT_EVENT: // resume by USER
    USB_CNTR_bit.LPMODE = 0;
    DlyCnt = USB_RESUME_DLY;
    USB_CNTR_bit.RESUME = 1;
    USB_CNTR_bit.ESOFM  = 1;
    UsbDevSuspendCallback(FALSE);
    break;
  case USB_RESUME_WAKE_UP_EVENT:  // resume by HOST
    LineStates = USB_FNR & 0xC000;
    if((LineStates == 0x8000) && (LineStates == 0x3000))
    {
      // noise return to suspend state again
      USB_Suspend();
    }
    else if(LineStates)
    {
      // wake-up
      USB_CNTR_bit.LPMODE = 0;
      USB_CNTR_bit.FSUSP  = 0;  // Must be 0
      UsbDevSuspendCallback(FALSE);
    }
    break;
  }
}

/*************************************************************************
 * Function Name: USB_GetDevStatus
 * Parameters: USB_DevStatusReqType_t Type
 *
 * Return: Boolean
 *
 * Description: Return USB device status
 *
 *************************************************************************/
Boolean USB_GetDevStatus (USB_DevStatusReqType_t Type)
{
  switch (Type)
  {
  case USB_DevConnectStatus:
    return(TRUE);
  case USB_SuspendStatus:
    return(USB_CNTR_bit.FSUSP);
  case USB_ResetStatus:
    return(USB_CNTR_bit.FRES);
  }
  return(FALSE);
}

/*************************************************************************
 * Function Name: USB_SetStallEP
 * Parameters: USB_Endpoint_t EP, Boolean Stall
 *
 * Return: USB_ErrorCodes_t
 *
 * Description: The endpoint stall/unstall
 *
 *************************************************************************/
USB_ErrorCodes_t USB_SetStallEP (USB_Endpoint_t EP, Boolean Stall)
{
  if (EpCnfg[EP].pEpCtrl == NULL)
  {
    return(USB_EP_NOT_VALID);
  }

  if(Stall)
  {
    EpCnfg[EP].Status = STALLED;
    if(EP & 1)
    {
      // IN EP
      EpCtrlSet_STAT_TX(EpCnfg[EP].pEpCtrl,EP_STALL);
      EpCnfg[EP].AvbBuff = EpCnfg[EP].bDoubleBuffered+1;
    }
    else
    {
      // OUT EP
      EpCtrlSet_STAT_RX(EpCnfg[EP].pEpCtrl,EP_STALL);
      EpCnfg[EP].AvbBuff = 0;
    }
  }
  else
  {
    EpCnfg[EP].Status = NOT_READY;
    if(EP & 1)
    {
      // IN EP
      EpCnfg[EP].AvbBuff = EpCnfg[EP].bDoubleBuffered+1;
      // reset Data Toggle bit
      if (EpCnfg[EP].bDoubleBuffered)
      {
        EpCtrlSet_DTOG_RX(EpCnfg[EP].pEpCtrl,0);
      }
      EpCtrlSet_DTOG_TX(EpCnfg[EP].pEpCtrl,0);
      EpCtrlSet_STAT_TX(EpCnfg[EP].pEpCtrl,EP_NAK);
    }
    else
    {
      // OUT EP
      EpCnfg[EP].AvbBuff = 0;
      // reset Data Toggle bit
      if (EpCnfg[EP].bDoubleBuffered)
      {
        EpCtrlSet_DTOG_TX(EpCnfg[EP].pEpCtrl,0);
      }
      EpCtrlSet_DTOG_RX(EpCnfg[EP].pEpCtrl,0);
      EpCtrlSet_STAT_RX(EpCnfg[EP].pEpCtrl,EP_VALID);
    }
  }
  return(USB_OK);
}

/*************************************************************************
 * Function Name: USB_StallCtrlEP
 * Parameters: none
 *
 * Return: none
 *
 * Description: Stall both direction of the CTRL EP
 *
 *************************************************************************/
void USB_StallCtrlEP (void)
{
  EpCnfg[CTRL_ENP_IN].AvbBuff  = EpCnfg[CTRL_ENP_IN].bDoubleBuffered + 1;
  EpCnfg[CTRL_ENP_IN].Status = STALLED;
  EpCnfg[CTRL_ENP_OUT].AvbBuff = 0;
  EpCnfg[CTRL_ENP_OUT].Status = STALLED;
  USB_SetStallEP(CTRL_ENP_IN,TRUE);
  USB_SetStallEP(CTRL_ENP_OUT,TRUE);
}

/*************************************************************************
 * Function Name: USB_GetStallEP
 * Parameters: USB_Endpoint_t EP, pBoolean pStall
 *
 * Return: USB_ErrorCodes_t
 *
 * Description: Get stall state of the endpoint
 *
 *************************************************************************/
USB_ErrorCodes_t USB_GetStallEP (USB_Endpoint_t EP, pBoolean pStall)
{
  if(EpCnfg[EP].pEpCtrl == NULL)
  {
    return(USB_EP_NOT_VALID);
  }
  *pStall = (EP & 1)?
            (EpCtrlGet_STAT_TX(EpCnfg[EP].pEpCtrl) == EP_STALL):  // IN EP
            (EpCtrlGet_STAT_RX(EpCnfg[EP].pEpCtrl) == EP_STALL);  // OUT EP
  return (USB_OK);
}

/*************************************************************************
 * Function Name: USB_EP_IO
 * Parameters: USB_Endpoint_t EndPoint
 *
 * Return: none
 *
 * Description: Endpoints IO
 *
 *************************************************************************/
void USB_EP_IO(USB_Endpoint_t EP)
{
Int32U Data, Count, CountHold;
pInt32U pDst;
pInt32U pSrc;
Boolean CurrentBuffer;
pEpCnfg_t pEP = &EpCnfg[EP];

  assert(pEP->pEpCtrl);

  if(pEP->Status != BEGIN_SERVICED &&
     pEP->Status != NO_SERVICED)
  {
    return;
  }
  if(EP & 1)
  {
    // IN
    Count = pEP->Size - pEP->Offset;

    while(pEP->AvbBuff)
    {
      if(Count == 0 && !pEP->bZeroPacket)
      {
        break;
      }

      // Set Status
      pEP->Status = BEGIN_SERVICED;
      // Get data size
      if(pEP->bZeroPacketPossible && Count == pEP->MaxSize)
      {
        pEP->bZeroPacketPossible = 0;
        pEP->bZeroPacket = 1;
      }

      CountHold = Count = MIN(Count,pEP->MaxSize);
      if(Count == 0)
      {
        pEP->bZeroPacket = 0;
      }
      Int32U Offset = pEP->Offset;
      pEP->Offset += Count;
      // Write data to SIE buffer
      CurrentBuffer = TRUE;
      switch (pEP->EpType)
      {
      case UsbEpTransferControl:
      case UsbEpTransferInterrupt:
        pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
        break;
      case UsbEpTransferBulk:
        if (!pEP->bDoubleBuffered)
        {
          pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
        }
        else
        {
          if ((CurrentBuffer = (*pEP->pEpCtrl & (1UL << 14)) == 0))  // DTOGRX
          {
            // Tx Buffer
            pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
          }
          else
          {
            // Rx Buffer
            pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
          }
        }
        break;
      case UsbEpTransferIsochronous:
        if((CurrentBuffer = (*pEP->pEpCtrl & (1UL << 6)) != 0))  // DTOGTX
        {
          // Tx Buffer
          pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrTx(pEP->EpSlot));
        }
        else
        {
          // Rx Buffer
          pDst = (pInt32U)__Offset2Addr_PackMem(ReadEpDTB_AddrRx(pEP->EpSlot));
        }
        break;
      default:
        assert(0);
        return;
      }

      while (Count)
      {
        Data = *(pEP->pBuffer+Offset++);
        if (--Count)
        {
          Data |= (Int32U)(*(pEP->pBuffer+Offset++))<<8;
          --Count;
        }
        *pDst++ = Data;
      }

⌨️ 快捷键说明

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