阅读:1810回复:2
ISP1161 host初始化问题
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。 |
|
沙发#
发布于:2008-04-26 10:29
我们交流交流吧。我也正用ISP1161。QQ38012101
|
|
板凳#
发布于: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; } |
|