stevenwin
驱动牛犊
驱动牛犊
  • 注册日期2008-03-29
  • 最后登录2008-07-02
  • 粉丝0
  • 关注0
  • 积分120分
  • 威望13点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
阅读:1810回复:2

ISP1161 host初始化问题

楼主#
更多 发布于:2008-04-01 16:47
ISP1161获取设备描述符的数据始终发不出去,我怀疑是ISP1161初始化的问题。请做过的朋友帮忙看一下,谢谢!


CPU:lpc2200 (ARM7)
void initHC()
{
   //检测主机控制器
   if( !CheckHC())
        return;
  
   //软件重新设置主机控制器,配置HcControl寄存器
    SoftResetHC();
    
    //配置HcHardwareConfiguration寄存器
    initHcHardwareConfiguration();
    
    //配置中断  
    initInterruptController();
  
    //配置HcFmInterval寄存器
    initHcFmInterval();
    
    //配置根集线器寄存器
    initHcRhDescriptorA();
    
    //设置ITL和ATL缓冲区长度
    setITL_ATL_length();
    
    //设置INT1中断服务程序
    
    
    //设置主机控制器为可操作的状态
    SetHC2Operate();
    
    //上述工作正常完成后,host就可以对device进行枚举了
}

//写端口(16位)
void outw(uint8 ADDR_16,uint16 RegCom_Data)
{
    (*((volatile uint16 *)(0x82000000+ADDR_16)) )=RegCom_Data;
}

//读端口(写16位)
uint16 inw(uint8 ADDR_16)
{
    uint16 temp;
   temp= (*((volatile uint16 *)(0x82000000+ADDR_16)) );
   return temp;
}

/*写32位寄存器*/
//输入:寄存器写命令,写的内容
//READ_32BIT_REG(HcCommandStatus);


uint32  READ_32BIT_REG(uint16 RegCom)
{
     uint32 temp;
     uint16 temp1;
     RegCom=RegCom|(0x00);
     outw(COMMAND_PORT,RegCom);
      temp1=inw(DATA_PORT);
      temp=inw(DATA_PORT);
      temp=(temp<<16)|(temp1);
  return temp;
}

//WRITE_32BIT_REG(hcCommandStatus, uValue);
void WRITE_32BIT_REG(uint16 RegCom,uint32 RegData)
{
    uint16 temp;
    RegCom=RegCom|(0x80);
    outw(COMMAND_PORT,RegCom);
    temp=RegData;
    outw(DATA_PORT,RegData);
    temp=RegData>>16;
    outw(DATA_PORT,RegData);
}
//WRITE_16BIT_REG(HcScratch, 0x55AA);
void WRITE_16BIT_REG(uint16 RegCom,uint16 RegData)
{
    RegCom=RegCom|(0x80);
    outw(COMMAND_PORT,RegCom);
    outw(DATA_PORT,RegData);
}

//READ_16BIT_REG(HcScratch);
uint16 READ_16BIT_REG(uint16 RegCom)
{
     uint16 temp;
     RegCom=RegCom|(0x00);
     outw(COMMAND_PORT,RegCom);
     temp=inw(DATA_PORT);
     return temp;
}

/*检测主机控制器是否存在*/
uint8 CheckHC()
{
    uint16 uData;
   // WRITE_16BIT_REG(HcScratch, 0x55AA);
   WRITE_16BIT_REG(HcScratch, 0x55AA);
    uData = READ_16BIT_REG(HcScratch);
  
    if (uData == 0x55AA)
    {
       uData = READ_16BIT_REG(HcChipID);
        // ISP1161x芯片ID的高字节
       if( (uData & 0xFF00) == 0x6100)
            return FoundISP1161x;
       else
            return NotFoundISP116x;  
            
    }
    else
        return NotFoundISP116x;        
}

//软件复位主机控制器
void SoftResetHC()
{
    uint32 uValue;
    
      //debug
    WRITE_16BIT_REG(HcTransferCounter, 0x0040);
   uValue = READ_16BIT_REG(HcTransferCounter);
    
    //读HcCommandStatus寄存器的内容
    uValue = READ_32BIT_REG(HcCommandStatus);
    //设置HCR位
    uValue |= 0x00000001;
    WRITE_32BIT_REG(HcCommandStatus, uValue);
    //等,直到复位完成。当复位完成时,HCR位被设置为逻辑0。
   while (READ_32BIT_REG(HcCommandStatus) & 0x00000001);
  
  
   /*****************设置为复位状态*********************************/
   uValue = READ_32BIT_REG(HcControl);
   //当写一个新的值到HcControl寄存器时寄存器中其它位的状态必须保留(通过写1到寄存器中已置位的位)。
    uValue &= ~0x000000C0;
    // 00B in bit[7:6] => RESET state
    uValue |= 0x00000000;
    WRITE_32BIT_REG (HcControl, uValue);
  
  //debug  
  READ_32BIT_REG(HcControl);  

}

