📄 socket.c
字号:
//
// Wait (up to 2 seconds) for ready before accessing card
//
for (t=0;t<PCMCIA_MAX_RDY_WAIT_TIME; t+=PCMCIA_RDY_POLL_INT) {
if (uSocket) {
if (PD365Read2(INDEX_INTERFACE_STATUS) & DATA_READY_BUSY) {
DEBUGMSG(ZONE_PDD,(TEXT("Card2 RDY after %d ms\n\r"),20 + t));
break;
} else {
Sleep(PCMCIA_RDY_POLL_INT);
}
} else {
if (PD365Read1(INDEX_INTERFACE_STATUS) & DATA_READY_BUSY) {
DEBUGMSG(ZONE_PDD,(TEXT("Card1 RDY after %d ms\n\r"),20 + t));
break;
} else {
Sleep(PCMCIA_RDY_POLL_INT);
}
}
}
if (t >= PCMCIA_MAX_RDY_WAIT_TIME)
DEBUGMSG(ZONE_PDD,(TEXT("Timed out waiting for card RDY\n\r")));
SetupWindows();
State = v_SockState[uSocket];
State.fInterruptEvents = EVENT_MASK_CARD_DETECT|EVENT_MASK_CARD_LOCK|
EVENT_MASK_BATTERY_LOW|EVENT_MASK_BATTERY_DEAD|
EVENT_MASK_WRITE_PROTECT;
State.fInterfaceType = CFG_IFACE_MEMORY;
State.fIREQRouting = 0;
PDCardSetSocket(uSocket, &State);
LeaveCriticalSection(&v_MemAccessCrit);
LeaveCriticalSection(&g_PCIC_Crit);
return CERR_SUCCESS;
} else {
//
// Disable accessing card
//
if (uSocket)
PD365Write2(INDEX_POWER_CONTROL,
(UINT8)(PD365Read2(INDEX_POWER_CONTROL) & (UINT8)~CARD_OUT_EN));
else
PD365Write1(INDEX_POWER_CONTROL,
(UINT8)(PD365Read1(INDEX_POWER_CONTROL) & (UINT8)~CARD_OUT_EN));
}
LeaveCriticalSection(&g_PCIC_Crit);
return CERR_BAD_SOCKET;
}
//
// PDCardGetAdapter
//
// @func STATUS | PDCardGetAdapter | Returns power save mode status and capabilities
// @rdesc Returns one of the CERR_* return codes in cardserv.h
//
// @comm When the PCMCIA system is in low power mode, the bit,
// ADP_STATE_POWERDOWN should be set. When the PCMCIA system is powered off,
// then the ADP_STATE_POWEROFF bit should be set. When the PCMCIA system is in
// a full power mode, then the state should either be 0 or ADP_STATE_MAINTAIN.
// This function will be called in critical power situations, so it should not
// block or yield.
//
STATUS
PDCardGetAdapter(
UINT32 uSocket,
PPDCARD_ADAPTER_STATE pState
)
{
UINT8 tmp;
BOOL bUserMode;
if (uSocket >= NUM_SOCKETS) {
return CERR_BAD_SOCKET;
}
if (pState == NULL) {
return CERR_BAD_ARGS;
}
bUserMode = (*pState & ADP_STATE_KERNEL_MODE) ? FALSE : TRUE;
if (bUserMode) {
EnterCriticalSection(&g_PCIC_Crit);
}
//
// Check and see if we are a powerd off state
//
*pState = 0;
if (uSocket)
tmp = PD365Read2(INDEX_POWER_CONTROL);
else
tmp = PD365Read1(INDEX_POWER_CONTROL);
if ( !(tmp & VCC1) ) {
*pState |= ADP_STATE_POWERDOWN|ADP_STATE_POWEROFF;
}
if (bUserMode) {
LeaveCriticalSection(&g_PCIC_Crit);
}
return CERR_SUCCESS;
}
//
// PDCardSetAdapter
//
// @func STATUS | PDCardSetAdapter | Sets power save mode status and capabilities
// @rdesc Returns one of the CERR_* return codes in cardserv.h
//
// @comm If the bit, ADP_STATE_POWEROFF, is set, then the PCMCIA system
// should be powered off. If the ADP_STATE_POWERDOWN bit is set, then the
// PCMCIA system should be placed in power saving mode. In power save mode, it
// is expected that card insertion and removal events can be detected. If both
// of these bits are off, then the PCMCIA system should be placed in full power
// mode.
// This function will be called in critical power situations, so it should not
// block or yield.
//
STATUS
PDCardSetAdapter(
UINT32 uSocket,
PPDCARD_ADAPTER_STATE pState
)
{
int t;
UINT8 tmp, tmp2;
if (uSocket >= NUM_SOCKETS) {
return CERR_BAD_SOCKET;
}
if (pState == NULL) {
return CERR_BAD_ARGS;
}
if (!(*pState & ADP_STATE_KERNEL_MODE)) {
EnterCriticalSection( &v_MemAccessCrit );
EnterCriticalSection(&g_PCIC_Crit);
}
if (*pState & ADP_STATE_POWEROFF) {
PD365Write2(INDEX_MANAGEMENT_INTERRUPT_CONFIGURATION, 0);
PD365Write2(INDEX_MAPPING_ENABLE, 0);
PD365Write1(INDEX_MANAGEMENT_INTERRUPT_CONFIGURATION, 0);
PD365Write1(INDEX_MAPPING_ENABLE, 0);
} else if (*pState & ADP_STATE_POWERDOWN) {
if (uSocket) {
PD365Write2(INDEX_MANAGEMENT_INTERRUPT_CONFIGURATION,
DATA_CARD_DETECT_ENABLE|
DATA_BATTERY_DEAD_STSCHG_ENABLE);
if (PD365Read2(INDEX_INTERFACE_STATUS) & DATA_CARD_POWER_ON) {
PD365Write2(INDEX_POWER_CONTROL,
(UINT8)(PD365Read2(INDEX_POWER_CONTROL) & (UINT8)~CARD_OUT_EN));
PD365Write2(INDEX_INTERRUPT_AND_GENERAL_CONTROL,
(UINT8)(PD365Read2(INDEX_INTERRUPT_AND_GENERAL_CONTROL) & ~DATA_CARD_RESET));
PD365Write2(INDEX_POWER_CONTROL,
(UINT8)(PD365Read2(INDEX_POWER_CONTROL) & (UINT8)~(VCC1|VCC0)));
}
} else {
PD365Write1(INDEX_MANAGEMENT_INTERRUPT_CONFIGURATION,
DATA_CARD_DETECT_ENABLE|
DATA_BATTERY_DEAD_STSCHG_ENABLE);
if (PD365Read1(INDEX_INTERFACE_STATUS) & DATA_CARD_POWER_ON) {
PD365Write1(INDEX_POWER_CONTROL,
(UINT8)(PD365Read1(INDEX_POWER_CONTROL) & (UINT8)~CARD_OUT_EN));
PD365Write1(INDEX_INTERRUPT_AND_GENERAL_CONTROL,
(UINT8)(PD365Read1(INDEX_INTERRUPT_AND_GENERAL_CONTROL) & ~DATA_CARD_RESET));
PD365Write1(INDEX_POWER_CONTROL,
(UINT8)(PD365Read1(INDEX_POWER_CONTROL) & (UINT8)~(VCC1|VCC0)));
}
}
} else {
// Enable interrupt
if (uSocket) {
PD365Write2(INDEX_MANAGEMENT_INTERRUPT_CONFIGURATION,
DATA_CARD_DETECT_ENABLE|
DATA_BATTERY_DEAD_STSCHG_ENABLE);
tmp = PD365Read2(INDEX_INTERFACE_STATUS);
} else {
PD365Write1(INDEX_MANAGEMENT_INTERRUPT_CONFIGURATION,
DATA_CARD_DETECT_ENABLE|
DATA_BATTERY_DEAD_STSCHG_ENABLE);
tmp = PD365Read1(INDEX_INTERFACE_STATUS);
}
if ( (tmp & DATA_CARD_DETECT_CD1) && (tmp & DATA_CARD_DETECT_CD2) ) {
if (uSocket)
// Disable output signals to card
PD365Write2(INDEX_POWER_CONTROL,
(UINT8)(PD365Read2(INDEX_POWER_CONTROL) & (UINT8)~CARD_OUT_EN));
else
// Disable output signals to card
PD365Write1(INDEX_POWER_CONTROL,
(UINT8)(PD365Read1(INDEX_POWER_CONTROL) & (UINT8)~CARD_OUT_EN));
// Wait 50ms from CD to apply VCC
if (*pState & ADP_STATE_KERNEL_MODE)
RtcWait(50);
else
Sleep(50);
if (uSocket) {
tmp = PD365Read2(INDEX_POWER_CONTROL);
if ( REG32(v_pPcmciaCSR2 + SKT_PRE_STATE) & _5V_CARD_DT ) {
// enable VCC5EN
tmp |= VCC1;
tmp &= ~VCC0;
} else {
// enable VCC3EN
tmp |= VCC1;
tmp |= VCC0;
}
PD365Write2(INDEX_POWER_CONTROL, tmp);
} else {
tmp2 = PD365Read1(INDEX_POWER_CONTROL);
// VS bits in the ExCA register don't indicate the current status.
// We need to check CardBus socket register.
if ( REG32(v_pPcmciaCSR1 + SKT_PRE_STATE) & _5V_CARD_DT ) {
// enable VCC5EN
tmp2 |= VCC1;
tmp2 &= ~VCC0;
} else {
// enable VCC3EN
tmp2 |= VCC1;
tmp2 |= VCC0;
}
PD365Write1(INDEX_POWER_CONTROL, tmp2);
}
// Wait 100ms from Vcc power to enable RESET
if (*pState & ADP_STATE_KERNEL_MODE)
RtcWait(100);
else
Sleep(100);
if (uSocket) {
PD365Write2(INDEX_INTERRUPT_AND_GENERAL_CONTROL,
(UINT8)(PD365Read2(INDEX_INTERRUPT_AND_GENERAL_CONTROL)
& (UINT8)~DATA_CARD_RESET));
// Enable output signals to card
PD365Write2(INDEX_POWER_CONTROL,
(UINT8)(PD365Read2(INDEX_POWER_CONTROL) | (UINT8)CARD_OUT_EN));
} else {
PD365Write1(INDEX_INTERRUPT_AND_GENERAL_CONTROL,
(UINT8)(PD365Read1(INDEX_INTERRUPT_AND_GENERAL_CONTROL)
& (UINT8)~DATA_CARD_RESET));
// Enable output signals to card
PD365Write1(INDEX_POWER_CONTROL,
(UINT8)(PD365Read1(INDEX_POWER_CONTROL) | (UINT8)CARD_OUT_EN));
}
//
// Wait 1ms after applying power before enabling signals to card (allows VCC to
// ramp up)
//
if (*pState & ADP_STATE_KERNEL_MODE)
RtcWait(1);
else
Sleep(1);
if (uSocket) {
// Make sure RESET is deasserted
PD365Write2(INDEX_INTERRUPT_AND_GENERAL_CONTROL,
(UINT8)(PD365Read2(INDEX_INTERRUPT_AND_GENERAL_CONTROL) | DATA_CARD_RESET));
} else {
// Make sure RESET is deasserted
PD365Write1(INDEX_INTERRUPT_AND_GENERAL_CONTROL,
(UINT8)(PD365Read1(INDEX_INTERRUPT_AND_GENERAL_CONTROL) | DATA_CARD_RESET));
}
// Wait 30ms from RESET Disable
if (*pState & ADP_STATE_KERNEL_MODE)
RtcWait(30);
else
Sleep(30);
//
// Some PCMCIA cards use a pull up resistor to assert the RESET line when we apply power.
// At least one card (RIPICAB) has problems if it is reset while initializing. So, poll
// the RDY line to let initialization complete.
//
for (t=0;t<PCMCIA_MAX_RDY_WAIT_TIME; t+=PCMCIA_RDY_POLL_INT) {
if (uSocket)
tmp = PD365Read2(INDEX_INTERFACE_STATUS);
else
tmp = PD365Read1(INDEX_INTERFACE_STATUS);
if (tmp & DATA_READY_BUSY) {
if (!(*pState & ADP_STATE_KERNEL_MODE))
DEBUGMSG(ZONE_PDD,(TEXT("PDCardSetAdapter - Card RDY after %d ms\n\r"),20 + t));
break;
} else {
if (*pState & ADP_STATE_KERNEL_MODE)
RtcWait(PCMCIA_RDY_POLL_INT);
else
Sleep(PCMCIA_RDY_POLL_INT);
}
}
if ((t >= PCMCIA_MAX_RDY_WAIT_TIME) && (*pState & ADP_STATE_KERNEL_MODE))
DEBUGMSG(ZONE_PDD,(TEXT("PDCardSetAdapter - Timed out waiting for card RDY\n\r")));
}
}
if (!(*pState & ADP_STATE_KERNEL_MODE)) {
LeaveCriticalSection(&g_PCIC_Crit);
LeaveCriticalSection( &v_MemAccessCrit );
}
return CERR_SUCCESS;
}
//--------------------------------------------------------//
// PD365READ1 Index Read Access for PC Card 1 //
// IN : byIndex = INDEX DATA //
// OUT : READ DATA (UINT8) //
//--------------------------------------------------------//
UINT8
PD365Read1(UINT8 byIndex)
{
return (REG8(v_pPcmciaCSR1 + EXCA_REGISTER_OFFSET + byIndex));
}
//--------------------------------------------------------//
// PD365WRITE1 Index Write Access for PC Card 1 //
// IN : byIndex = INDEX DATA //
// : byDATA = WRITE DATA //
// OUT : VOID //
//--------------------------------------------------------//
VOID
PD365Write1(UINT8 byIndex ,UINT8 byData)
{
REG8(v_pPcmciaCSR1 + EXCA_REGISTER_OFFSET + byIndex) = byData;
}
//--------------------------------------------------------//
// PD365READ2 Index Read Access for PC Card 2 //
// IN : byIndex = INDEX DATA //
// OUT : READ DATA (UINT8) //
//--------------------------------------------------------//
UINT8
PD365Read2(UINT8 byIndex)
{
return (REG8(v_pPcmciaCSR2 + EXCA_REGISTER_OFFSET + byIndex));
}
//--------------------------------------------------------//
// PD365WRITE2 Index Write Access for PC Card 2 //
// IN : byIndex = INDEX DATA //
// : byDATA = WRITE DATA //
// OUT : VOID //
//--------------------------------------------------------//
VOID
PD365Write2(UINT8 byIndex ,UINT8 byData)
{
REG8(v_pPcmciaCSR2 + EXCA_REGISTER_OFFSET + byIndex) = byData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -