|
此函數(shù)庫(kù)可以直接使用PHILIPS的Demo驅(qū)動(dòng)D12TEST 以下只用了端點(diǎn)1進(jìn)行控制傳輸,端點(diǎn)2的數(shù)據(jù)傳輸自己添加,沒(méi)有使用DMA功能,為簡(jiǎn)單的固件程序 /************************************************************************** PHILIPS PDIUSBD12 FIRMWARE COPYRIGHT (c) 2005 BY JJJ. -- ALL RIGHTS RESERVED -- File Name: D12_USB.h Author: Jiang Jian Jun Created: 2005/4/3 Modified: NO Revision: 1.0 ***************************************************************************/ #ifndef __D12_USB_H_REVISION_FIRST__ #define __D12_USB_H_REVISION_FIRST__ #include <REGX51.H> sbit SUSPEND = P3^5; #define D12_INT_ENDP0OUT 0x0001 //中斷寄存器位定義 #define D12_INT_ENDP0IN 0x0002 #define D12_INT_ENDP1OUT 0x0004 #define D12_INT_ENDP1IN 0x0008 #define D12_INT_ENDP2OUT 0x0010 #define D12_INT_ENDP2IN 0x0020 #define D12_INT_BUSRESET 0x0040 #define D12_INT_SUSPENDCHANGE 0x0080 #define D12_INT_EOT 0x0100 #define D12_SETUPPACKET 0x20 //讀最后處理狀態(tài)寄存器的設(shè)置信息包0010,0000b #define EP0_PACKET_SIZE 16 //p0最大16byte #define USB_ENDPOINT_DIRECTION_MASK 0x80 //設(shè)備請(qǐng)求類(lèi)型,傳輸方向 D7 1000,0000b #define USB_REQUEST_TYPE_MASK 0x30 //bmRequest的設(shè)置 #define USB_REQUEST_MASK 0x0f #define USB_STANDARD_REQUEST 0x00 //5,6位的定義 #define USB_VENDOR_REQUEST 0x20 #define USB_DEVICE_DESCRIPTOR_TYPE 0x01 //描述符類(lèi)型 設(shè)備描述符01h,配置描述符02,接口描述符04,端點(diǎn)描述符05 #define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02 #define CONFIG_DESCRIPTOR_LENGTH 0x002E //配置描述符總長(zhǎng)度 //************************************************************************** //Port And Macros And Structure And Union Definitions #define SWAP(x) ((((x) & 0x00FF) << 8) | (((x) >> 8) & 0x00FF)) //交換高低8位 #define MSB(x) (((x) >> 8) & 0x00FF) //取數(shù)據(jù)高8位 #define LSB(x) ((x) & 0x00FF) //取數(shù)據(jù)低8位 typedef union _Event_Flags_ //定義USB事件標(biāo)志數(shù)據(jù)類(lèi)型 { struct _Bit_Flags_ { unsigned char Timer : 1; //定時(shí)器益出事件標(biāo)記 unsigned char BusReset : 1; //USB總線復(fù)位標(biāo)志 unsigned char Suspend : 1; //USB器件掛起標(biāo)志 unsigned char SetupPacket : 1; //收到SETUP包標(biāo)志 unsigned char RemoteWakeup : 1; //遠(yuǎn)程喚醒標(biāo)志 unsigned char InISR : 1; //USB中斷服務(wù)標(biāo)志 unsigned char ControlState : 2; //控制端點(diǎn)處理狀態(tài) //0:IDEL 空閑狀態(tài) //1:TRANSMIT 數(shù)據(jù)發(fā)送狀態(tài) //2:RECEIVE 數(shù)據(jù)接受狀態(tài) unsigned char Configuration : 1; //配置標(biāo)志 (0:未配置;1:已配置) unsigned char Port1RxDone : 1; //端口1收到數(shù)據(jù)標(biāo)志 unsigned char Port2RxDone : 1; //端口2收到數(shù)據(jù)標(biāo)志 unsigned char Port1TxFull : 1; //端口1輸出緩沖區(qū)滿標(biāo)志 unsigned char Port2TxFull : 1; //端口2輸出緩沖區(qū)滿標(biāo)志 unsigned char Reserve : 3; //保留,未使用 }Bits; unsigned short int Value; }EVENT_FLAGS; //事件標(biāo)志數(shù)據(jù)類(lèi)型 typedef struct _DEVICE_REQUEST_ { unsigned char bmRequestType; //請(qǐng)求類(lèi)型 unsigned char bRequest; //USB請(qǐng)求 unsigned short wValue; //USB請(qǐng)求值 unsigned short wIndex; //USB請(qǐng)求索引 unsigned short wLength; //記數(shù)長(zhǎng)度 }DEVICE_REQUEST; #define MAX_CONTROLDATA_SIZE 8 typedef struct _control_xfer { DEVICE_REQUEST DeviceRequest; //USB請(qǐng)求結(jié)構(gòu)體 unsigned short wLength; //傳輸數(shù)據(jù)的總字節(jié)數(shù) unsigned short wCount; //傳輸字節(jié)數(shù)統(tǒng)計(jì) unsigned char * pData; //傳輸數(shù)據(jù)指針 unsigned char dataBuffer[MAX_CONTROLDATA_SIZE]; //請(qǐng)求的數(shù)據(jù) }CONTROL_XFER; static EVENT_FLAGS EventFlags; //定義為全局變量,用于與主程序的通信 static CONTROL_XFER ControlData; //保存SETUP包請(qǐng)求類(lèi)型和請(qǐng)求數(shù)據(jù) unsigned char idata EndPoint1Buffer[4]; //控制端點(diǎn)緩存 unsigned char idata EndPoint2Buffer[64];//主端點(diǎn)緩存 //************************************************************************** //硬件提取層,多路地址/數(shù)據(jù)總線方式讀寫(xiě) void Outportb(unsigned int Addr, unsigned char Data) { *((unsigned char xdata *) Addr) = Data; } unsigned char Inportb(unsigned int Addr) { return *((unsigned char xdata *) Addr); } void USB_Delay1ms(unsigned int count) { unsigned int i,j; for(i=0;i<count;i++) for(j=0;j<120;j++); } //************************************************************************** #define D12_DATA 0 #define D12_COMMAND 1 //PDIUSBD12命令接口函數(shù) void D12_SetMode(unsigned char bConfig,unsigned char bClkDiv) { Outportb(D12_COMMAND,0xF3); Outportb(D12_DATA,bConfig); Outportb(D12_DATA,bClkDiv); } //設(shè)置端點(diǎn) void D12_SetEndpointStatus(unsigned char bEndp,unsigned char bStalled) { Outportb(D12_COMMAND,0x40+bEndp); Outportb(D12_DATA,bStalled); } //應(yīng)答!!!!! void D12_AcknowledgeEndpoint(unsigned char endp) { Outportb(D12_COMMAND,endp); Outportb(D12_COMMAND,0xF1); if(endp==0) Outportb(D12_COMMAND,0xF2); } //設(shè)置地址使能 void D12_SetAddressEnable(unsigned char bAddress,unsigned char bEnable) { Outportb(D12_COMMAND,0xd0); if(bEnable) bAddress |= 0x80; Outportb(D12_DATA,bAddress); } //設(shè)置端點(diǎn)使能 void D12_SetEndpointEnable(unsigned char bEnable) { Outportb(D12_COMMAND,0xD8); if(bEnable) Outportb(D12_DATA,1); else Outportb(D12_DATA,0); } //讀中斷寄存器 unsigned short D12_ReadInterruptRegister(void) { unsigned char b1; unsigned int j; Outportb(D12_COMMAND,0xF4); b1=Inportb(D12_DATA); j=Inportb(D12_DATA); j<<=8; j+=b1; return j; } //讀取端點(diǎn)狀態(tài) unsigned char D12_ReadEndpointStatus(unsigned char EndPoint) { unsigned char BackValue; if(EventFlags.Bits.InISR == 0) EA = 0; Outportb(D12_COMMAND, 0x80 + EndPoint);//讀取端點(diǎn)狀態(tài) BackValue = Inportb(D12_DATA); if(EventFlags.Bits.InISR == 0) EA = 1; return BackValue; } //讀端點(diǎn)最后處理狀態(tài) unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp) { Outportb(D12_COMMAND,0x40+bEndp); return Inportb(D12_DATA); } //讀端口 unsigned char D12_ReadEndpoint(unsigned char endp,unsigned char len,unsigned char *buf) { unsigned char i,j; Outportb(D12_COMMAND,endp); if((Inportb(D12_DATA)&0xff)==0)//" define D12_FULLEMPTY as 0xFF by newer return 0; Outportb(D12_COMMAND,0x80+endp); i=Inportb(D12_DATA); i=i&0x60; Outportb(D12_COMMAND,0xF0); j=Inportb(D12_DATA); j=Inportb(D12_DATA); if(j>len) j=len; for(i=0;i<j;i++) *(buf+i)=Inportb(D12_DATA); Outportb(D12_COMMAND,0xF2); return j; }
unsigned char D12_ReadEndpoint_Int(unsigned char endp,unsigned char len,unsigned char *buf) { unsigned char i,j; Outportb(D12_COMMAND,endp); if((Inportb(D12_DATA)&0xff)==0)//" define D12_FULLEMPTY as 0xFF by newer return 0; Outportb(D12_COMMAND,0x80+endp); i=Inportb(D12_DATA); i=i&0x60; Outportb(D12_COMMAND,0xF0); j=Inportb(D12_DATA); j=Inportb(D12_DATA); if(j>len) j=len; for(i=0;i<j;i++) *(buf+i)=Inportb(D12_DATA); Outportb(D12_COMMAND,0xF2); return j; }
unsigned char D12_WriteEndpoint(unsigned char endp,unsigned char len,unsigned char * buf) { unsigned char i; Outportb(D12_COMMAND,endp); Inportb(D12_DATA); Outportb(D12_COMMAND,0xF0); Outportb(D12_DATA,0); Outportb(D12_DATA,len); for(i=0;i<len;i++) Outportb(D12_DATA,*(buf+i)); Outportb(D12_COMMAND,0xFA); return len; } unsigned char D12_WriteEndpoint_Int(unsigned char endp,unsigned char len,unsigned char * buf) { unsigned char i; Outportb(D12_COMMAND,endp); Inportb(D12_DATA); Outportb(D12_COMMAND,0xF0); Outportb(D12_DATA,0); Outportb(D12_DATA,len); for(i=0;i<len;i++) Outportb(D12_DATA,*(buf+i)); Outportb(D12_COMMAND,0xFA); return len; } void DisconnectUSB(void) { D12_SetMode(0x02,0x03);//SET TO ONE? by newer } void InitialUSBInt(void); void ConnectUSB(void) { EventFlags.Value = 0x0000; InitialUSBInt(); D12_SetMode(0x16,0x03); } void ReconnectUSB(void) { SUSPEND = 0; DisconnectUSB(); USB_Delay1ms(1000); ConnectUSB(); } //************************************************************************** //中斷服務(wù)程序 void InitialUSBInt(void) { IT1=0; //低電平中斷觸發(fā) EX1=1; //允許外部中斷 PX1=0; //優(yōu)先級(jí)低 EA =1; } void EP0_Out(void) { unsigned char ep_last,i; ep_last=D12_ReadLastTransactionStatus(0);//interrupt symbol if(ep_last&D12_SETUPPACKET) { //recieved SETUP packet ---by newer ControlData.wLength=0; ControlData.wCount=0; if(D12_ReadEndpoint_Int(0,sizeof(ControlData.DeviceRequest),(unsigned char *)(&(ControlData.DeviceRequest)))!=sizeof(DEVICE_REQUEST)) { D12_SetEndpointStatus(0,1); D12_SetEndpointStatus(1,1); EventFlags.Bits.ControlState=0; //should define USB_IDLE first --by newer return; } ControlData.DeviceRequest.wValue=SWAP(ControlData.DeviceRequest.wValue); ControlData.DeviceRequest.wIndex=SWAP(ControlData.DeviceRequest.wIndex); ControlData.DeviceRequest.wLength=SWAP(ControlData.DeviceRequest.wLength); D12_AcknowledgeEndpoint(0); D12_AcknowledgeEndpoint(1); ControlData.wLength=ControlData.DeviceRequest.wLength; ControlData.wCount=0; if(ControlData.DeviceRequest.bmRequestType&(unsigned char)USB_ENDPOINT_DIRECTION_MASK) { EventFlags.Bits.SetupPacket=1; //recv from host? --by newer EventFlags.Bits.ControlState=1; //by newer } else { if(ControlData.DeviceRequest.wLength==0) { EventFlags.Bits.SetupPacket=1; EventFlags.Bits.ControlState=0; //by newer } else { if(ControlData.DeviceRequest.wLength>16)//最大傳16byte { EventFlags.Bits.ControlState=0; //by newer D12_SetEndpointStatus(0,1); D12_SetEndpointStatus(1,1); } else { EventFlags.Bits.ControlState=2;//by newer } } } } else if(EventFlags.Bits.ControlState==2) { i=D12_ReadEndpoint_Int(0,EP0_PACKET_SIZE,ControlData.dataBuffer+ControlData.wCount); ControlData.wCount+=i; if(i!=EP0_PACKET_SIZE||ControlData.wCount>=ControlData.wLength) { EventFlags.Bits.SetupPacket=1; EventFlags.Bits.ControlState=0; } } else EventFlags.Bits.ControlState=0; } void EP0_In(void) { short i=ControlData.wLength-ControlData.wCount; D12_ReadLastTransactionStatus(1); if(EventFlags.Bits.ControlState!=1) return; if(i>=EP0_PACKET_SIZE) { D12_WriteEndpoint_Int(1,EP0_PACKET_SIZE,ControlData.pData+ControlData.wCount); ControlData.wCount+=EP0_PACKET_SIZE; EventFlags.Bits.ControlState=1; return; } if(i!=0) { D12_WriteEndpoint_Int(1,i,ControlData.pData+ControlData.wCount); ControlData.wCount+=i; EventFlags.Bits.ControlState=0; return; } D12_WriteEndpoint_Int(1,0,0); EventFlags.Bits.ControlState=0; } void EP1_Out(void) { unsigned char Length; D12_ReadLastTransactionStatus(2); /* Clear interrupt flag */ Length = D12_ReadEndpoint_Int(2, sizeof(EndPoint1Buffer),EndPoint1Buffer); if(Length != 0) EventFlags.Bits.Port1RxDone = 1; } void EP1_In(void) { D12_ReadLastTransactionStatus(3); } void EP2_Out(void) { unsigned char Length,EP2Status; D12_ReadLastTransactionStatus(4); /* Clear interrupt flag */ EP2Status = D12_ReadEndpointStatus(4); EP2Status&=0x60; Length = D12_ReadEndpoint(4,sizeof(EndPoint2Buffer),EndPoint2Buffer); if(EP2Status==0x60) Length = D12_ReadEndpoint(4,sizeof(EndPoint2Buffer),EndPoint2Buffer); if(Length != 0) EventFlags.Bits.Port2RxDone = 1; } void EP2_In(void) { D12_ReadLastTransactionStatus(5); /* Clear interrupt flag */ } //************************************************************************** //請(qǐng)求處理 typedef struct _usb_device_descriptor { unsigned char bLength; unsigned char bDescriptorType; unsigned int bcdUSB; unsigned char bDeviceClass; unsigned char bDeviceSubClass; unsigned char bDeviceProtocol; unsigned char bMaxPacketSize0; unsigned int idVendor; unsigned int idProduct; unsigned int bcdDevice; unsigned char iManufacturer; unsigned char iProduct; unsigned char iSerialNumber; unsigned char bNumConfiguations; }USB_DEVICE_DESCRIPTOR; code USB_DEVICE_DESCRIPTOR DeviceDescr= { sizeof(USB_DEVICE_DESCRIPTOR), 0x01,//USB_DEVICE_DESCRIPTOR_TYPE, SWAP(0x0100), 0xDC,//USB_CLASS_CODE_TEST_CLASS_DEVICE, 0, 0, EP0_PACKET_SIZE, SWAP(0x0471), SWAP(0x0666), SWAP(0x0100), 0, 0, 0, 25 }; //配置描述符 typedef struct _usb_configuration_descriptor { unsigned char bLength[0x2e]; }USB_CONFIGURATION_DESCRIPTOR; code USB_CONFIGURATION_DESCRIPTOR ConfigDescr= { 0x09,0x02,0x2e,0x00,0x01,0x01,0x00,0xa0,0x32, 0x09,0x04,0x00,0x00,0x04,0xdc,0xa0,0xb0,0x00, 0x07,0x05,0x81,0x03,0x02,0x00,0x0a, 0x07,0x05,0x01,0x03,0x02,0x00,0x0a, 0x07,0x05,0x82,0x02,0x40,0x00,0x0a, 0x07,0x05,0x02,0x02,0x40,0x00,0x0a }; //code_tramsit 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) { D12_WriteEndpoint(1,EP0_PACKET_SIZE,ControlData.pData); ControlData.wCount+=EP0_PACKET_SIZE; EA = 0; EventFlags.Bits.ControlState=1; EA = 1; } else { D12_WriteEndpoint(1,ControlData.wLength,pRomData); ControlData.wCount+=ControlData.wLength; EA = 0; EventFlags.Bits.ControlState=0; EA = 1; } } //獲取描述符 void get_descriptor(void) { if(MSB(ControlData.DeviceRequest.wValue)==USB_DEVICE_DESCRIPTOR_TYPE) { code_transmit((unsigned char code*)&DeviceDescr,sizeof(USB_DEVICE_DESCRIPTOR)); return; } if(MSB(ControlData.DeviceRequest.wValue)==USB_CONFIGURATION_DESCRIPTOR_TYPE) { if(ControlData.DeviceRequest.wLength>CONFIG_DESCRIPTOR_LENGTH) { ControlData.DeviceRequest.wLength=CONFIG_DESCRIPTOR_LENGTH; //標(biāo)識(shí)符總大小2E byte,第二次請(qǐng)求時(shí)wlength=0x00ff } //這里的ConfigDescr其實(shí)應(yīng)該包括其他標(biāo)識(shí)符! code_transmit((unsigned char code*)&ConfigDescr,ControlData.DeviceRequest.wLength); return; } } //single transmit void single_transmit(unsigned char *buf,unsigned char len) { if(len<=EP0_PACKET_SIZE) { D12_WriteEndpoint(1,len,buf); } } //設(shè)置地址 void set_address(void) { D12_SetAddressEnable((unsigned char)(ControlData.DeviceRequest.wValue&0xff),1); //比如wValue是"02 00" 應(yīng)該得到02 single_transmit(0,0); } //設(shè)置配置 void set_configuration(void) { if(ControlData.DeviceRequest.wValue==0) { single_transmit(0,0); EventFlags.Bits.Configuration=0; D12_SetEndpointEnable(0); } else if(ControlData.DeviceRequest.wValue==1) { single_transmit(0,0); D12_SetEndpointEnable(0); D12_SetEndpointEnable(1); EventFlags.Bits.Configuration=1; } } //讀取配置 void get_configuration(void) { unsigned char c=EventFlags.Bits.Configuration; single_transmit(&c,1); } //讀取設(shè)備接口信息 void get_interface(void) { unsigned char txdat=0; single_transmit(&txdat,1); } static code void (*StandardDeviceRequest[])(void)= { 0,0,0,0, 0,set_address,get_descriptor,0, get_configuration,set_configuration,get_interface,0, 0,0,0,0 }; static code void (*VendorDeviceRequest[])(void)= { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 }; void ControlHandler(void) { unsigned char type,req; type=ControlData.DeviceRequest.bmRequestType&USB_REQUEST_TYPE_MASK;//0011,0000b req=ControlData.DeviceRequest.bRequest&USB_REQUEST_MASK;//0000,1111b if(type==USB_STANDARD_REQUEST) (*StandardDeviceRequest[req])(); else if(type==USB_VENDOR_REQUEST) (*VendorDeviceRequest[req])(); } void USB_ISR(void) interrupt 2 { unsigned int i_st; EA = 0; EventFlags.Bits.InISR=1; i_st=D12_ReadInterruptRegister(); if(i_st!=0) { if(i_st&D12_INT_ENDP0OUT) EP0_Out(); if(i_st&D12_INT_ENDP0IN) EP0_In(); if(i_st&D12_INT_ENDP1OUT) EP1_Out(); if(i_st&D12_INT_ENDP1IN) EP1_In(); if(i_st&D12_INT_ENDP2OUT) EP2_Out(); if(i_st&D12_INT_ENDP2IN) EP2_In(); } EventFlags.Bits.InISR=0; EA = 1; } //************************************************************************** #endif //簡(jiǎn)單主程序文件,自己按需要改寫(xiě) #include <REGX51.H> #include "D12_USB.h" extern EVENT_FLAGS EventFlags; //事件信號(hào) extern unsigned char idata EndPoint1Buffer[4]; main() { ReconnectUSB(); while(1) { if(EventFlags.Bits.SetupPacket) { EA = 0; EventFlags.Bits.SetupPacket = 0; ControlHandler(); EA = 1; } if(EventFlags.Bits.Timer) { EventFlags.Bits.Timer = 0; } if(EventFlags.Bits.Port1RxDone) { EventFlags.Bits.Port1RxDone = 0; } } } |