原创 圈圈教你玩USB--3.7 设备描述符的返回(程序)

2011-5-2 20:33 1854 9 9 分类: MCU/ 嵌入式

#include<at89x52.h>

#define uint8 unsigned char
#define uint16 unsigned short int

#define Fclk       22118400UL
#define BitRate       9600UL
#define D12SetCommandAddr()    P3_5=1
#define D12SetDataAddr()     P3_5=0
#define D12SetWr()       P3_6=1
#define D12ClrWr()      P3_6=0
#define D12SetRd()      P3_7=1
#define D12ClrRd()      P3_7=0
#define D12SetPortIn()     P0=0xFF
#define D12SetPortOut()
#define D12SetData(Value)    P0=Value
#define D12GetData()     P0

#define D12_WRITE_BUFFER    0xF0
#define D12_READ_BUFFER     0xF0
#define D12_ACKNOWLEDGE_SETUP   0xF1
#define D12_CLEAR_BUFFER    0xF2
#define D12_SET_MODE     0xF3
#define READ_INTERRUPT_REGISTER   0xF4
#define D12_VALIDATE_BUFFER    0xFA

#define GET_STATUS      0
#define CLEAR_FEATURE     1
#define SET_FEATURE      3
#define SET_ADDRESS      5
#define GET_DESCRIPTOR     6
#define SET_DESCRIPTOR     7
#define GET_CONFIGURATION    8
#define SET_CONFIGURATION    9
#define GET_INTERFACE     10
#define SET_INTERFACE     11
#define SYNCH_FRAME      12

#define DEVICE_DESCRIPTOR    1
#define CONFIGURATION_DESCRIPTOR  2
#define STRING_DESCRIPTOR    3
#define ITNERFACE_DESCRIPTOR   4
#define ENDPOINT_DESCRIPTOR    5

uint8 Sending;
uint8 Buffer[16];

uint8 bmRequestType;
uint8 bRequest;
uint16 wValue;
uint16 wIndex;
uint16 wLength;
uint8 *pSendData;
uint16 SendLength;
uint8 NeedZeroPacket;

code uint8 HexTable[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
code uint8 DeviceDescriptor[0x12]={
 /*Length*/0x12,/*bDescriptorType*/0x01,
 /*bcdUSB*/0x10,0x01,/*bDeviceClass*/0x00,
 /*bDeviceSubClass*/0x00,/*bDeviceProtocol*/0x00,
 /*bMaxPacketSize0*/0x10,/*idVender*/0x88,0x88,
 /*idProduct*/0x01,0x00,/*bcdDevice*/0x00,0x01,
 /*iManufacturer*/0x01,/*iProduct*/0x02,
 /*iSerialNumber*/0x03,/*bNumConfigurations*/0x01
};

void D12Write(uint8 d){
 D12ClrWr();
 D12SetPortOut();
 D12SetData(d);
 D12SetWr();
 D12SetPortIn();
}

void D12WriteByte(uint8 Value){
 D12SetDataAddr();
 D12Write(Value);
}

void D12WriteCommand(uint8 Command){
 D12SetCommandAddr();
 D12Write(Command);
}

uint8 D12ReadByte(){
 uint8 temp;
 D12SetDataAddr();
 D12ClrRd();
 temp=D12GetData();
 D12SetRd();
 return temp;
}

void InitUART(){
 EA=0;
 TMOD&=0x0F;
 TMOD|=0x20;
 PCON=0x80;
 SCON=0x50;
 TH1=256-Fclk/(BitRate*12*16);
 TL1=256-Fclk/(BitRate*12*16);
 ES=1;
 EA=1;
 TR1=1;
}

void UartISR() interrupt 4{
 if(RI) RI=0;
 else{
  TI=0;
  Sending=0;
 }
}

void UartPutChar(uint8 d){
 SBUF=d;
 Sending=1;
 while(Sending);
}

void Prints(uint8 *pd){
 while(*pd!='\0')
  UartPutChar(*pd++);
}

void PrintHex(uint8 d){
 Prints("0x");
 UartPutChar(HexTable[d>>4]);
 UartPutChar(HexTable[d&0x0F]);
 UartPutChar(' ');
}

void UsbConnect(){
 Prints("连接USB。\r\n");
 D12WriteCommand(D12_SET_MODE);
 D12WriteByte(0x16);
 D12WriteByte(0x47); 
}

uint8 D12ReadEndpointLastStatus(uint8 Endp){
 D12WriteCommand(0x40+Endp);
 return D12ReadByte();
}

uint8 D12ReadEndpointBuffer(uint8 Endp,uint8 Len,uint8 *Buf){
 uint8 i,j;
 D12WriteCommand(0x00+Endp);
 D12WriteCommand(D12_READ_BUFFER);
 D12ReadByte();
 j=D12ReadByte();
 if(j>Len)
  j=Len;

 Prints("读端点");
 UartPutChar('0'+Endp/2);
 Prints("缓冲区");
 PrintHex(j);
 Prints("字节。\r\n");

 for(i=0;i<j;i++){
  *(Buf+i)=D12ReadByte();
  PrintHex(*(Buf+i));
 }
 if(j%16!=0) Prints("\r\n");
 return j;
}

void D12AcknowledgeSetup(void){
 D12WriteCommand(0x00+1);
 D12WriteCommand(D12_ACKNOWLEDGE_SETUP);
 D12WriteCommand(0x00+0);
 D12WriteCommand(D12_ACKNOWLEDGE_SETUP);
}

uint8 D12WriteEndpointBuffer(uint8 Endp,uint8 Len,uint8 *Buf){
 uint8 i;
 D12WriteCommand(0x00+Endp);
 D12WriteCommand(D12_WRITE_BUFFER);
 D12WriteByte(0);
 D12WriteByte(Len);
 Prints("写端点");
 UartPutChar('0'+Endp/2);
 Prints("缓冲区");
 PrintHex(Len);
 Prints("字节。\r\n");
 for(i=0;i<Len;i++){
  D12WriteByte(*(Buf+i));
  PrintHex(*(Buf+i));
  if((i+1)%16==0) Prints("\r\n");
 }
 if(Len%16!=0) Prints("\r\n");
 D12SetPortIn();
 D12WriteCommand(D12_VALIDATE_BUFFER);
 return Len;
}

void UsbEp0SendData(){
 if(SendLength>DeviceDescriptor[7]){
  D12WriteEndpointBuffer(1,DeviceDescriptor[7],pSendData);
  SendLength-=DeviceDescriptor[7];
  pSendData+=DeviceDescriptor[7];
 } 
 else{
  if(SendLength!=0){
   D12WriteEndpointBuffer(1,SendLength,pSendData);
   SendLength=0;
  }
  else{
   if(NeedZeroPacket==1){
    D12WriteEndpointBuffer(1,0,Buffer);
    NeedZeroPacket=1;    
   }
  }
 }
}

void UsbEp0Out(){
 Prints("USB端点0输出中断。\r\n");
 if(D12ReadEndpointLastStatus(0)&0x20){
  D12ReadEndpointBuffer(0,16,Buffer);
  D12AcknowledgeSetup();
 }
 else
  D12ReadEndpointBuffer(0,16,Buffer);
 D12WriteCommand(D12_ACKNOWLEDGE_SETUP);
 bmRequestType=Buffer[0];
 bRequest=Buffer[1];
 wValue=Buffer[2]+((uint16)Buffer[3])<<8;
 wIndex=Buffer[4]+((uint16)Buffer[5])<<8;
 wLength=Buffer[6]+((uint16)Buffer[7])<<8;
 if((bmRequestType&0x80)==0x80)
  switch((bmRequestType>>5)&0x03){
  case 0: Prints("USB标准输入请求:");
   switch(bRequest){
   case GET_CONFIGURATION: Prints("获取配置。\r\n"); break;
   case GET_DESCRIPTOR: Prints("获取描述符--");
    switch((wValue>>8)&0xFF){
    case DEVICE_DESCRIPTOR: Prints("设备描述符。\r\n");
     pSendData=DeviceDescriptor;
     if(wLength>DeviceDescriptor[0]){
      SendLength=DeviceDescriptor[0];
      if(SendLength%DeviceDescriptor[7]==0) NeedZeroPacket=1;
     }
     else SendLength=wLength;
     UsbEp0SendData();
     break;
    case CONFIGURATION_DESCRIPTOR: Prints("配置描述符。\r\n"); break;
    case STRING_DESCRIPTOR: Prints("字符串描述符。\r\n"); break;
    default: Prints("其他描述符,描述符代码:");
     PrintHex((wValue>>8)&0xFF);
     Prints("\r\n");
    }
    break;
   case GET_INTERFACE: Prints("获取接口。\r\n"); break;
   case GET_STATUS: Prints("获取状态。\r\n"); break;
   case SYNCH_FRAME: Prints("同步帧。\r\n"); break;
   default: Prints("错误:未定义的标准输入请求。\r\n");
   }
   break;
  case 1: Prints("USB类输入请求:\r\n"); break;
  case 2: Prints("USB厂商输入请求:\r\n"); break;
  default: Prints("错误:未定义的输入请求。\r\n");
  }
  else
   switch((bmRequestType>>5)&0x03){
   case 0: Prints("USB标准输出请求。\r\n");
    switch(bRequest){
    case CLEAR_FEATURE: Prints("清除特性。\r\n"); break;
    case SET_ADDRESS: Prints("设置地址。\r\n"); break;
    case SET_CONFIGURATION: Prints("设置配置。\r\n"); break;
    case SET_DESCRIPTOR: Prints("设置描述符。\r\n"); break;
    case SET_FEATURE: Prints("设置特性。\r\n"); break;
    case SET_INTERFACE: Prints("设置接口。\r\n"); break;
    default: Prints("错误:未定义的标准输出请求。\r\n"); 
    }
   case 1: Prints("USB类输出请求:\r\n"); break;
   case 2: Prints("USB厂商输出请求。\r\n"); break;
   default: Prints("错误:未定义的标准输出请求。\r\n");
   }
}

void UsbEp0In(){
  Prints("USB端点0输入中断。\r\n");
 D12ReadEndpointLastStatus(1);
 UsbEp0SendData();
}

void main(void){
 uint8 InterruptSource;
 InitUART();
 UsbConnect();
 while(1){
  D12WriteCommand(READ_INTERRUPT_REGISTER);
  InterruptSource=D12ReadByte();
  if(InterruptSource&0x80) Prints("USB总线挂起。\r\n");
  if(InterruptSource&0x40) Prints("USB总线复位。\r\n");
  if(InterruptSource&0x01) UsbEp0Out();
  if(InterruptSource&0x02) UsbEp0In();
 }
}

文章评论0条评论)

登录后参与讨论
我要评论
0
9
关闭 站长推荐上一条 /2 下一条