我用外部控件模式,獲取描述符,讀回的長度始終只有8個字節(jié)。也就是只有端點(diǎn)一的fifo大小。怎么可以連續(xù)讀到更多的字符?
想問一下,你向端點(diǎn)一寫的話,PC端能找到設(shè)備嗎?
哦,忘記了說明一下,我是主控模式,讀取usb打印機(jī)的描述符,只讀回了8個字節(jié)。 代碼如下: //端點(diǎn) const UINT8 SetupGetDevId[] = {// dir type recipient (DEVICE_to_HOST|CLASS_TYPE|INTERFACE_RECIPIENT),//bmRequestTyep 0xA1 0x00, //bRequest 0x00 0x00,0x00, //wValue ConfigIndex 0x00,0x00 0x00, 0x00, //wIndex Interface&AlternateSetting 0x00,0x00 0xf1, 0x03 //wLength 0x01,0x00 };
//獲得廠商/設(shè)備字符串信息 UINT8 GetStringDescribe(UINT8 type) { UINT8 rstatus; switch(type) { case 0: rstatus = SetupStage(SetupGetStr0Descr); break; case 1: rstatus = SetupStage(SetupGetStr1Descr); break; case 2: rstatus = SetupStage(SetupGetStr2Descr); break; case 3: rstatus = SetupStage(SetupGetDevId); break; default: break; } if((rstatus==USB_INT_SUCCESS)||(rstatus == USB_INT_CONNECT)) /* SETUP階段操作成功 */ { rstatus=DataStage(); if((rstatus==USB_INT_SUCCESS) ||(rstatus == USB_INT_CONNECT) ) //發(fā)送out令牌*/ { ReadUsbData(buffer);//只能讀到8個字節(jié) rstatus = StatusStage(); } } return rstatus; }
只留這個問題了。大家?guī)唾M(fèi)費(fèi)心看看。謝謝了!
你的程序不全啊,這樣找不到問題的。
#define USB_CTR_PORT PORTC #define USB_CTR_DDR DDRC #define USB_CTR_PIN PINC #define USB_CS_BIT (1<<7) #define USB_INIT_BIT (1<<6) #define USB_WR_BIT (1<<5) #define USB_RD_BIT (1<<4) #define USB_AO_BIT (1<<3)
#define USB_INT_PIN USB_CTR_PIN&USB_INIT_BIT #define USB_CMD_OPT USB_CTR_PORT|=USB_AO_BIT #define USB_DATA_OPT USB_CTR_PORT&=~USB_AO_BIT #define USB_WR_OPT USB_CTR_PORT&=~USB_WR_BIT #define USB_RD_OPT USB_CTR_PORT&=~USB_RD_BIT
#define USB_DATA_PORT PORTD #define USB_DATA_DDR DDRD #define USB_DATA_PIN PIND
#define USB_OUT_DIR USB_DATA_DDR=0xFF #define USB_IN_DIR USB_DATA_DDR=0x00
#define USB_CMD_WR USB_CMD_OPT;USB_WR_OPT;USB_OUT_DIR #define USB_CMD_RD USB_IN_DIR;USB_CMD_OPT;USB_RD_OPT #define USB_DATA_WR USB_DATA_OPT;USB_WR_OPT;USB_OUT_DIR #define USB_DATA_RD USB_IN_DIR;USB_DATA_OPT;USB_RD_OPT #define USB_ENABLE USB_CTR_PORT&=~USB_CS_BIT #define USB_RELEASE USB_CTR_PORT|=(USB_WR_BIT|USB_RD_BIT|USB_CS_BIT) void InitUsbPort(void) { USB_DATA_DDR=0x00;//輸入 USB_DATA_PORT=0xFF;//上拉 USB_CTR_PORT|=(USB_CS_BIT|USB_WR_BIT|USB_RD_BIT|USB_AO_BIT|USB_INIT_BIT); //CS,WR,RD,AO輸出高電平,INIT輸入上拉 USB_CTR_DDR|=(USB_CS_BIT|USB_WR_BIT|USB_RD_BIT|USB_AO_BIT);//CS,WR,RD,AO輸出 USB_CTR_DDR&=~USB_INIT_BIT;//INIT輸入 } /* 向CH375的命令端口寫入命令,周期不小于4uS,如果單片機(jī)較快則延時 */
void Ch375WriteCmdPort(UINT8 cmd) {
USB_DATA_PORT=cmd;//賦值 USB_ENABLE; //打開USB USB_CMD_WR; USB_RELEASE; DelayNus(5); } /* 向CH375的數(shù)據(jù)端口寫入數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時 */
void Ch375WriteDataPort(UINT8 data) { USB_DATA_PORT=data; USB_ENABLE; USB_DATA_WR; USB_DATA_PORT=data; USB_RELEASE; DelayNus(5); } /* 從CH375的數(shù)據(jù)端口讀出數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時 */ UINT8 Ch375ReadDataPort(void) { UINT8 rt; USB_ENABLE; USB_DATA_RD; PORTC=0b00100000; rt=PIND; USB_RELEASE; DelayNus(2); return (rt); } /* CH375初始化子程序 */ BOOL CheckCh375(void) { UINT8 i,j; Ch375WriteCmdPort(CMD_RESET_ALL);/* 多次重復(fù)發(fā)命令,執(zhí)行硬件復(fù)位 */ DelayNms(40); for(i=0;i<100;i++) { Ch375WriteCmdPort(CMD_CHECK_EXIST); /* 測試CH375是否正常工作 */ Ch375WriteDataPort(0x5A); /* 寫入測試數(shù)據(jù), 返回?cái)?shù)據(jù)應(yīng)該是測試數(shù)據(jù)取反 */ if((Ch375ReadDataPort())!=0xA5)/* CH375不正常 */ { for(j=0;j<5;j++) { Ch375WriteCmdPort(CMD_RESET_ALL);/* 多次重復(fù)發(fā)命令,執(zhí)行硬件復(fù)位 */ } DelayNms(40);//ch375要求40ms } else return TRUE; } if(i==100) return FALSE; }
UINT8 Ch375CmdProg(UINT8 cmd,UINT8 arg) { UINT8 i,rdata; for(i=0;i<100;i++) { Ch375WriteCmdPort(cmd); if(arg != 0xFF) Ch375WriteDataPort(arg); rdata=Ch375ReadDataPort(); if((rdata==CMD_RET_SUCCESS)||(rdata==USB_INT_CONNECT)) return TRUE; } return FALSE; }
UINT8 TestConnect(void) { Ch375WriteCmdPort(CMD_TEST_CONNECT); return(Ch375ReadDataPort()); } BOOL WaitInterrupt(void) { // UINT8 i; while(USB_INT_PIN);
// for(i=0;USB_INT_PIN != 0;i++)/* 如果CH375的中斷引腳輸出高電平則等待,通過計(jì)數(shù)防止超時 */ // { // DelayUs(); // if(i ==0xF000 ) // Ch375WriteCmdPort(CMD_ABORT_NAK); /* 如果超時達(dá)61mS以上則強(qiáng)行終止NAK重試,中斷返回USB_INT_RET_NAK */ // } Ch375WriteCmdPort(CMD_GET_STATUS); return(Ch375ReadDataPort()); }
UINT8 GetDescr(UINT8 type ) /* 從設(shè)備端獲取描述符 */ { Ch375WriteCmdPort(CMD_GET_DESCR); Ch375WriteDataPort(type);/* 描述符類型, 只支持1(設(shè)備)或者2(配置) */ return(WaitInterrupt());/* 描述符類型, 只支持1(設(shè)備)或者2(配置) */ }
UINT8 SetAddr(UINT8 addr ) /* 設(shè)置設(shè)備端的USB地址 */ { BOOL rstatus; Ch375WriteCmdPort(CMD_SET_ADDRESS); /* 設(shè)置USB設(shè)備端的USB地址 */ Ch375WriteDataPort(addr);/* 地址, 從1到127之間的任意值, 常用2到20 */ rstatus=WaitInterrupt(); if((rstatus==USB_INT_SUCCESS)||(rstatus == USB_INT_CONNECT))/* 等待CH375操作完成 */ { Ch375WriteCmdPort(CMD_SET_USB_ADDR);/* 設(shè)置USB主機(jī)端的USB地址 */ Ch375WriteDataPort(addr); /* 當(dāng)目標(biāo)USB設(shè)備的地址成功修改后,應(yīng)該同步修改主機(jī)端的USB地址 */ DelayNms(5); } return( rstatus ); } UINT8 SetConfig(UINT8 cfg ) /* 設(shè)置設(shè)備端的USB配置 */ { tog_send=tog_recv=0;/* 復(fù)位USB數(shù)據(jù)同步標(biāo)志 */ Ch375WriteCmdPort(CMD_SET_CONFIG);/* 設(shè)置USB設(shè)備端的配置值 */ Ch375WriteDataPort(cfg);/* 此值取自USB設(shè)備的配置描述符中 */ return(WaitInterrupt()); /* 等待CH375操作完成 */ }
// 向CH37X寫入數(shù)據(jù)塊 void WriteUsbData(UINT8 len,UINT8 *buf) { Ch375WriteCmdPort(CMD_WR_USB_DATA7);/* 向CH375的端點(diǎn)緩沖區(qū)寫入準(zhǔn)備發(fā)送的數(shù)據(jù) */ Ch375WriteDataPort(len); /* 后續(xù)數(shù)據(jù)長度, len不能大于64 */ while(len--) { Ch375WriteDataPort(*buf); buf++; } } /* 向CH37X寫入數(shù)據(jù)塊 */ void WriteUsbFlashData(UINT8 len,flash UINT8 *buf) { Ch375WriteCmdPort(CMD_WR_USB_DATA7);/* 向CH375的端點(diǎn)緩沖區(qū)寫入準(zhǔn)備發(fā)送的數(shù)據(jù) */ Ch375WriteDataPort(len); /* 后續(xù)數(shù)據(jù)長度, len不能大于64 */ while(len--) { Ch375WriteDataPort(*buf); buf++; } } // 從CH37X讀出數(shù)據(jù)塊 UINT8 ReadUsbData( UINT8 *buf ) { UINT8 i, len,j; Ch375WriteCmdPort(CMD_RD_USB_DATA); /* 從CH375的端點(diǎn)緩沖區(qū)讀取接收到的數(shù)據(jù) */ len=Ch375ReadDataPort(); /* 后續(xù)數(shù)據(jù)長度 */ j=(len>64)? 64 : len; for ( i=0; i { *buf=Ch375ReadDataPort(); buf++; } return( len ); }
/************************************************************************************ 數(shù)據(jù)同步 USB的數(shù)據(jù)同步通過切換DATA0(奇數(shù)包)和DATA1(偶數(shù)包)實(shí)現(xiàn): 在設(shè)備端, USB設(shè)備可以自動切換; 在主機(jī)端, 必須由SET_ENDP6和SET_ENDP7命令控制CH375切換DATA0與DATA1. 主機(jī)端的程序處理方法是為設(shè)備端的各個端點(diǎn)分別提供一個全局變量, 初始值均為DATA0, 每執(zhí)行一次成功事務(wù)后取反, 每執(zhí)行一次失敗事務(wù)后將其復(fù)位為DATA1 *************************************************************************************/
/* 主機(jī)接收同步控制:0=DATA0,1=DATA1 */ void ToggleRecv(BOOL tog) { Ch375WriteCmdPort(CMD_SET_ENDP6); Ch375WriteDataPort(tog?0xC0:0x80); DelayNus(5); } void ToggleSend( BOOL tog ) /* 主機(jī)發(fā)送同步控制:0=DATA0,1=DATA1 */ { Ch375WriteCmdPort(CMD_SET_ENDP7); Ch375WriteDataPort(tog?0xC0:0x80); DelayNus(5); } /* 執(zhí)行USB事務(wù) */ BOOL IssueToken(UINT8 endp_and_pid) /* 高4位目的端點(diǎn)號, 低4位令牌PID */ { /* 執(zhí)行完成后, 將產(chǎn)生中斷通知單片機(jī), 如果是USB_INT_SUCCESS就說明操作成功 */ Ch375WriteCmdPort(CMD_ISSUE_TOKEN); Ch375WriteDataPort(endp_and_pid); return (WaitInterrupt()); /* 等待CH375操作完成 */ } /* // 執(zhí)行USB事務(wù),適用于CH375A UINT8 IssueTokenX(UINT8 endp_and_pid,UINT8 tog) { // 執(zhí)行完成后, 將產(chǎn)生中斷通知單片機(jī), 如果是USB_INT_SUCCESS就說明操作成功 Ch375WriteCmdPort(CMD_ISSUE_TKN_X); Ch375WriteDataPort(tog); //同步標(biāo)志的位7為主機(jī)端點(diǎn)IN的同步觸發(fā)位, 位6為主機(jī)端點(diǎn)OUT的同步觸發(fā)位, 位5~位0必須為0 Ch375WriteDataPort(endp_and_pid);// 高4位目的端點(diǎn)號, 低4位令牌PID return(WaitInterrupt()); }*/ //控制傳輸三個階段 UINT8 SetupStage(flash UINT8 *pag)//設(shè)置事務(wù) { tog_send=tog_recv=0;//復(fù)位USB數(shù)據(jù)同步標(biāo)志 ToggleSend(0);//SETUP階段為DATA0 WriteUsbFlashData(8,pag);//SETUP數(shù)據(jù)總是8字節(jié) return (IssueToken((0<<4)|DEF_USB_PID_SETUP)); } UINT8 DataStage()//輸入事務(wù) { ToggleRecv(1); //從接收器接收DATA1 return (IssueToken(( 0 << 4 ) | DEF_USB_PID_IN )); }
UINT8 StatusStage()//輸出事務(wù) {