📄 usbh_hcds_72v05.c
字号:
RegClear(REG08_H_Reset, BIT_ResetHTM);
/*=====================================/
Initialize the register that can be controlled even if it is asynchronous
/=====================================*/
RegClear(REG08_MainIntEnb, BIT_EnHostIntStat);
RegWrite(REG08_HostIntEnb, 0x00);
RegClear(REG08_H_USB_Control, BIT_VBUS_Enb);
RegWrite(REG08_H_XcvrControl, ((TERM_SELECT_FS << 7)|(XCVR_SELECT_FS << 4)|(OPMODE_NON_DRIVING)));
SavePortSpeed = 1;
}
/*=============================================================================================
// Function_Name: USBH_HCDS_HCRegisterPortInterrupt
//
// description : Register the callback used for the port interrupt notification
//
// Register the callback which is called when VBUS is changed with the device side connector
//
// argument : pfnCallback (in)Pointer of callback function which is called when VBUS is changed
//
// return : None
===============================================================================================*/
void USBH_HCDS_HCRegisterPortInterrupt( CALLBACK_PROC pfnCallback )
{
HCStatus.pfnPortInterruptCallback = pfnCallback;
}
/*=============================================================================================
// Function_Name: USBH_HCDS_HCInterrupt
//
// description : Host Controller interrupt process
//
// The interrupt of Host Controller is processed
//
// argument : None
//
// return : None
===============================================================================================*/
void USBH_HCDS_HCInterruptProc( void )
{
volatile unsigned char savedMainIntStat;
volatile unsigned char savedDeviceIntStat;
volatile unsigned char savedHostIntStat;
volatile unsigned char savedCPU_IntStat;
volatile unsigned char savedH_SIE_IntStat_0;
volatile unsigned char savedH_SIE_IntStat_1;
volatile unsigned char savedH_FIFO_IntStat;
volatile unsigned char savedH_FrameIntStat;
volatile unsigned char savedH_CHrIntStat;
volatile REG_rxH_CHxWindow *prxH_CHxWindow;
volatile unsigned short *prsH_CHxWindow;
volatile unsigned char *prcH_CHxIntStat;
URB_INFO *psURBInfo;
unsigned char indexCH;
unsigned char portSpeed;
unsigned long remainDataSize;
portSpeed = 0; // Countermeasure against warning of optimizing
/*=============================/
Save the main interrupt status/
/=============================*/
savedMainIntStat = RegRead(REG08_MainIntStat) & RegRead(REG08_MainIntEnb);
RegWrite(REG08_MainIntStat, savedMainIntStat);
/*=========================/
Each interrupt status processing/
/=========================*/
if( savedMainIntStat & MASK_FinishedPM ){
/* Power Management transfer finish */
RegClear(REG08_MainIntEnb, BIT_EnFinishedPM); /* Disable FinishedPM interrupt */
USBH_HCDS_ExecCallback(HCStatus.pfnPMFinishedCallback,
(RegRead(REG08_PM_Control_1)&MASK_PM_State)>>SHIFT_PM_State,
0,
NULL);
}
if(savedMainIntStat & MASK_CPU_IntStat){
/* There is CPU interrupt */
/*==========================/
Save the CPU interrupt status/
/==========================*/
savedCPU_IntStat= RegRead(REG08_CPU_IntStat) & RegRead(REG08_CPU_IntEnb);
RegWrite(REG08_CPU_IntStat, savedCPU_IntStat);
/* Clear the saved interrupt status */
savedCPU_IntStat = 0x00;
}
if( savedMainIntStat & MASK_HostIntStat ){
/* There is Host interrupt */
/*===========================/
Save the Host interrupt status/
/===========================*/
savedHostIntStat = RegRead(REG08_HostIntStat) & RegRead(REG08_HostIntEnb);
RegWrite(REG08_HostIntStat, savedHostIntStat);
if( savedHostIntStat & MASK_H_CHrIntStat ){
/* There is CHr interrupt */
/*==========================/
Save the CHr interrupt status/
/==========================*/
savedH_CHrIntStat = RegRead(REG08_H_CHrIntStat) & RegRead(REG08_H_CHrIntEnb);
for( indexCH = 1; indexCH < NUM_USB_CH; indexCH++ ){
/* Detect the CH interrupt*/
if( savedH_CHrIntStat & (1 << (indexCH - 1)) ){
/*==============================/
Check the CHr interrupt status/
/==============================*/
CheckCHxIntStat(indexCH);
}
}
/* Clear the saved interrupt status */
savedH_CHrIntStat = 0x00;
}
if( savedHostIntStat & MASK_H_CH0IntStat ){
/* There is CH0 interrupt */
/*==============================/
Check the CHr interrupt status/
/==============================*/
indexCH = 0;
CheckCHxIntStat(indexCH);
}
if( savedHostIntStat & MASK_H_FIFO_IntStat ) {
/* There is FIFO interrupt */
/*===========================/
Save the FIFO interrupt status/
/===========================*/
savedH_FIFO_IntStat = RegRead(REG08_H_FIFO_IntStat) & RegRead(REG08_H_FIFO_IntEnb);
RegWrite(REG08_H_FIFO_IntStat, savedH_FIFO_IntStat);
if( savedH_FIFO_IntStat & MASK_H_FIFO0_Cmp ){
/* FIFO emptied after DMA0 transfer finish */
RegClear( REG08_H_FIFO_IntEnb, BIT_EnFIFO0_Cmp); /* Disable the FIFO0_Cmp interrupt */
indexCH = DMATransactionEnd(0);
if( indexCH == 0 ){
/* Control transfer channel */
if( RegRead(REG08_H_CH0IntStat) & BIT_CTL_SupportCmp){
TransactionEnd(indexCH);
} else {
RegSet(REG08_H_CH0IntEnb, (BIT_EnCTL_SupportCmp | BIT_EnCTL_SupportStop));
}
} else if( URBInfo[indexCH].bmTranFlags.supportBO == 1 ){
/* The Bulk-Only support function is in using*/
if( RegRead(REG08_H_CHaIntStat) & BIT_BO_SupportCmp ){
TransactionEnd(indexCH);
} else {
RegSet(REG08_H_CHaIntEnb, (BIT_EnBO_SupportCmp | BIT_EnBO_SupportStop));
}
} else {
TransactionEnd(indexCH);
}
}
if( savedH_FIFO_IntStat & MASK_H_FIFO1_Cmp ){
/* FIFO emptied after DMA1 transfer finish */
RegClear(REG08_H_FIFO_IntEnb, BIT_EnFIFO1_Cmp); /* Disable the FIFO0_Cmp interrupt */
indexCH = DMATransactionEnd(1);
if( indexCH == 0 ){
/* Control transfer channel */
if( RegRead(REG08_H_CH0IntStat) & BIT_CTL_SupportCmp ){
TransactionEnd(indexCH);
} else {
RegSet(REG08_H_CH0IntEnb, (BIT_EnCTL_SupportCmp | BIT_EnCTL_SupportStop));
}
} else if( URBInfo[indexCH].bmTranFlags.supportBO == 1 ){
/* The Bulk-Only support function is in using*/
if( RegRead(REG08_H_CHaIntStat) & BIT_BO_SupportCmp ){
TransactionEnd(indexCH);
} else {
RegSet(REG08_H_CHaIntEnb, (BIT_EnBO_SupportCmp | BIT_EnBO_SupportStop));
}
} else {
TransactionEnd(indexCH);
}
}
if( savedH_FIFO_IntStat & MASK_H_FIFO_IDE_Cmp ){
/* FIFO emptied after DirectCopy transfer finish */
/* DirectCopy execution Channel index */
for( indexCH = 1; indexCH < NUM_USB_CH; indexCH++ ){
REG_H_CHX_WINDOW_ADDR(prsH_CHxWindow, indexCH);
prxH_CHxWindow = (volatile REG_rxH_CHxWindow *)prsH_CHxWindow;
if( RegRead(&prxH_CHxWindow->rcH_CHxJoin) & BIT_JoinIDE ) break;
}
/* IDE is transferred again when the USB transfer still remains*/
remainDataSize = ( RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_H) << 16) & 0xFFFF0000;
remainDataSize += RegRead(&prxH_CHxWindow->rsH_CHxTotalSize_L);
if(remainDataSize == 0) {
RegClear(REG08_H_FIFO_IntEnb, BIT_EnFIFO_IDE_Cmp); /* Disable the FIFO_IDE_Cmp interrupt */
if( URBInfo[indexCH].bmTranFlags.supportBO == 1 ){
/* The Bulk-Only support function is in using*/
if( RegRead(REG08_H_CHaIntStat) & BIT_BO_SupportCmp ){
TransactionEnd(indexCH);
} else {
RegSet(REG08_H_CHaIntEnb, (BIT_EnBO_SupportCmp | BIT_EnBO_SupportStop));
}
} else {
TransactionEnd(indexCH);
}
}
}
/* Clear the saved interrupt status */
savedH_FIFO_IntStat = 0x00;
}
if( savedHostIntStat & MASK_H_FrameIntStat ){
/* There is Frame interrupt */
/*============================/
Save the Frame interrupt status/
/============================*/
savedH_FrameIntStat = RegRead(REG08_H_FrameIntStat) & RegRead(REG08_H_FrameIntEnb);
RegWrite(REG08_H_FrameIntStat,savedH_FrameIntStat);
if( savedH_FrameIntStat & MASK_PortErr ){
/* Port error happened*/
RegWrite(REG08_H_NegoControl_0, NEGO_AUTO_MODE_CANCEL);
while( RegRead( REG08_H_NegoControl_0) & MASK_AutoModeCancel );
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_DISABLED, USBH_HCDS_PORT_SPEED_MODE_UNKNOWN, NULL );
}
if( savedH_FrameIntStat & MASK_SOF ){
if( HCStatus.bmSOFCheck != 0 ){
for( indexCH = 1; indexCH < NUM_USB_CH; indexCH++ ){
if( (HCStatus.bmSOFCheck & (1 << indexCH)) != 0 ){
psURBInfo = &URBInfo[indexCH];
psURBInfo->waitSOFCount--;
if( psURBInfo->waitSOFCount == 0 ){
HCStatus.bmSOFCheck &= ~(1 << indexCH);
USBH_HCDS_HCTranGo(psURBInfo->psUrb, indexCH, psURBInfo->pfnCallback);
}
}
}
} else {
RegClear(REG08_H_FrameIntEnb, BIT_EnSOF);
}
}
/* Clear the saved interrupt status */
savedH_FrameIntStat = 0x00;
}
if( savedHostIntStat & MASK_H_SIE_IntStat_0 ){
/* There is SIE interrupt 0*/
/*===========================/
Save the SIE interrupt status 0/
/===========================*/
savedH_SIE_IntStat_0 = RegRead(REG08_H_SIE_IntStat_0) & RegRead(REG08_H_SIE_IntEnb_0);
RegWrite(REG08_H_SIE_IntStat_0, savedH_SIE_IntStat_0);
if( savedH_SIE_IntStat_0 & MASK_DetectDevChirpNG ){
/* Check device Chirp and if NG operation */
RegClear(REG08_H_SIE_IntEnb_0, BIT_EnDetectDevChirpNG); /* Disable the DetectDevChirpNG interrupt */
HCStatus.bmFlags.chirpNG = 1;
}
if( savedH_SIE_IntStat_0 & MASK_DetectDevChirpOK ){
/* Check device Chirp and if OK operation */
RegClear(REG08_H_SIE_IntEnb_0, BIT_EnDetectDevChirpOK); /* Disable the DetectDevChirpOK interrupt */
HCStatus.bmFlags.chirpNG = 0;
}
if( savedH_SIE_IntStat_0 & MASK_DetectRmtWkup ){
/* Detect remote wake-up */
RegClear(REG08_H_SIE_IntEnb_0, BIT_EnDetectRmtWkup); /* Disable the DetectRmtWkup interrupt */
USBH_HCDS_HCPortGoResume();
}
if( savedH_SIE_IntStat_0 & MASK_DetectDiscon ){
/* Detect the disconnection of device */
RegClear(REG08_H_SIE_IntEnb_0, BIT_EnDetectDiscon); /* Disable the DetectDiscon interrupt */
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_DISCONNECTED, USBH_HCDS_PORT_SPEED_MODE_UNKNOWN, NULL );
}
if( savedH_SIE_IntStat_0 & MASK_DetectCon ){
/* Detect the connection of device */
RegClear(REG08_H_SIE_IntEnb_0, BIT_EnDetectCon); /* Disable the DetectCon interrupt */
/* The connection of the device is reported by DisabledCmp */
}
/* Clear the saved interrupt status */
savedH_SIE_IntStat_0 = 0x00;
}
if( savedHostIntStat & MASK_H_SIE_IntStat_1 ){
/* There is SIE interrupt 1*/
/*===========================/
Save the SIE interrupt status 1/
/===========================*/
savedH_SIE_IntStat_1 = RegRead(REG08_H_SIE_IntStat_1) & RegRead(REG08_H_SIE_IntEnb_1);
RegWrite(REG08_H_SIE_IntStat_1, savedH_SIE_IntStat_1);
if( savedH_SIE_IntStat_1 & MASK_ResetCmp ){
/* Port reset finished */
RegClear( REG08_H_SIE_IntEnb_1, BIT_EnResetCmp); /* Disable the ResetCmp interrupt */
RegSet( REG08_H_FrameIntEnb, BIT_EnPortErr); /* Enable the PortErr interrupt */
SavePortSpeed = 1;
switch( (RegRead(REG08_H_NegoControl_1) & MASK_PortSpeed)>>SHIFT_PortSpeed ){
case NEGO_PORTSPEED_HIGH:
portSpeed = USBH_HCDS_PORT_SPEED_MODE_HIGH;
break;
case NEGO_PORTSPEED_FULL:
portSpeed = USBH_HCDS_PORT_SPEED_MODE_FULL;
break;
case NEGO_PORTSPEED_LOW:
portSpeed = USBH_HCDS_PORT_SPEED_MODE_LOW;
break;
}
if( HCStatus.bmFlags.chirpNG == 1 ){
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_DISABLED, portSpeed, NULL );
} else {
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_ENABLED, portSpeed, NULL );
}
}
if( savedH_SIE_IntStat_1 & MASK_SuspendCmp ){
/* Port suspend finished */
RegClear(REG08_H_SIE_IntEnb_1, BIT_EnSuspendCmp); /* Disable the SuspendCmp interrupt */
USBH_HCDS_ExecCallback(HCStatus.pfnPortInterruptCallback, USBH_HCDS_PORT_ST_SUSPENDED, USBH_HCDS_PORT_SPEED_MODE_UNKNOWN, NULL );
}
if( savedH_SIE_IntStat_1 & MASK_ResumeCmp ){
/* Port resume finished */
RegClear( REG08_H_SIE_IntEnb_1, BIT_EnResumeCmp); /* Disable the ResumeCmp interrupt */
/*===============================/
Resume all of channels that were run/
/===============================*/
for( indexCH = 0; indexCH < NUM_USB_CH; indexCH++ ){
psURBInfo = &URBInfo[indexCH];
if( psURBInfo->bmTranFlags.tranGo == 1 ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -