阅读:1836回复:15
400分求教1161问题
小弟正在用PHILIPS1161做USB HOST的开发,遇到一问题始终过不去,请大家帮帮忙
问题描述如下: 我们可以发送ptd包,而且ptd包也的执行了(CompletionCode[3:0]:0000), 但是我们在第一次读取设备描述符的时候,出来的结果不对。 应该返回的正确数据是: 0112,0100 00DC 1000 0471 0666 0100 0000 但是我们返回的数据是: 0000 0000 0000 0000 0000 0000 0000 0001 我们读取设备描述符的程序如下: void FirstGetDeviceDescriptor(char addr) { unsigned int cbuf_ptr[8]; unsigned int rb_ptr[8]; unsigned int cbuf_ptr2[12]; unsigned int rb_ptr2[12]; unsigned int cbuf_ptr3[8]; unsigned int rb_ptr3[8]; write_16bit_reg(0x24,0x04); //Clear EOT interrupt bit //send SETUP packet make_ptd(cbuf_ptr,(char)SETUP,1,0,8,0,addr); *(cbuf_ptr+4)=0x0680; *(cbuf_ptr+5)=0x0100; *(cbuf_ptr+6)=0x0000; *(cbuf_ptr+7)=0x0040; send_ptd(cbuf_ptr,rb_ptr,16); //send IN packet make_ptd(cbuf_ptr2,(char)IN,1,0,16,1,addr); *(cbuf_ptr2+4)=0x0000; *(cbuf_ptr2+5)=0x0000; *(cbuf_ptr2+6)=0x0000; *(cbuf_ptr2+7)=0x0000; *(cbuf_ptr2+8)=0x0000; *(cbuf_ptr2+9)=0x0000; *(cbuf_ptr2+10)=0x0000; *(cbuf_ptr2+11)=0x0000; send_ptd(cbuf_ptr2,rb_ptr2,24); //send OUT packet make_ptd(cbuf_ptr3,(char)OUT,1,0,0,1,addr); *(cbuf_ptr3+4)=0x0000; *(cbuf_ptr3+5)=0x0000; *(cbuf_ptr3+6)=0x0000; *(cbuf_ptr3+7)=0x0000; send_ptd(cbuf_ptr3,rb_ptr3,16); } void make_ptd(unsigned int *rptr, char type_ptd,char last,char ep,unsigned int max,char tog,char addr) { PTD ptd2send; int port1speed ; PortSpeed=1; if(toggle==0) { tog=1; toggle=1; } else { tog=0; toggle=0; } ptd2send.CompletetionCode=0x0; // Set Completion Code = 0000. No Errors. ptd2send.active_bit=1; // Enable execution of transactions by the Host Controller. ptd2send.toggle=tog; ptd2send.ActualBytes=0; // Set to zero. This field is filled by the Host Controller to // reflect how many bytes are sent or received. ptd2send.endpoint=ep; ptd2send.last_ptd=last; ptd2send.speed=PortSpeed; // Indicates speed of the endpoint ptd2send.MaxPacketSize=max; ptd2send.TotalBytes=max; ptd2send.pid= type_ptd; ptd2send.format=0; ptd2send.fm=0; ptd2send.FunctionAddress=addr; *(rptr+0) = (ptd2send.CompletetionCode & 0x0000)<<12 |(ptd2send.active_bit & 0x0001)<<11 |(ptd2send.toggle & 0x0001)<<10 // Shift bit 10 bits to the left |(ptd2send.ActualBytes & 0x03FF); // 10 bits of ActualBytes in bytes 0 and 1 // of PTD *(rptr+1) = (ptd2send.endpoint & 0x000F)<<12 |(ptd2send.last_ptd & 0x0001)<<11 |(ptd2send.speed & 0x0001)<<10 |(ptd2send.MaxPacketSize & 0x03FF); // 10 bits of MaxPacketSize in bytes 1 and 2 // of PTD *(rptr+2) = (0x0000 & 0x000F)<<12 |(ptd2send.pid & 0x0003)<<10 |(ptd2send.TotalBytes & 0x03FF); // 10 bits of TotalSize in bytes 3 // and 4 of PTD *(rptr+3) = (ptd2send.fm & 0x00FF)<<8 |(ptd2send.format & 0x0001)<<7 |(ptd2send.FunctionAddress & 0x007F); } void send_ptd(unsigned int *a_ptr,unsigned int *r_ptr,unsigned short data_size) { unsigned int abuf[64],*nptr; int port1speed,wait_time;//unsafed !!! int active_bit,cnt; int count; unsigned short temp; unsigned short temp1; unsigned long temp2; unsigned long data,data2; unsigned short remain_number; port1speed=1;//unsafed !!! wait_time=100; //unsafed !!! remain_number = 0; if(data_size%2==0) count=data_size/2; else count=data_size/2+1; for(remain_number=0;remain_number<count;remain_number++) { abuf[remain_number]=*(a_ptr+remain_number); } nptr=abuf; write_atl(nptr,data_size); // Write data_size bytes write_16bit_reg(HcBufferStatus,0x20); for(temp1=0;temp1<4000;temp1++) { temp1=temp1+1; } do { if(PortSpeed==1) {read_atl(r_ptr,data_size);} // Read data_size bytes if(PortSpeed==0) {read_atl(r_ptr,4*data_size);} // Read data_size*4 bytes active_bit=(*r_ptr)&(0x0800); // Check active bit. The Host Controller sets the // bit to 0 after PTD is finished active_bit=active_bit>>11; cnt--; pwait(wait_time); } while((cnt>0) && (active_bit!=0)); } |
|
沙发#
发布于:2004-05-20 10:57
老兄帮帮忙,我也在搞1161,我在发包的时候遇到同样的问题,就是ATL
写进去和读出来的一样,看你好像已经解决了,能否见告,不胜感激。 |
|
板凳#
发布于:2004-05-20 21:11
你这样肯定不对了。
MAKE PTD的时候要将CompletetionCode置为0xFF,这样才知道该PTD有没有处理,你把PTD初始化为0,然后去读,如果HC没有对它处理,则读出的结果肯定还是0,也就不能证明是否处理! |
|
|
地板#
发布于:2004-05-20 21:13
菲利普支持真差
:P |
|
|
地下室#
发布于:2004-05-21 12:41
是啊是啊,我都按它例程做的,给它工程师写信也没得到正确的建议
|
|
5楼#
发布于:2004-05-27 08:42
ttzwater,我收到你的回信了,我上周就能读描述符了,但到今天还是只能单步执行,你说郁闷不郁闷。
|
|
6楼#
发布于:2004-05-29 08:04
在写ATL时要把握好时机,如果有冲突就不行
|
|
7楼#
发布于:2004-05-29 18:07
我正准备用,请多指教。
|
|
8楼#
发布于:2004-05-31 08:17
如果你还没开始,建议你改芯片,1161支持太差,使用起来会很困难,到时出不来不要怪我没提醒你
|
|
9楼#
发布于:2004-05-31 09:24
还有什么芯片可以用,要用做host.
|
|
10楼#
发布于:2004-10-18 10:23
给个做USB主机的方案建议,谢谢
|
|
|
11楼#
发布于:2005-01-17 16:31
write_16bit_reg(0x24,0x04); //Clear EOT interrupt bit
//send SETUP packet make_ptd(cbuf_ptr,(char)SETUP,1,0,8,0,addr); *(cbuf_ptr+4)=0x0680; *(cbuf_ptr+5)=0x0100; *(cbuf_ptr+6)=0x0000; *(cbuf_ptr+7)=0x0040; 最后为什么是40呢?真奇怪。我的是08 用过ISP1161才知道,真玩意儿真不是好东西。 |
|
|
12楼#
发布于:2005-07-19 17:34
HcBufferStatus寄存器是只读的,你怎么可以在Send_Ptd中写这个寄存器呢?
你的代码好像根1161编程手册上的差不多,编程手册上的那段可能是错的。 |
|
13楼#
发布于:2005-07-26 10:24
可以用1362,程序改动不大,速度还快
|
|
14楼#
发布于:2008-03-31 16:58
回 楼主(ttzwater) 的帖子
ISP1161host问题求助我正在用PHILIPS1161做USB HOST的开发,遇到一问题始终过不去,请大家帮帮忙 void USB_Host_Exception() { uint8 i; //uint16 temp; uint32 st1,st2,ist; uint8 addr; addr=0; st1= READ_32BIT_REG(HcRhPortStatus1); st2= READ_32BIT_REG(HcRhPortStatus2); ist=READ_32BIT_REG(HcInterruptStatus); /* if((st1&0x0200)||(st2&0x0200)) device_speed=low_speed; else device_speed=full_speed;*/ device_speed=1; if((st1&0x00000001)||(st2&0x00000001))//有设备连上,则进行枚举 { WRITE_32BIT_REG(HcuPInterrupt,0x04); //Clear EOT interrupt bit //第一个控制建立数据包Setup make_control_ptd((uint16 *)c_ptd,0x00,1,0,64,0,addr); send_control(c_ptd,rb_ptr,0x0680,0x0100,0x0000,0x0012,16); //IN make_control_ptd((uint16 *)c_ptd,0x01,1,0,64,1,addr); send_control(c_ptd,rb_ptr,0x0000,0x0000,0x0000,0x0000,8); //out空包 make_control_ptd((uint16 *)c_ptd, 0x02, 1, 0, 64,1,addr); send_control(c_ptd,rb_ptr,0x0000,0x0000,0x0000,0x0000,8); //发送0长度包来结束传输 } } void write_atl(uint16 *a_ptr, uint16 data_size) { uint32 cnt; uint16 temp; WRITE_16BIT_REG(HcTransferCounter,data_size*2); //debug // WRITE_16BIT_REG(HcTransferCounter, 0x0040); temp = READ_16BIT_REG(HcTransferCounter); if(temp==0) return; //debug //读HcBufferStatus Register READ_16BIT_REG(HcBufferStatus);//此时bit[2]为0,empty outw(COMMAND_PORT,HcATLBufferPort|0x80); //关中断 interrupt_disable(); cnt=0; do { outw(DATA_PORT,*(a_ptr+cnt)); cnt++; outw(DATA_PORT,*(a_ptr+cnt)); cnt++; } // while(cnt<(data_size)); while(cnt<(data_size/2)); //开中断 interrupt_enable(); //debug //读HcBufferStatus Register READ_16BIT_REG(HcBufferStatus);//此时bit[2]为1,full //debug outw(COMMAND_PORT,HcATLBufferPort); for(temp=0;temp<16;temp++){ inw(DATA_PORT);} } void read_atl(uint16 *a_ptr, uint16 data_size) { uint32 cnt; WRITE_16BIT_REG(HcTransferCounter,data_size*2); outw(COMMAND_PORT,HcATLBufferPort); cnt=0; do { *(a_ptr+cnt)=inw(DATA_PORT); cnt++; } while(cnt<(data_size)); } void make_control_ptd(uint16 *rptr,uint8 type_ptd,uint8 last,uint8 ep,uint32 max,uint8 tog,uint8 addr) { //ptd2send.CompletetionCode=0x0; //设置完成代码 = 0000。 无错误。 ptd2send.CompletetionCode=0xF; ptd2send.active_bit=1; //使能主机控制器执行的传输 ptd2send.toggle=tog; ptd2send.ActualBytes=0; //设为0。该字段被主机控制器填充,反映了发送或接收的字节数 ptd2send.endpoint=ep; ptd2send.last_ptd=1; ptd2send.speed=device_speed; ptd2send.MaxPacketSize=max; ptd2send.TotalBytes=max; ptd2send.pid_type= type_ptd; ptd2send.format=0; ptd2send.fm=0; ptd2send.FunctionAddress=addr; //PTD的字节0和1的10位ActualBytes //rptr[0]= (ptd2send.CompletetionCode &0x0000)<<12|(ptd2send.active_bit &0x0001)<<11|(ptd2send.toggle &0x0001)<<10 |(ptd2send.ActualBytes &0x03FF); rptr[0]= (ptd2send.CompletetionCode &0xFFFF)<<12|(ptd2send.active_bit &0x0001)<<11|(ptd2send.toggle &0x0001)<<10 |(ptd2send.ActualBytes &0x03FF); // PTD的字节1和2的10位MaxPacketSize rptr[1]= (ptd2send.endpoint &0x000F)<<12|(ptd2send.last_ptd &0x0001)<<11|(ptd2send.speed &0x0001)<<10|(ptd2send.MaxPacketSize&0x03FF); // PTD的字节3和4的10位TotalSize rptr[2]= (0x0000 &0x000F)<<12|(ptd2send.pid_type &0x0003)<<10|(ptd2send.TotalBytes &0x03FF); rptr[3]= (ptd2send.fm &0x00FF)<<8|(ptd2send.format &0x0001)<<7|(ptd2send.FunctionAddress &0x007F); } void send_control(uint16 *a_ptr,uint16 *r_ptr,uint16 d0,uint16 d1,uint16 d2,uint16 d3,uint32 send_bytes) { uint32 cnt=8; uint8 active_bit; uint16 send_words; uint16 i; abuf[0]=*(a_ptr+0); abuf[1]=*(a_ptr+1); abuf[2]=*(a_ptr+2); abuf[3]=*(a_ptr+3); abuf[4]=d0; abuf[5]=d1; abuf[6]=d2; abuf[7]=d3; send_words=send_bytes/2; write_atl(abuf,send_words); do { if(ptd2send.speed==1)// 读16字节 {read_atl(r_ptr, 16);} else// 读72字节 {read_atl(r_ptr,72);} active_bit=(*r_ptr)&(0x0800); // 检查有效位。PTD结束后主机控制器将该位清零。 active_bit=active_bit>>11; // cnt--; } //while((cnt>2) && (active_bit!=0)); while(active_bit!=0); } 现在能看到数据写进ATL缓冲区,再读出来的时候,completion code=00,标识发送无误,但数据包始终没有发送出去?还有一个问题就是,读出的数据的PIDDirection怎么都是01(IN)? 附件中是读ATL缓冲区时在中断中看到的数据(处理器:LPC2200) |
|
15楼#
发布于:2008-04-26 10:34
我们交流交流吧。我也正用ISP1161。QQ38012101
|
|