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

📄 d_usb.c

📁 乐高机器人的源码,开发平台是IAR_for_AVR.
💻 C
📖 第 1 页 / 共 2 页
字号:
  UBYTE bmRequestType, bRequest;
  UWORD wValue, wIndex, wLength, wStatus;

  if ( !((*AT91C_UDP_CSR0) & AT91C_UDP_RXSETUP) )         // No setup package available
    return;
                                                          // Bytes are popped from the FIFO one by one

  bmRequestType = *AT91C_UDP_FDR0;
  bRequest      = *AT91C_UDP_FDR0;
  wValue        = ((*AT91C_UDP_FDR0) & 0xFF);
  wValue       |= ((*AT91C_UDP_FDR0) << 8);
  wIndex        = ((*AT91C_UDP_FDR0) & 0xFF);
  wIndex       |= ((*AT91C_UDP_FDR0) << 8);
  wLength       = ((*AT91C_UDP_FDR0) & 0xFF);
  wLength      |= ((*AT91C_UDP_FDR0) << 8);

  if (bmRequestType & 0x80)                               // If a DEVICE-TO-HOST request
  {
    *AT91C_UDP_CSR0 |= AT91C_UDP_DIR;                     // Enables data IN transaction in the control data stage
    while ( !((*AT91C_UDP_CSR0) & AT91C_UDP_DIR) );       // Repeat until the DIR bit is set
  }

  *AT91C_UDP_CSR0 &= ~AT91C_UDP_RXSETUP;                  // Device firmware has read the setup data in FIFO
  while ( ((*AT91C_UDP_CSR0)  & AT91C_UDP_RXSETUP)  );    // Wait until bit cleared

  // Handle supported standard device request from Table 9-3 in USB specification Rev 2.0

   switch ((bRequest << 8) | bmRequestType)
   {
      case STD_GET_DESCRIPTOR:

      RequestedData = wLength;

      if (wValue == 0x100)       // Return Device Descriptor
      {
         if (sizeof(DeviceDescriptor) > wLength)
         {
            dUsbSendViaControl(DeviceDescriptor, wLength);
         }
         else
         {
            dUsbSendViaControl(DeviceDescriptor, sizeof(DeviceDescriptor));
         }
      }
      else if (wValue == 0x200)  // Return Configuration Descriptor
      {
         if (sizeof(ConfigurationDescriptor) > wLength)
         {
			dUsbSendViaControl(ConfigurationDescriptor, wLength);
         }
         else
         {
            dUsbSendViaControl(ConfigurationDescriptor, sizeof(ConfigurationDescriptor));
         }
      }
      else if ((wValue & 0xF00) == 0x300)
      {
        switch(wValue & 0xFF)
        {
          case 0x00:
            if ((sizeof(LangIdDescriptor)) > wLength)
			{
				dUsbSendViaControl(LangIdDescriptor, wLength);
			}
            else
			{
				dUsbSendViaControl(LangIdDescriptor, sizeof(LangIdDescriptor));
			}
          break;

          case 0x01:
            if ((sizeof(SerialNumberDescriptor)) > wLength)
			{
				dUsbSendViaControl(SerialNumberDescriptor, wLength);
			}
            else
			{
				dUsbSendViaControl(SerialNumberDescriptor, sizeof(SerialNumberDescriptor));
			}
          break;

          default:
			dUsbSendStall();  // Illegal request :-(
          break;
        }
      }
      else
        dUsbSendStall();      // Illegal request :-(

      break;

    case STD_SET_ADDRESS:

        // Status IN transfer
        (*AT91C_UDP_CSR0) |= AT91C_UDP_TXPKTRDY;

        dUsbStartTimeoutTimer();

        while((*AT91C_UDP_CSR0) & AT91C_UDP_TXPKTRDY && !dUsbTimedOut());

              *AT91C_UDP_FADDR = (AT91C_UDP_FEN | wValue);            // Set device address. No check for invalid address.
                                                                      // Function endpoint enabled.
              *AT91C_UDP_GLBSTATE  = (wValue) ? AT91C_UDP_FADDEN : 0; // If Device address != 0 then flag device
                                                                      // in ADDRESS STATE
              break;

    case STD_SET_CONFIGURATION:

              CurrentConfiguration = wValue;                          // Low byte of wValue = wanted configuration
              UsbConnectionStates = USB_CONFIGURED;
              dUsbSendZeroLengthPackage();                            // Signal request processed OK

              *AT91C_UDP_GLBSTATE  = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;           // If wanted configuration != 0

              *AT91C_UDP_CSR1 = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0; // Endpoint 1 enabled and set as BULK OUT
              *AT91C_UDP_CSR2 = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)  : 0; // Endpoint 2 enabled and set as BULK IN
              *AT91C_UDP_CSR3 = (wValue) ? (AT91C_UDP_EPTYPE_INT_IN)   : 0;                   // Endpoint 3 disabled and set as INTERRUPT IN

              break;

    case STD_GET_CONFIGURATION:                                       // The actual configuration value is sent to HOST

              RequestedData = sizeof(CurrentConfiguration);

              dUsbSendViaControl((UBYTE *) &(CurrentConfiguration), sizeof(CurrentConfiguration));

              break;

    case STD_GET_STATUS_ZERO:

              wStatus = 0x01;                                         // Atmel has a 0x00, but we're not BUS-powered
              RequestedData = sizeof(wStatus);

              dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus));

              break;

    case STD_GET_STATUS_INTERFACE:                                    // Everything reset to zero (reserved)

              wStatus = 0;
              RequestedData = sizeof(wStatus);

              dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus));

              break;

    case STD_GET_STATUS_ENDPOINT:

              wStatus = 0;
              RequestedData = sizeof(wStatus);
              wIndex &= 0x0F;                                                 // Mask the endpoint #

              if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_CONFG) && (wIndex <= 3)) // If device in CONFIGURED state
              {                                                               // and ENDPOINT selected in valid range

                switch (wIndex)
                {

                  case 1: wStatus = ((*AT91C_UDP_CSR1) & AT91C_UDP_EPEDS) ? 0 : 1;  // If an endpoint is halted, the HALT
                                                                                    // feature is set to 1, else reset
                          break;

                  case 2: wStatus = ((*AT91C_UDP_CSR2) & AT91C_UDP_EPEDS) ? 0 : 1;

                          break;

                  case 3: wStatus = ((*AT91C_UDP_CSR3) & AT91C_UDP_EPEDS) ? 0 : 1;

                          break;
                  default:
                          // We'll never come here, but we'll never say never.......
                          break;
                }

                dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus));

              }

              else if (((*AT91C_UDP_GLBSTATE) & AT91C_UDP_FADDEN) && (wIndex == 0))
              {
                wStatus = ((*AT91C_UDP_CSR0) & AT91C_UDP_EPEDS) ? 0 : 1;            // Return 1 if device in ADRESSED state

                dUsbSendViaControl((UBYTE *) &wStatus, sizeof(wStatus));
              }
              else

                dUsbSendStall();                                // Illegal request :-(

              break;

    case STD_SET_FEATURE_ZERO:

              dUsbSendStall();                                  // Illegal request :-(

              break;

    case STD_SET_FEATURE_INTERFACE:

              dUsbSendZeroLengthPackage();                      // TextBook

              break;

    case STD_SET_FEATURE_ENDPOINT:

              wIndex &= 0x0F;

              if ((wValue == 0) && wIndex && (wIndex <= 3))     // Feature Selector = 0 ENDPOINT HALT and
              {                                                 // endpoint isolated and validated

                switch (wIndex)
                {

                case 1:   (*AT91C_UDP_CSR1) = 0;

                          break;

                case 2:   (*AT91C_UDP_CSR2) = 0;

                          break;

                case 3:   (*AT91C_UDP_CSR3) = 0;

                          break;

                default:
                          // We'll never come here, but we'll never say never.......
                break;

                }

                dUsbSendZeroLengthPackage();

              }
              else

                dUsbSendStall();                              // Illegal request :-(

              break;

    case STD_CLEAR_FEATURE_ZERO:

              dUsbSendStall();                                // Illegal request :-(

              break;

    case STD_CLEAR_FEATURE_INTERFACE:

              dUsbSendZeroLengthPackage();                    // No special

              break;

    case STD_CLEAR_FEATURE_ENDPOINT:

              wIndex &= 0x0F;

              if ((wValue == 0) && wIndex && (wIndex <= 3))   // Feature Selector = 0 => ENABLE A HALTED endpoint
              {                                               // and endpoint isolated and validated

                if (wIndex == 1)
                  (*AT91C_UDP_CSR1) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);  // On duty again
                else if (wIndex == 2)
                  (*AT91C_UDP_CSR2) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);   // -
                else if (wIndex == 3)
                  (*AT91C_UDP_CSR3) = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);    // -

                dUsbSendZeroLengthPackage();

              }
              else

                dUsbSendStall();				// Illegal request :-(

              break;

    default:

              dUsbSendStall();					// Illegal request :-(

              break;
    }
}

UBYTE dUsbIsConfigured(void)
{

	if (*AT91C_UDP_ISR & END_OF_BUS_RESET)        // If "End Of Bus Reset Interrupt"
	{                                             // Somebody fallen in the wire? ;-)


		*AT91C_UDP_ICR = END_OF_BUS_RESET;          // Reset "End Of Bus Reset Interrupt"
		*AT91C_UDP_ICR = SUSPEND_RESUME;            // State unknown after reset, so we better clear
		*AT91C_UDP_ICR = WAKEUP;                    // As above

		CurrentConfiguration = 0;                   // We're new and ready
		UsbConnectionStates = USB_NOT_CONFIGURED;

		*AT91C_UDP_RSTEP = 0xFFFFFFFF;              // Reset all implemented endpoints "and a few more"
		*AT91C_UDP_RSTEP = 0x0;                     // Restored as zeroes
													// Below our main crash thing, if it is missing ;-)
		CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Start the PING-PONG buffers at a known state and order

		*AT91C_UDP_FADDR = AT91C_UDP_FEN;           // Set FEN in the Function Address Register
													// USB device is able to receive and transfer data

		*AT91C_UDP_CSR0 = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);  // Configure endpoint 0
																	// AT91C_UDP_EPEDS = Endpoint enable
																	// AT91C_UDP_EPTYPE_CTRL = Endpoint type CONTROL
	}
	
	else if (*AT91C_UDP_ISR & SUSPEND_INT)
	{
		if (UsbConnectionStates == USB_CONFIGURED)
		{
			UsbConnectionStates = USB_CONFIGURED_BUT_SUSPENDED;
		}
		else
		{
			UsbConnectionStates = USB_NOT_CONFIGURED;
		}

		*AT91C_UDP_ICR = SUSPEND_INT;
		CurrentReceiveBank = AT91C_UDP_RX_DATA_BK0; // Start the PING-PONG buffers at a known state and order
	}

    else if (*AT91C_UDP_ISR & SUSPEND_RESUME)
    {
        if (UsbConnectionStates == USB_CONFIGURED_BUT_SUSPENDED)
		{
			UsbConnectionStates = USB_CONFIGURED;
		}
        else
		{
			UsbConnectionStates = USB_NOT_CONFIGURED;
		}

        *AT91C_UDP_ICR = WAKEUP;
        *AT91C_UDP_ICR = SUSPEND_RESUME;
    }
	
	else if (*AT91C_UDP_ISR &  AT91C_UDP_EPINT0)	// If "Endpoint 0 Interrupt"
	{
		*AT91C_UDP_ICR = AT91C_UDP_EPINT0;          // Reset "Endpoint 0 Interrupt"
		if (BrickNameKnown)
			dUsbEnumerate();						// Let's date & exchange "personal data"
	}
	
	if (UsbConnectionStates == USB_CONFIGURED)
	{
		return TRUE;
	}
	else
	{
		return FALSE;
	}

}


void      dUsbInsertHandle(UBYTE Handle)
{
  UBYTE   Tmp;

  Tmp = 0;
  while((UsbHandleList[Tmp] != MAX_HANDLES) && (Tmp < MAX_HANDLES))
  {
    Tmp++;
  }
  UsbHandleList[Tmp] = Handle;
}

void      dUsbRemoveHandle(UBYTE Handle)
{
  UBYTE   Tmp;

  Tmp = 0;
  while (Tmp < MAX_HANDLES)
  {
    if (Handle == UsbHandleList[Tmp])
    {
      UsbHandleList[Tmp] = MAX_HANDLES;
    }
    Tmp++;
  }
}

UWORD     dUsbGetFirstHandle(void)
{
  UWORD   RtnVal;

  UsbHandleCnt = 0;
  RtnVal = dUsbGetNextHandle();

  return(RtnVal);
}

UWORD     dUsbGetNextHandle(void)
{
  UBYTE   Tmp;
  UWORD   RtnVal;

  RtnVal = 0;
  Tmp = UsbHandleCnt;
  while((Tmp < MAX_HANDLES) && (MAX_HANDLES == UsbHandleList[Tmp]))
  {
    Tmp++;
  }
  UsbHandleCnt = Tmp + 1;

  if (Tmp < MAX_HANDLES)
  {
    RtnVal |= UsbHandleList[Tmp];
  }
  else
  {
    RtnVal = 0x8100;
  }

  return(RtnVal);
}

UWORD     dUsbCheckConnection(void)
{
  UWORD   ADValue;
  UWORD   Return;

  Return = FALSE;
  USBReadADCValue(&ADValue);

  if (ADValue > 512)
  {
    Return = TRUE;
  }
  return(Return);
}

void dUsbInit(void)
{
  UBYTE   Tmp;

  // We could come from a SAMBA session and then we need
  // to "introduce ourself in a polite way for the PNP manager
  // We will pull the carpet and start a new session by removing
  // the pull up of the D+ wire

  BrickNameKnown = FALSE;
  dUsbStartTimeoutTimer();								// Let H/W settle
  dUsbDisconnect();										// Pull the carpet
  while(!USBTimedOut);									// wait 1 mS.

  USBHwInit;											// New session

  CurrentConfiguration = 0;								// We're new born     
  UsbConnectionStates = USB_NOT_CONFIGURED;
  CurrentReceiveBank   = AT91C_UDP_RX_DATA_BK0;			// Always start from Bank 0
  RequestedData = 0;

  for(Tmp = 0; Tmp < MAX_HANDLES; Tmp++)
  {
    UsbHandleList[Tmp] = MAX_HANDLES;
  }
}

void      dUsbResetConfig(void)
{
  CurrentConfiguration = 0;								// We've lost the connection
  UsbConnectionStates = USB_NOT_CONFIGURED;
}

void dUsbExit(void)
{
//  USBExit;
}

⌨️ 快捷键说明

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