您的位置:首页 > 其它

USB研究(三)U盘驱动中的中断

2009-07-11 15:02 483 查看
一、 USB中断:
中断服务程序为void ISP1160_Exception(void),主要是当USB插入时,对HC中的各中断寄存器中中断状态标志清0,并改变一些全局变量,如:g_event_marker,g_has_device
注:中断总是处于触发状态。
void ISP1160_Exception(void)

{

isr_USB_Hc(); // 与ISP116x驱动接口的中断处理函数

/* 以下与用户硬件相关 */

EXTINT = 0x04; // EINT2

VICVectAddr = 0;

}

ISP116x驱动接口的中断处理函数

void isr_USB_Hc( void )

{

unsigned short intr;//用来保存USB主控中断寄存器状态

unsigned short inter_en;//用来保存USB主控中断使能寄存器状态

disable();

inter_en = disable_Hc(); //保存状态,并关闭中断

intr = read_register16( Com16_HcuPInterrupt );//读取USB中断状态寄存器

clear_HcuPInterrupt_bit( intr );//写一清零

interrupt_handler_USB_Hc( intr & inter_en );//处理各USB主控中断

enable_Hc( inter_en ); //开启主控中断

enable();

}

USB主控中断判断及处理程序,对HcuPInterrupt中产生的各种中断源进行软件识别与处理着重于对HcuInterrupt_OPR_Reg位的处理。

void interrupt_handler_USB_Hc( unsigned short intr )

{

int i;

if ( intr & HcuInterrupt_AllEOTInterrupt )//判断是否通过PIO 传输或DMA 传输的数据传输已经完成,0x04

;

if ( intr & HcuInterrupt_SOFITInt )//0x01,判断SOF是否将长约1ms。HC控制的ITL缓冲必须进行读取操作。为了了解ITL缓冲区的状态,HcBufferStatus寄存器必须首先被读取。通过这种方式,微处理器可与HC进行ISO数据通信。

{

for ( i = 0; i < MAXMUM_NUMBER_OF_SOF_SERVICE_ROUTINE_METHOD; i++ )

if ( g_SOF_service_routine[ i ] )

(*g_SOF_service_routine[ i ])();

g_sof_counter = (g_sof_counter & 0xFFFF0000)

|(read_register32( Com32_HcFmNumber ) & 0x0000FFFF);

}

if ( intr & HcuInterrupt_ATLInt )//意味着微处理器必须从HC 读取ATL 数据。其要求HcBufferStatus 寄存器必须首先被读取。

{

for ( i = 0; i < MAXMUM_NUMBER_OF_SOF_SERVICE_ROUTINE_METHOD; i++ )

if ( g_ATLInt_service_routine[ i ] )

(*g_ATLInt_service_routine[ i ])();

}

if ( intr & HcuInterrupt_OPR_Reg )

{

unsigned long intr32;

intr32 = read_register32( Com32_HcInterruptStatus ); //读取USB事件中断状态寄存器

clear_HcInterruptStatus_bit( intr32 ); // 清中断源

HcuInterrupt_OPR_Reg_handler( intr32 );//对USB事件中断进行处理

}

if ( intr & HcuInterrupt_HCSuspend )

;

if ( intr & HcuInterrupt_ClkReady )

;

}

USB事件中断判断及处理程序,此函数中判断出是否有U盘的插入

void HcuInterrupt_OPR_Reg_handler( unsigned long cause )

{

unsigned long intr_stat;

unsigned long port_stat1;

unsigned long port_stat2;

intr_stat = cause & read_register32( Com32_HcInterruptEnable );

if ( intr_stat & HcInterruptStatus_SO )

;

if ( intr_stat & HcInterruptStatus_SF )

;

if ( intr_stat & HcInterruptStatus_RD )

;

if ( intr_stat & HcInterruptStatus_UE )

;

if ( intr_stat & HcInterruptStatus_RHSC )//当HcRhStatus 的内容或HcRhPortStatus[1:2]中的内容被更改时,该位被设

{

g_event_marker = ROOT_HUB_EVENT;//USB事件发生标志,第一次运行将使g_event_marke值变为0x80

++rhsc_event;//记录更改次数

port_stat1 = read_register32( Com32_HcRhPortStatus1 );//读取HcRhPortStatus[1:2]中的内容

port_stat2 = read_register32( Com32_HcRhPortStatus2 );

if(port_stat1&HcPortStatus_CSC || port_stat2&HcPortStatus_CSC)//CSC:当发生一次连接或断开事件时,该位被置位。

{

g_device_switch = 1;

g_has_device = port_stat1 & HcPortStatus_CCS + (port_stat2 & HcPortStatus_CCS)<<1;//记录两端口的状态

//清除状态装换位

clear_HcPortStatus_bit(HcPortStatus_CSC,1);

clear_HcPortStatus_bit(HcPortStatus_CSC,2);

}

}

if ( intr_stat & HcInterruptStatus_ATD )

;

if ( intr_stat & HcInterruptStatus_FNO )

g_sof_counter += (g_sof_counter & 0x00008000) ? 0 : (1L << 16);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: