📄 hostdriver.c
字号:
#include "HCDriver.h"
//写端口(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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -