📄 hnp.c
字号:
hnp->workingState = OTG242HNP_B_PERIPHERAL;
}
}
}
/***********************************************************
V Bus error,
***********************************************************/
if(status & OTG242_INTR_VBUSERROR)
{
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP:V Bus Err S32 \r\n");
if (hnp->otgPortMode == OTG242_MODE_HF_SOFTWARE_HNP)
{
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP:V Bus error\r\n");
}
else
{
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP:V Bus error, hardware mode\r\n");
hnpStatus = OTG242HNP_ReadReg(hnp, OTG242HNP_CTRL);
if ((hnpStatus & OTG242HNP_CTRL_HNP_STATE) == OTG242HNP_CTRL_HNP_A_VBUS_ERR)
{
/*********************************************
A temporary hnp condition vbus error, just
clear it by writing 1 to hnpcontrol status
*********************************************/
hnpStatus |= OTG242HNP_CTRL_CLEAR_ERROR;
OTG242HNP_WriteReg(hnp, OTG242HNP_CTRL, hnpStatus);
}
}
}
/*******************************************************
Master state interrupt (host)
********************************************************/
if( (status & OTG242_INTR_MASSLVCHG)
&& (OTG242HNP_ReadReg(hnp, OTG242HNP_CTRL) & OTG242HNP_CTRL_HNPCS_MASTER)
)
{
hnpStatus = OTG242HNP_ReadReg(hnp, OTG242HNP_CTRL);
/*******************************************************
if we are in A device, just go as usual,cause there
is no time constraint.
******************************************************/
if (hnpStatus & OTG242HNP_CTRL_IS_A_DEVICE)
{
OTG242HNP_WriteReg(hnp, OTG242HC_RH_PORT_STATUS(1),
OTG242HC_RH_PORT_STATUS_PPS);
/*******************************************************
We have turned to A-MASTER, but now this leaves the
A-DEVICE in reset condition (SE0) and this A-DEVICE
keeps generating B-RESET signalling to top level.
Therefore, we need to disable the A-DEVICE interrupt
in top level .
*******************************************************/
OTG242_DisableIntr(hnp->otg, OTG242_INTR_STATUS_FC);
/********************************************
Turn on bus-request. When we transit to
A-MASTER from A-PERIPHERL where b-req
has been disabled.
********************************************/
hnpStatus |= OTG242HNP_CTRL_BUS_REQUEST;
OTG242HNP_WriteReg(hnp, OTG242HNP_CTRL, hnpStatus);
/****************************************************
Enable host controller interrupts and enter oper
****************************************************/
val =
OTG242HC_INTR_SCHEDULE_OVERRUN |
OTG242HC_INTR_WRITE_DONE_HEAD |
OTG242HC_INTR_START_OF_FRAME |
OTG242HC_INTR_RESUME_DETECT |
OTG242HC_INTR_UNRECOVERABLE_ERROR |
OTG242HC_INTR_ROOT_HUB_STATUS_CHANGE |
OTG242HC_INTR_FRAME_NO_OVERFLOW;
OTG242_EnableIntr(hnp->otg, val);
/*
EnterOperationalState();
*/
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP: A Master, Enter Operational \r\n");
}
else
{
/*****************************************************
We need to issue port reset to otg port, if the
otg port is not enabled, so that the device side
will stay at PERIPHERAL state. Must do this quick
cause A-device may slide out A-peripheral if 3ms
passes.
*****************************************************/
val = OTG242HNP_ReadReg(hnp, OTG242HC_CTRL) &
~(OTG242HC_CTRL_CBSR | OTG242HC_CTRL_HCFS);
val = OTG242HC_CTRL_CBSR_1TO1 | OTG242HC_CTRL_HCFS_OPERATIONAL | OTG242HC_CTRL_RWE;
OTG242HNP_WriteReg(hnp, OTG242HC_CTRL, val);
for (port = OTG242HC_RH_PORT_FIRST; port < OTG242HC_RH_PORT_FIRST + OTG242HC_RH_PORT_MAX ; port++)
{
OTG242HNP_WriteReg
(
hnp,
OTG242HC_RH_PORT_STATUS(port),
OTG242HC_RH_PORT_STATUS_PPS
);
}
/**********************************************************
Port status should change to connected 0x10101, reset
this port to get this port enabled and propergate down
SOF packets, to make A-DEVICE stay at A-PERIPHERAL.
**********************************************************/
portStatus =
OTG242HNP_ReadReg(hnp, OTG242HC_RH_PORT_STATUS(OTG242HNP_OTG_PORT));
val = 0;
while((portStatus & OTG242HC_RH_PORT_STATUS_CCS) == 0)
{
portStatus =
OTG242HNP_ReadReg(hnp, OTG242HC_RH_PORT_STATUS(OTG242HNP_OTG_PORT));
/******************************************
Running on strongarm 206mz, 1500 may
cost 3ms.
*******************************************/
if(val++ > 1200)
{
hnpStatus = OTG242HNP_ReadReg(hnp, OTG242HNP_CTRL);
OS_DEBUG_MSG3(OS_ZONE_INIT,
"OTG242HNP: B dev Port Status remains 0x%08X, mnp 0x%08X \r\n",
portStatus, hnpStatus);
break;
}
}
OTG242HNP_WriteReg(hnp, OTG242HC_RH_PORT_STATUS(OTG242HNP_OTG_PORT),
OTG242HC_RH_PORT_STATUS_PRS);
/************************************************
Sleep some time to give A-DEVICE some time
to stablize at A-PERIPHERAL state and execute
the codes to unload drivers.
************************************************/
OS_Wait(2000);
/*********************************************************
Here, the port status is messed already, it contains
PORTREST, resetcomplete, enabled, power-on, CCS, CSC.
our software will get confused if we continue to
process those info. The above RESET is for hnp protocal,
HERE, we will issue one more RESET to clear those bits
and get the correct one. 0x10101.
*********************************************************/
OTG242HNP_WriteReg(hnp, OTG242HC_RH_PORT_STATUS(OTG242HNP_OTG_PORT),
0x100000);
/*******************************************************
We have turned to B-MASTER, but now this leaves the
B-DEVICE in reset condition (SE0) and this B-DEVICE
keeps generating B-RESET signalling to top level.
Therefore, we need to disable the B-DEVICE interrupt
in top level .
*******************************************************/
val = OTG242HNP_ReadReg(hnp, OTG242_INTR_ENABLE);
if (val == 0)
{
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP: !!Error Enter Host TopChipIntEnable 0 \r\n");
}
val = OTG242_INTR_HC | OTG242_INTR_HNP;
OTG242HNP_WriteReg(hnp, OTG242_INTR_ENABLE, val);
val = OTG242_INTR_IDCHANGE |
OTG242_INTR_SRPINT |
OTG242_INTR_SRPSUCFAIL |
OTG242_INTR_VBUSERROR |
OTG242_INTR_MASSLVCHG |
OTG242_INTR_AVBUSVAILD |
OTG242_INTR_ASESSVAILD |
OTG242_INTR_AIDLEBDTO |
OTG242_INTR_AWAITBTO;
OTG242HNP_WriteReg(hnp, OTG242_HNPINTERRUPTSTATUSENABLE, val);
/*******************************************************
Huuu, take a brake here, we do the above quickly in
order to get the port enabled.
********************************************************/
val =
OTG242HC_INTR_SCHEDULE_OVERRUN |
OTG242HC_INTR_WRITE_DONE_HEAD |
OTG242HC_INTR_START_OF_FRAME |
OTG242HC_INTR_RESUME_DETECT |
OTG242HC_INTR_UNRECOVERABLE_ERROR |
OTG242HC_INTR_ROOT_HUB_STATUS_CHANGE |
OTG242HC_INTR_FRAME_NO_OVERFLOW;
OTG242HNP_WriteReg(hnp, OTG242HC_INTR_ENABLE, val);
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP: B dev, Enter master state\r\n");
}
}
/******************************************************
Slave state interrupt (function)
******************************************************/
if( (status & OTG242_INTR_MASSLVCHG)
&& (OTG242HNP_ReadReg(hnp, OTG242HNP_CTRL) & OTG242HNP_CTRL_HNPCS_SLAVE)
)
{
OTG242HNP_WriteReg(hnp, OTG242_HNPINTERRUPTSTATUS, OTG242_INTR_STATUS_MASSLVCHG);
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP: Enter slave state\r\n");
hnpStatus = OTG242HNP_ReadReg(hnp, OTG242HNP_CTRL);
if (hnpStatus & OTG242HNP_CTRL_IS_A_DEVICE)
{
}
else
{
/********************************************
Here, we become B-Device cause the Mini-A
is disconnected. therefore, we will remove
bus request.
********************************************/
hnpStatus &= ~OTG242HNP_CTRL_BUS_REQUEST;
OTG242HNP_WriteReg(hnp, OTG242HNP_CTRL, hnpStatus);
}
/*************************************************
When host side application clears bus request
and set bus drop, host will return to OTG242HNP_A_IDLE,
in this case, the device bus reset S32 will
remains there forever. So, in the device side,
when such a case is detected, chip level S32
for device (the first bit) will be cleared.
When device is waked up by any means, this
SlaveState interrupt will be called, therefore,
we need to enable this bit again right here.
*************************************************/
val = OTG242HNP_ReadReg(hnp, OTG242_INTR_ENABLE);
if (val == 0)
{
OS_DEBUG_MSG1(OS_ZONE_INIT, "OTG242HNP: !!Error Enter Slave TopChipIntEnable 0 \r\n");
}
val = OTG242_INTR_HC | OTG242_INTR_HC | OTG242_INTR_HNP;
OTG242HNP_WriteReg(hnp, OTG242_INTR_ENABLE, val);
val = OTG242_INTR_IDCHANGE |
OTG242_INTR_SRPINT |
OTG242_INTR_SRPSUCFAIL |
OTG242_INTR_VBUSERROR |
OTG242_INTR_MASSLVCHG |
OTG242_INTR_AVBUSVAILD |
OTG242_INTR_ASESSVAILD |
OTG242_INTR_AIDLEBDTO |
OTG242_INTR_AWAITBTO;
OTG242HNP_WriteReg(hnp, OTG242_HNPINTERRUPTSTATUSENABLE, val);
/*
Otg242Fc_RestoreRegisterFromReset(OTG242_GetFc(hnp->otg));
*/
}
/* Otg242Hc_ResumeFromPowerSaveMode(); */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -