#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条评论)
登录后参与讨论