//配置HcHardwareConfiguration 寄存器
void initHcHardwareConfiguration()
{
    uint32 uData;
    uData = READ_16BIT_REG(HcHardwareConfiguration);
    //高电平有效使能全局中断管脚INT1。
    uData |= (INTERRUPT_PIN_ENABLE | INTERRUPT_OUTPUT_POLARITY);
    WRITE_16BIT_REG(HcHardwareConfiguration, uData);
    
}

//配置中断
void initInterruptController()
{
    //清除所有等待的中断
    WRITE_16BIT_REG(HcuPInterrupt, 0xFFFF);
    
    // 使能OPR和SOF中断。
    WRITE_16BIT_REG(HcuPInterruptEnable, OPR_Reg | SOFITLInt);
    // 禁能所有USB指定的中断。
    WRITE_32BIT_REG(HcInterruptDisable, 0x0000007F);
    
    // 使能SOF和主机中断。
    WRITE_32BIT_REG(HcInterruptEnable, SF | RHSC | MIE);
    
    /*
   //以下代码就是用来清除根集线器状态变化(RHSC)的中断位:
    WRITE_32BIT_REG (HcInterruptStatus, RHSC);
    以下代码就是用来清除OPR_Reg中断:
    WRITE_16BIT_REG (Hc.PInterrupt, OPR_Reg);
    */
}

//配置HcFmInterval 寄存器
void initHcFmInterval()
{
    WRITE_32BIT_REG (HcFmInterval, 0x2EDF | (0x2778 << 16));
}

//配置根集线器寄存器A,B
void initHcRhDescriptorA()
{
    /*初始化HcRhDescriptorA寄存器*/
    uint32 uData;
    uData = 0x00000200 ;
    // 必须使用一个偶数值。
    uData |= ((POWER_ON_TO_POWER_GOOD_TIME / 2) << 24);
    WRITE_32BIT_REG (HcRhDescriptorA, uData);
    
    /*初始化HcRhStatus寄存器*/
    // LPSC <= 1
    uData = 0x00010000;
    WRITE_32BIT_REG(HcRhStatus, uData);
    
    
    //初始化HcRhDescriptorB寄存器的程序如下:
    WRITE_32BIT_REG(HcRhDescriptorB, 0x00000000);
    
}

//设置ITL 和ATL 缓冲区长度
void setITL_ATL_length()
{
    WRITE_16BIT_REG (HcITLBufferLength, 1024);
    WRITE_16BIT_REG (HcATLBufferLength, 2048);

}

//设置INT1 中断服务程序
/*void initHostInterrupt()
{
  
    //P0.15设置为外部中断2
    PINSEL0=PINSEL1&0x3FFFFFFF;
    PINSEL1=PINSEL1|0x80000001;
    
    VICVectCntl1=(0x20|0x10);
    VICVectAddr1=(INT32U)ISP1160_Handler;//设置EINT0向量地址
    VICIntEnable=1<<16;//允许EINT2
    
    
}*/

//设置主机控制器为可操作的状态
void SetHC2Operate()
{
    uint32 uValue;
    uValue = READ_32BIT_REG(HcControl);
    //当在HcControl寄存器中写入一个新的值时,寄存器中其它位的状态必须通过向已被置位的位写入0来保留
    uValue &= 0x000000C0;
    // 位[7:6]中的10B =>可操作的状态
    uValue |= 0x00000080;
    WRITE_32BIT_REG (HcControl, uValue);
    
    //debug
    READ_32BIT_REG(HcControl);
}
发送枚举数据的程序在http://bbs.driverdevelop.com/htm_data/9/0803/110080.html
liudingli
驱动牛犊
驱动牛犊
  • 注册日期2008-04-16
  • 最后登录2008-07-16
  • 粉丝4
  • 关注0
  • 积分213分
  • 威望33点
  • 贡献值2点
  • 好评度29点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-04-26 10:29
我们交流交流吧。我也正用ISP1161。QQ38012101
huhaiy97
驱动牛犊
驱动牛犊
  • 注册日期2002-10-01
  • 最后登录2009-05-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望12点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-04-15 15:33
似乎问题出在这两句吧,不知你寄存器读出来没有?
void outw(uint8 ADDR_16,uint16 RegCom_Data)
{
    (*((volatile uint16 *)(0x82000000+ADDR_16)) )=RegCom_Data;
}

//读端口(写16位)
uint16 inw(uint8 ADDR_16)
{
    uint16 temp;
  temp= (*((volatile uint16 *)(0x82000000+ADDR_16)) );
  return temp;
}
游客

返回顶部