📄 pcmsock.cpp
字号:
{
if( pState->dwInteruptStatus & SOCK_INT_FUNC_IRQ_ROUTING )
{
tmp |= GetPCCardBusBridge()->GetFnInterruptNo(); // enable interrupt routing
}
else
{
tmp &= 0xf0; // disable interrupt routing
}
m_SocketState.dwInteruptStatus = pState->dwInteruptStatus;
m_SocketState.fIREQRouting = pState->fIREQRouting;
};
if( ( pState->dwInterfaceType & CFG_IFACE_MEMORY_IO ) != 0 )
{
tmp |= INT_CARD_IS_IO;
}
m_SocketState.dwInterfaceType = pState->dwInterfaceType;
PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL, tmp );
if( ( pState->dwEventStatus & SOCK_EVENT_EJECT ) != 0 ||
( pState->dwEventStatus & SOCK_EVENT_INSERT ) != 0 )
{
// Ask for ejection of the card.
DEBUGMSG( ZONE_PDD,
( TEXT( "PDCardSetSocket CPCMSocket. Gernerate Artificial Eject\r\n" ) ) );
CardInjectEvent();
}
else if( ( pState->fVcc & SOCK_VCC_LEVEL_MASK ) >=
NUM_POWER_ENTRIES ||
!( m_rgPowerEntries[pState->fVcc & SOCK_VCC_LEVEL_MASK].fSupply & PWR_SUPPLY_VCC ) )
{
pState->fVcc = m_SocketState.fVcc;
status = CERR_BAD_VCC;
}
else
{
BYTE oldfVcc = m_SocketState.fVcc;
BYTE olduVpp = m_SocketState.uVpp1;
if( ( pState->fVcc & SOCK_VCC_LEVEL_MASK ) !=
( m_SocketState.fVcc & SOCK_VCC_LEVEL_MASK ) )
{
m_SocketState.fVcc = pState->fVcc;
}
if( ( pState->uVpp1 & SOCK_VCC_LEVEL_MASK ) !=
( m_SocketState.uVpp1 & SOCK_VCC_LEVEL_MASK ) )
{
if( ( pState->uVpp1 & SOCK_VCC_LEVEL_MASK ) >=
NUM_POWER_ENTRIES ||
!( m_rgPowerEntries[pState->uVpp1 & SOCK_VCC_LEVEL_MASK].fSupply & PWR_SUPPLY_VPP1 ) )
pState->uVpp1 = m_SocketState.uVpp1;
m_SocketState.uVpp1 = pState->uVpp1;
if( m_rgPowerEntries[m_SocketState.uVpp1 & SOCK_VCC_LEVEL_MASK].uPowerLevel !=
0 &&
m_rgPowerEntries[m_SocketState.uVpp1 & SOCK_VCC_LEVEL_MASK].uPowerLevel !=
120 )
{
// VPP is same as VCC.
m_SocketState.uVpp1 = m_SocketState.fVcc;
}
}
if( oldfVcc != m_SocketState.fVcc || olduVpp != m_SocketState.uVpp1 )
{
if( m_SocketState.fVcc == 0 )
{
DEBUGMSG( ZONE_PDD,
( TEXT( "PDCardSetSocket CPCMSocket. Socket is Power Down! Function Interrupt Routing will force to Off\r\n" ) ) );
m_SocketState.dwInteruptStatus &= ~SOCK_INT_FUNC_IRQ_ROUTING;
PCICRegisterWrite( REG_POWER_CONTROL, 0 );
}
else
{
PowerOnProcedure( m_SocketState.fVcc, m_SocketState.uVpp1 );
DEBUGMSG( ZONE_PDD,
( TEXT( "PDCardSetSocket CPCMSocket. Socket is Power Up with fVcc=%d\r\n" ),
m_SocketState.fVcc ) );
}
}
else
{
DEBUGMSG( ZONE_PDD,
( TEXT( "PDCardSetSocket CPCMSocket. Same Power with fVcc=%d and uVpp1\r\n" ),
m_SocketState.fVcc,
m_SocketState.uVpp1 ) );
}
}
DEBUGMSG( ZONE_PDD,
( TEXT( "PDCardSetSocket Vcc = %d, Vpp = %d\r\n" ),
m_rgPowerEntries[m_SocketState.fVcc & SOCK_VCC_LEVEL_MASK].uPowerLevel,
m_rgPowerEntries[m_SocketState.uVpp1].uPowerLevel ) );
DEBUGMSG( ZONE_PDD,
( TEXT( "PDCardSetSocket REG_POWER_CONTROL = %x,Present Register=%x,Socket_Event=%x\r\n" ),
PCICRegisterRead( REG_POWER_CONTROL ), 0, 0 ) );
PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL,
PCICRegisterRead( REG_INTERRUPT_AND_GENERAL_CONTROL ) |
INT_CARD_NOT_RESET );
}
else
{
status = CERR_BAD_SOCKET;
}
Unlock();
#ifdef DEBUG
bool fFlag = false;
if( fFlag )
{
DumpAllRegisters();
}
#endif
return status;
}
void CPCMSocket::PowerCycleEvent()
{
GetPCCardBusBridge()->PowerCycleEvent();
}
void CPCMSocket::CardInjectEvent()
{
GetPCCardBusBridge()->CardInjectEvent();
}
void CPCMSocket::PowerOnProcedure( UINT8 fVcc, UINT8 fVpp )
{
DEBUGMSG( ZONE_SOCKET,
( TEXT( "+SMDK2410!CPCMSocket:PowerOnProcedure fVcc=%d,fVpp=%d\r\n" ),
fVcc,
fVpp ) );
if( !GetPCCardBusBridge()->PollingMode() )
{
// PD6710 specific code to enable management interrupt(routed to -INTR)
UINT8 tmp = PCICRegisterRead( REG_INTERRUPT_AND_GENERAL_CONTROL );
tmp |= INT_ENABLE_MANAGE_INT;
PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL, tmp );
}
//
// Power off the socket
//
PCICRegisterWrite( REG_POWER_CONTROL, 0 );
//
// Tri-state outputs for 310ms
//
Sleep( 310 );
//
// Power the socket to default Vcc=50 and Vpp = Vcc;
//
DEBUGCHK( fVcc < NUM_POWER_ENTRIES );
DEBUGCHK( fVpp < NUM_POWER_ENTRIES );
BYTE bPowerReg = 0;
if( m_rgPowerEntries[fVcc].uPowerLevel == 33 )
{
bPowerReg |= PWR_OUTPUT_ENABLE | PWR_VCC_POWER;
DEBUGMSG( ZONE_PDD, (TEXT(" set to 3.3V\r\n")));
PCICRegisterWrite( REG_GENERAL_CONTROL, PCICRegisterRead( REG_GENERAL_CONTROL ) | MISC1_VCC_33 );
}
else if( m_rgPowerEntries[fVcc].uPowerLevel == 50 )
{
bPowerReg |= PWR_OUTPUT_ENABLE | PWR_VCC_POWER;
if( PCICRegisterRead( REG_GENERAL_CONTROL ) & MISC1_5V_DETECT ) //REG_MISC_CONTROL_1;
{ // i.e., if we detect a 5V card:
DEBUGMSG( ZONE_PDD, (TEXT(" set to 5V\r\n")) );
PCICRegisterWrite( REG_GENERAL_CONTROL, PCICRegisterRead( REG_GENERAL_CONTROL ) & ~MISC1_VCC_33 ); // disable 3.3V (i.e., use 5V)
}
else
{
// this is a 3.3V ONLY card and mustn't be powered at 5V
// so ignore the command; we'd assert here save that card
// services will attempt to apply 5V to read the CIS.
DEBUGMSG( ZONE_PDD, (TEXT(" set to 3.3V[5V]\r\n")));
PCICRegisterWrite( REG_GENERAL_CONTROL, PCICRegisterRead( REG_GENERAL_CONTROL ) | MISC1_VCC_33 ); // enable 3.3V
}
}
if( fVcc == fVpp )
{
bPowerReg |= PWR_VPP1_BIT0; // set Vpp = Vcc
}
else
{
bPowerReg |= PWR_VPP1_BIT0 | PWR_VPP1_BIT1; // set Vpp = 0
}
PCICRegisterWrite( REG_POWER_CONTROL, bPowerReg );
Sleep( 100 );
//
// Assert RESET for 20 MS
//
UINT8 intctl = PCICRegisterRead( REG_INTERRUPT_AND_GENERAL_CONTROL );
PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL, intctl & ~ INT_CARD_NOT_RESET );
Sleep( 20 );
Sleep(20);
//
// Deassert RESET
//
PCICRegisterWrite( REG_INTERRUPT_AND_GENERAL_CONTROL,
intctl | INT_CARD_NOT_RESET );
//
// Allow the card 2 seconds to assert RDY
//
DWORD dwCount;
for( dwCount = 0; dwCount < 2000; dwCount += 20 )
{
// Check for one second.
if( ( PCICRegisterRead( REG_INTERFACE_STATUS ) & STS_CARD_READY ) !=
0 )
{
break;
}
PCICRegisterWrite( REG_POWER_CONTROL, bPowerReg );
Sleep( 20 );
};
if( dwCount >= 2000 )
{
DEBUGMSG( ZONE_FUNCTION,
( TEXT( "PDCardResetSocket: CARD IN SOCKET NOT RDY AFTER %dms\r\n" ),
dwCount ) );
}
PowerCycleEvent();
}
//
// ResetSocket - do a PCMCIA reset
// return CERR_SUCCESS on success, CERR_UNSUPPORTED_SERVICE if size is anomolous
//
STATUS CPCMSocket::CardResetSocket()
{
DEBUGMSG( ZONE_SOCKET, ( TEXT( "+SMDK2410!ResetPCMCIASocket()\r\n" ) ) );
// set INT_CARD_NOT_RESET in INTERRUPT_AND_GENERAL_CONTROL register as directed
Lock();
STATUS status = CERR_SUCCESS;
if( m_pBridge )
{
//
// Power the socket
//
UINT8 uTmp = PCICRegisterRead( REG_INTERFACE_STATUS );
if( ( uTmp & ( STS_CD1 | STS_CD2 ) ) == 0 )
{
// No card Inserted
status = CERR_NO_CARD;
}
else
{
BYTE uVcc = 1;
if( PCICRegisterRead( REG_GENERAL_CONTROL ) & MISC1_5V_DETECT )
{
// 5 Volt Card.
uVcc = 2;
DEBUGMSG( ZONE_SOCKET,
( TEXT( "+SMDK2410!ResetPCMCIASocket: Initial Power on is 5 Volt\r\n" ) ) );
}
else
{
DEBUGMSG( ZONE_SOCKET,
( TEXT( "+SMDK2410!ResetPCMCIASocket: Initial Power on is 3 Volt\r\n" ) ) );
}
PowerOnProcedure( uVcc, 0 );
//
// Power the socket
//
m_SocketState.fVcc = uVcc;
m_SocketState.uVpp1 = 0;
m_SocketState.uVpp2 = 0;
}
}
else
{
status = CERR_BAD_SOCKET;
}
DEBUGMSG( ZONE_SOCKET,
( TEXT( "-SMDK2410!ResetPCMCIASocket() return status =%x\r\n" ),
status ) );
Unlock();
return status;
}
void CPCMSocket::SocketEventHandle( DWORD dwEvent, DWORD dwPresentStateReg ) // Event Handle from Interrupt.
{
SS_SOCKET_STATE sSockState;
Lock();
CardGetSocket( &sSockState );
// Update the state from interrupt. But not card detection. Card detection event
// generate during object createion.
sSockState.dwEventChanged &= ~SOCK_EVENT_CD;
if( ( dwPresentStateReg & SPS_POWERCYCLE ) != 0 )
{
sSockState.dwEventStatus |= SOCK_EVENT_PWRCYCLE;
sSockState.dwEventChanged |= SOCK_EVENT_PWRCYCLE;
}
Unlock();
m_pBridge->CallBackToCardService( GetSocketHandle(),
&sSockState );
}
CPcmciaCardSocket* CreatePCMCIASocket( CPcmciaBusBridge* pBridge )
{
CPCMSocket* pNewSocket = new CPCMSocket( pBridge );
if( pNewSocket != NULL )
{
if( pNewSocket->CardInitWindow( pNewSocket ) )
{
return pNewSocket;
}
else
{
delete pNewSocket;
}
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -