📄 simhw.c
字号:
OUTREG32(&pSIMReg->XMT_STATUS, CSP_BITFVAL(SIM_XMT_STATUS_GPCNT, SIM_XMT_STATUS_GPCNT_CLR)); //Clear GP Counter flag
if (g_PortSelect == PORT0)
{
// SIM reset H
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SRST, SIM_PORT0_CNTL_SRST_ENABLE);
}
else
{
// SIM reset H
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SRST, SIM_PORT1_CNTL_SRST_ENABLE);
}
// Get the ATR Data block (40000)
INSREG32BF(&pSIMReg->GPCNT, SIM_GPCNT, COLDRESET_DELAY2);
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_DISABLE); // Disable and reset GPCNT
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_CARD); // Enable GPCNT with card clock
// Enable the receiver and transmitter
INSREG32BF(&pSIMReg->ENABLE, SIM_ENABLE_XMTEN, SIM_ENABLE_XMTEN_ENABLE);
INSREG32BF(&pSIMReg->ENABLE, SIM_ENABLE_RCVEN, SIM_ENABLE_RCVEN_ENABLE);
//Start reading ATR
(*BufferLength) = 0;
// Clear the CWT flag
OUTREG32(&pSIMReg->RCV_STATUS, CSP_BITFVAL(SIM_RCV_STATUS_CWT, SIM_RCV_STATUS_CWT_CLR));
// Using polling method
while (1)
{
while ((!EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_RDRF)) &&
(!EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_CWT)) &&
(!EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_GPCNT)));
if (EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_RDRF))
{
// GPCNT Disable and reset if necessary
if (EXTREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL)!=0)
{
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_DISABLE);
}
if ( flag ==1)
{
if (ATR_RemBytes == 1)
{
if (g_PortSelect == PORT0)
Buffer[*BufferLength]= (unsigned char)EXTREG32BF(&pSIMReg->PORT0_RCV_BUF, SIM_PORT0_RCV_BUF_RCV_BUF);
else
Buffer[*BufferLength]= (unsigned char)EXTREG32BF(&pSIMReg->PORT1_RCV_BUF, SIM_PORT1_RCV_BUF_RCV_BUF);
(*BufferLength)++;
ATR_RemBytes --;
goto CHECK;
}
else if (ATR_RemBytes != 1)
{
if (g_PortSelect == PORT0)
Buffer[*BufferLength]= (unsigned char)EXTREG32BF(&pSIMReg->PORT0_RCV_BUF, SIM_PORT0_RCV_BUF_RCV_BUF);
else
Buffer[*BufferLength]= (unsigned char)EXTREG32BF(&pSIMReg->PORT1_RCV_BUF, SIM_PORT1_RCV_BUF_RCV_BUF);
(*BufferLength)++;
ATR_RemBytes --;
}
}
if ( flag == 0)
{
if (g_PortSelect == PORT0)
Buffer[*BufferLength]= (unsigned char)EXTREG32BF(&pSIMReg->PORT0_RCV_BUF, SIM_PORT0_RCV_BUF_RCV_BUF);
else
Buffer[*BufferLength]= (unsigned char)EXTREG32BF(&pSIMReg->PORT1_RCV_BUF, SIM_PORT1_RCV_BUF_RCV_BUF);
if (*BufferLength == 1)
{
TA1_Byte = 0xF0 & Buffer[*BufferLength];
for (Bit_Num = 7; Bit_Num > 3; Bit_Num --)
{
if (((TA1_Byte = TA1_Byte << 1) & 0x80) == 0x80)
ATR_RemBytes ++;
}
TA1_Byte = 0x0F & Buffer[*BufferLength];
ATR_RemBytes = TA1_Byte + ATR_RemBytes;
flag = 1;
}
(*BufferLength)++;
}
continue;
}
// Deal with the GPCNT timeout
if (EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_GPCNT))
{
//clear the GPCNT flag
DEBUGMSG(1,(TEXT("GPCOUNT TimeOut")));
OUTREG32(&pSIMReg->XMT_STATUS, CSP_BITFVAL(SIM_XMT_STATUS_GPCNT, SIM_XMT_STATUS_GPCNT_CLR));
return(STATUS_TIMEOUT);
}
// Deal with the CWT timeout
if (EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_CWT))
{
DEBUGMSG(1,(TEXT("CWT TimeOut")));
OUTREG32(&pSIMReg->XMT_STATUS, CSP_BITFVAL(SIM_RCV_STATUS_CWT, SIM_RCV_STATUS_CWT_CLR));
return(STATUS_TIMEOUT);
}
}
CHECK:
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_ColdReset\n") ));
if ((*BufferLength) > 0)
return(STATUS_SUCCESS);
if ((*BufferLength) == 0 && SmallVolt == TRUE)
{
SmallVolt = FALSE;
if (g_PortSelect == PORT0)
{
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_3VOLT, SIM_PORT0_CNTL_3VOLT_DISABLE);
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SVEN, SIM_PORT0_CNTL_SVEN_ENABLE);
}
else
{
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_3VOLT, SIM_PORT1_CNTL_3VOLT_DISABLE);
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SVEN, SIM_PORT1_CNTL_SVEN_ENABLE);
}
goto start;
}
else
return(STATUS_NOT_SUPPORTED);
}
//-----------------------------------------------------------------------------
//
// Function: SIM_WarmReset
//
// This function performs warm reset to SIM
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
//
// Returns:
// NTSTATUS
//
//-----------------------------------------------------------------------------
NTSTATUS SIM_WarmReset(PCSP_SIM_REG pSIMReg)
{
NTSTATUS NTStatus = STATUS_SUCCESS;
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_WarmReset\n") ));
// SIM reset = low
if (g_PortSelect == PORT0)
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SRST, 0);
else
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SRST, 0);
// Delay for at least 400 * BAUD_CLK
INSREG32BF(&pSIMReg->GPCNT, SIM_GPCNT, COLDRESET_DELAY1);
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_DISABLE); // Disable and reset GPCNT
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_CARD); // Enable GPCNT with card clock
// Wait GP Counter flag
while (!EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_GPCNT));
// Clear GP Counter flag
OUTREG32(&pSIMReg->XMT_STATUS, CSP_BITFVAL(SIM_XMT_STATUS_GPCNT, SIM_XMT_STATUS_GPCNT_CLR));
// SIM reset
if (g_PortSelect == PORT0)
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SRST, SIM_PORT0_CNTL_SRST_ENABLE);
else
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SRST, SIM_PORT1_CNTL_SRST_ENABLE);
// Delay for at least 40000 * BAUD_CLK
INSREG32BF(&pSIMReg->GPCNT, SIM_GPCNT, COLDRESET_DELAY2);
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_DISABLE); // Disable and reset GPCNT
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_CARD); // Enable GPCNT with card clock
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_WarmReset\n") ));
return(STATUS_SUCCESS);
}
//-----------------------------------------------------------------------------
//
// Function: SIM_ReadData
//
// This function reads the data from receive buffer
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
// *Buffer
// [in]Pointer of the destination buffer
// Length
// [in]Length of the data to be read
//
// Returns:
// NTSTATUS
//
//-----------------------------------------------------------------------------
NTSTATUS SIM_ReadData(PCSP_SIM_REG pSIMReg, UCHAR *Buffer, ULONG Length)
{
ULONG i = 0;
NTSTATUS NTStatus = STATUS_SUCCESS;
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_ReadData\n") ));
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_CWTEN, SIM_CNTL_CWTEN_DISABLE);
// Clear the CWT flag
OUTREG32(&pSIMReg->RCV_STATUS, CSP_BITFVAL(SIM_RCV_STATUS_CWT, SIM_RCV_STATUS_CWT_CLR));
INSREG32BF(&pSIMReg->CHAR_WAIT, SIM_CHAR_WAIT_CWT, COLDRESET_CWT);
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_CWTEN, SIM_CNTL_CWTEN_ENABLE);
// Using polling method
while (1)
{
while ((!EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_RDRF)) &&
(!EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_CWT)));
if (EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_RDRF) && (Length >0))
{
// GPCNT Disable and reset if necessary
if (EXTREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL)!=0)
{
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_DISABLE);
}
while ( Length > 0 )
{
if (EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_RFD))
{
if (g_PortSelect == PORT0)
Buffer[i]= (unsigned char)EXTREG32BF(&pSIMReg->PORT0_RCV_BUF, SIM_PORT0_RCV_BUF_RCV_BUF);
else
Buffer[i]= (unsigned char)EXTREG32BF(&pSIMReg->PORT1_RCV_BUF, SIM_PORT1_RCV_BUF_RCV_BUF);
i++;
Length--;
}
}
break;
}
// Deal with the CWT timeout
if (EXTREG32BF(&pSIMReg->RCV_STATUS, SIM_RCV_STATUS_CWT))
{
OUTREG32(&pSIMReg->XMT_STATUS, CSP_BITFVAL(SIM_RCV_STATUS_CWT, SIM_RCV_STATUS_CWT_CLR));
DEBUGMSG(1,(TEXT("CWT TimeOut in SIM_Read")));
return(STATUS_TIMEOUT);
}
}
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_ReadData\n") ));
return(STATUS_SUCCESS);
}
//-----------------------------------------------------------------------------
//
// Function: SIM_WriteData
//
// This function writes the data to transmitter buffer
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
// *Buffer
// [in]Pointer of the destination buffer
// Length
// [in]Length of the data to be read
//
// Returns:
// NTSTATUS
//
//-----------------------------------------------------------------------------
NTSTATUS SIM_WriteData(PCSP_SIM_REG pSIMReg, UCHAR *Buffer, ULONG Length)
{
ULONG i;
ULONG limit = 0;
NTSTATUS NTStatus = STATUS_SUCCESS;
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_WriteData\n") ));
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SVEN, SIM_PORT0_CNTL_SVEN_ENABLE);
INSREG32BF(&pSIMReg->GPCNT, SIM_GPCNT, 0x200);
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_GPCNT_CLK_SEL, CLK_SEL_CARD);
SIM_FlushFIFO(pSIMReg);
// Write the characters to be sent as response to the XMT FIFO
for ( i = 0; i < Length; i++)
{
if (g_PortSelect == PORT0)
{
pSIMReg->PORT0_XMT_BUF = Buffer[i];
Sleep (25);
}
else
{
pSIMReg->PORT1_XMT_BUF = Buffer[i];
limit ++;
if (limit == 15)
{
while (!(EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_TFE) ||
EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_ETC)));
limit = 0;
}
}
}
// Wait for transmit complete
while (!(EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_TFE) ||
EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_ETC)));
// Clear the flags
OUTREG32(&pSIMReg->XMT_STATUS, CSP_BITFVAL(SIM_XMT_STATUS_TFE, SIM_XMT_STATUS_TFE_CLR));
OUTREG32(&pSIMReg->XMT_STATUS, CSP_BITFVAL(SIM_XMT_STATUS_ETC, SIM_XMT_STATUS_ETC_CLR));
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_WriteData\n") ));
return(STATUS_SUCCESS);
}
//-----------------------------------------------------------------------------
//
// Function: SIM_Deactivate
//
// This function deactives SIM
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
//
// Returns:
// NTSTATUS
//
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -