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

📄 usb.c

📁 运行于c51单片机上的用keil c创建的C源程序,采用PDIUSBD12接口。
💻 C
字号:

void stall_ep0(void)
{
  D12_SetEndpointStatus(0, 1);
  D12_SetEndpointStatus(1, 1);
}

void init_unconfig(void)
{
  //unsigned char i;

  D12_SetEndpointEnable(0);	/* Disable all endpoints but EPP0. */
}

void init_config(void)
{
  D12_SetEndpointEnable(1);	/* Enable  generic/iso endpoints. */
}

void single_transmit(unsigned char * buf, unsigned char len)
{
  if( len <= EP0_PACKET_SIZE) //0x10
  {
    D12_WriteEndpoint(1, len, buf);
  }
}

void code_transmit(unsigned char code * pRomData, unsigned short len)
{
  ControlData.wCount = 0;
  if(ControlData.wLength > len)
    ControlData.wLength = len;

  ControlData.pData = pRomData;
  if( ControlData.wLength >= EP0_PACKET_SIZE) //0x10
  {
    D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData);
    ControlData.wCount += EP0_PACKET_SIZE;

    DISABLE;
    B_Conrol_Stat = USB_TRANSMIT;
    ENABLE;
  }
  else 
  {
    D12_WriteEndpoint(1, ControlData.wLength, pRomData);
    ControlData.wCount += ControlData.wLength;
    DISABLE;
    B_Conrol_Stat = USB_IDLE;
    ENABLE;
  }
}

void get_status(void)
{
  unsigned char endp, txdat[2];
  unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
  unsigned char c;

  if (bRecipient == USB_RECIPIENT_DEVICE) 
  {
    if(B_D12_Lb & WAKEUP)
      txdat[0] = 3;
    else
      txdat[0] = 1;
    txdat[1]=0;
    single_transmit(txdat, 2);
  }
  else if (bRecipient == USB_RECIPIENT_INTERFACE) 
  {
    txdat[0]=0;
    txdat[1]=0;
    single_transmit(txdat, 2);
  } 
  else if (bRecipient == USB_RECIPIENT_ENDPOINT) 
  {
    endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
    if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
      c = D12_SelectEndpoint(endp*2 + 1);	/* Control-in */
    else
      c = D12_SelectEndpoint(endp*2);	/* Control-out */
    if(c & D12_STALL)
      txdat[0] = 1;
    else
      txdat[0] = 0;
    txdat[1] = 0;
    single_transmit(txdat, 2);
  } 
  else
    stall_ep0();
}

void clear_feature(void)
{
  unsigned char endp;
  unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;

  if((bRecipient == USB_RECIPIENT_DEVICE) && (ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)) 
  {
    DISABLE;
    B_D12_Lb &= ~WAKEUP;//define WAKEUP  2  //远程唤醒
    ENABLE;
    single_transmit(0, 0);
  }
  else if((bRecipient == USB_RECIPIENT_ENDPOINT) && (ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)) 
  {
    endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
    if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
	/* clear TX stall for IN on EPn. */
      D12_SetEndpointStatus(endp*2 + 1, 0);
    else
        /* clear RX stall for OUT on EPn. */
      D12_SetEndpointStatus(endp*2, 0);
    single_transmit(0, 0);
  } 
  else
    stall_ep0();
}

void reserved(void)
{
	stall_ep0();
}

void set_feature(void)
{
  unsigned char endp;
  unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;

  if ((bRecipient == USB_RECIPIENT_DEVICE) && (ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)) 
  {
    DISABLE;
    B_D12_Lb |= WAKEUP;
    ENABLE;
    single_transmit(0, 0);
  }
  else if ((bRecipient == USB_RECIPIENT_ENDPOINT) && (ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)) 
  {
    endp = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
    if (ControlData.DeviceRequest.wIndex & (unsigned char)USB_ENDPOINT_DIRECTION_MASK)
	/* clear TX stall for IN on EPn. */
      D12_SetEndpointStatus(endp*2 + 1, 1);
    else
	/* clear RX stall for OUT on EPn. */
    D12_SetEndpointStatus(endp*2, 1);
    single_transmit(0, 0);
  } 
  else
    stall_ep0();
}

void set_address(void)
{
  D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue & DEVICE_ADDRESS_MASK), 1);
  single_transmit(0, 0);
}

void get_descriptor(void)
{
  unsigned char bDescriptor;
  bDescriptor = (unsigned char)(ControlData.DeviceRequest.wValue >> 8);

  if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) 	//设备描述符0x1
  {
    code_transmit((unsigned char code *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
  } 
  else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) 	//配置,接口,四个端点,0端点除外  0x02
  {
    if (ControlData.DeviceRequest.wLength > CONFIG_DESCRIPTOR_LENGTH) 
       ControlData.DeviceRequest.wLength = CONFIG_DESCRIPTOR_LENGTH;
    code_transmit((unsigned char code *)&ConfigDescr, ControlData.DeviceRequest.wLength);
  } 
  else
    stall_ep0();
}

void get_configuration(void)	 //其实返回ConfigDescr.bConfigurationValue的值;这里只有一种配置
{
  unsigned char c;

  c = B_D12_Lb & CONFIGURE;

  single_transmit(&c, 1);
}

void set_configuration(void)			//配置表中是1,若要选中配置1,则发送参数1。
{
  if (ControlData.DeviceRequest.wValue == 0) 
  {
    /* put device in unconfigured state */
    single_transmit(0, 0);
    DISABLE;
    B_D12_Lb &= ~CONFIGURE;
    ENABLE;
    init_unconfig();
  } 
  else if (ControlData.DeviceRequest.wValue == 1) 
  {
    /* Configure device */
    single_transmit(0, 0);

    init_unconfig();
    init_config();
		
    DISABLE;
    B_D12_Lb |= CONFIGURE;
    ENABLE;
  } 
  else
    stall_ep0();
}

void get_interface(void)
{
  unsigned char txdat = 0;        /* Only/Current interface = 0 */
  single_transmit(&txdat, 1);
}

void set_interface(void)
{
  if (ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
    single_transmit(0, 0);
  else
    stall_ep0();
}


//USB标准设备请求入口地址指针表
code void (*StandardDeviceRequest[])(void) =
{
	get_status,
	clear_feature,
	reserved,//stall ep0
	set_feature,
	reserved,
	set_address,
	get_descriptor,
	reserved,
	get_configuration,
	set_configuration,
	get_interface,
	set_interface,
	reserved,
	reserved,
	reserved,
	reserved
};

void get_firmware_version()
{
	unsigned char i;

	i = 0x30; // firmware version number
	single_transmit((unsigned char *)&i, 1);
}

void get_buffer_size()
{
	unsigned char i[4];

	i[0] = EP2_PACKET_SIZE;//define EP2_PACKET_SIZE  64
	i[1] = 0;
	i[2] = 0;
	i[3] = 0;
	single_transmit((unsigned char *)&i, 4);
}

void read_write_register(void)
{
  if(ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK) //0x80
  {
    if(ControlData.DeviceRequest.wIndex == GET_FIRMWARE_VERSION &&	//0x472
			ControlData.DeviceRequest.wValue == 0 &&
			ControlData.DeviceRequest.wLength == 1)
      get_firmware_version();
    else
      if(ControlData.DeviceRequest.wIndex == GET_BUFFER_SIZE &&	//0x474
			ControlData.DeviceRequest.wValue == 0 &&
			ControlData.DeviceRequest.wLength == 4)
        get_buffer_size();
      else
 	stall_ep0();

  }	// if read register
  else
  {
    if(ControlData.DeviceRequest.wIndex == SETUP_DMA_REQUEST &&	//0x471
			ControlData.DeviceRequest.wValue == 0 &&
			ControlData.DeviceRequest.wLength == 6)
    {
      if(ControlData.dataBuffer[5]==0x81)
 	D12_WriteEndpoint(5, ControlData.dataBuffer[3], EpBuf);
      single_transmit(0, 0);
    }
    else
      stall_ep0();
  }	// if write register
}

//厂商请求入口地址
code void (*VendorDeviceRequest[])(void) =
{
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	reserved,
	read_write_register,
	reserved,
	reserved,
	reserved
};



⌨️ 快捷键说明

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