ttzwater
驱动小牛
驱动小牛
  • 注册日期2003-06-07
  • 最后登录2011-10-04
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望23点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
阅读:1836回复:15

400分求教1161问题

楼主#
更多 发布于:2004-02-26 20:52
小弟正在用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));



}






mlw888
驱动牛犊
驱动牛犊
  • 注册日期2004-05-20
  • 最后登录2007-08-11
  • 粉丝0
  • 关注0
  • 积分192分
  • 威望20点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-05-20 10:57
老兄帮帮忙,我也在搞1161,我在发包的时候遇到同样的问题,就是ATL
写进去和读出来的一样,看你好像已经解决了,能否见告,不胜感激。
dragon_hn
驱动中牛
驱动中牛
  • 注册日期2002-05-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分297分
  • 威望40点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-05-20 21:11
你这样肯定不对了。
MAKE PTD的时候要将CompletetionCode置为0xFF,这样才知道该PTD有没有处理,你把PTD初始化为0,然后去读,如果HC没有对它处理,则读出的结果肯定还是0,也就不能证明是否处理!
www.dragon-2008.com 欢迎交流
dragon_hn
驱动中牛
驱动中牛
  • 注册日期2002-05-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分297分
  • 威望40点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-05-20 21:13
菲利普支持真差
 :P
www.dragon-2008.com 欢迎交流
ttzwater
驱动小牛
驱动小牛
  • 注册日期2003-06-07
  • 最后登录2011-10-04
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望23点
  • 贡献值0点
  • 好评度22点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-05-21 12:41
是啊是啊,我都按它例程做的,给它工程师写信也没得到正确的建议
mlw888
驱动牛犊
驱动牛犊
  • 注册日期2004-05-20
  • 最后登录2007-08-11
  • 粉丝0
  • 关注0
  • 积分192分
  • 威望20点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-05-27 08:42
ttzwater,我收到你的回信了,我上周就能读描述符了,但到今天还是只能单步执行,你说郁闷不郁闷。
mlw888
驱动牛犊
驱动牛犊
  • 注册日期2004-05-20
  • 最后登录2007-08-11
  • 粉丝0
  • 关注0
  • 积分192分
  • 威望20点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-05-29 08:04
在写ATL时要把握好时机,如果有冲突就不行
lingxscn
驱动牛犊
驱动牛犊
  • 注册日期2003-08-25
  • 最后登录2004-09-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-05-29 18:07
我正准备用,请多指教。
mlw888
驱动牛犊
驱动牛犊
  • 注册日期2004-05-20
  • 最后登录2007-08-11
  • 粉丝0
  • 关注0
  • 积分192分
  • 威望20点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-05-31 08:17
如果你还没开始,建议你改芯片,1161支持太差,使用起来会很困难,到时出不来不要怪我没提醒你
lingxscn
驱动牛犊
驱动牛犊
  • 注册日期2003-08-25
  • 最后登录2004-09-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-05-31 09:24
还有什么芯片可以用,要用做host.
yyouking
驱动老牛
驱动老牛
  • 注册日期2003-12-18
  • 最后登录2020-04-28
  • 粉丝0
  • 关注0
  • 积分967分
  • 威望114点
  • 贡献值1点
  • 好评度78点
  • 原创分0分
  • 专家分0分
  • 社区居民
10楼#
发布于:2004-10-18 10:23
给个做USB主机的方案建议,谢谢
提供: AT89S52+D12开发套件 W78E54+Sl811HST单片机读写U盘套件 PL2303HX-串口转USB 网站http://www.devking.cn 联系 sl811hs@yahoo.com.cn QQ:14441292
tsingkong
驱动牛犊
驱动牛犊
  • 注册日期2003-03-25
  • 最后登录2013-11-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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才知道,真玩意儿真不是好东西。
mailto:tsingkong@163.com
jasonx
驱动牛犊
驱动牛犊
  • 注册日期2002-11-30
  • 最后登录2005-12-17
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-07-19 17:34
HcBufferStatus寄存器是只读的,你怎么可以在Send_Ptd中写这个寄存器呢?
你的代码好像根1161编程手册上的差不多,编程手册上的那段可能是错的。
yingbohu
驱动牛犊
驱动牛犊
  • 注册日期2005-06-20
  • 最后登录2006-10-12
  • 粉丝0
  • 关注0
  • 积分47分
  • 威望7点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-07-26 10:24
可以用1362,程序改动不大,速度还快
stevenwin
驱动牛犊
驱动牛犊
  • 注册日期2008-03-29
  • 最后登录2008-07-02
  • 粉丝0
  • 关注0
  • 积分120分
  • 威望13点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
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)
liudingli
驱动牛犊
驱动牛犊
  • 注册日期2008-04-16
  • 最后登录2008-07-16
  • 粉丝4
  • 关注0
  • 积分213分
  • 威望33点
  • 贡献值2点
  • 好评度29点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2008-04-26 10:34
我们交流交流吧。我也正用ISP1161。QQ38012101
游客

返回顶部