📄 simhw.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// File: simhw.c
//
// This file implements the device specific functions for sim
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <devload.h>
#include <smclib.h>
#include <winsmcrd.h>
#include "mxarm11.h"
#include "simcb.h"
#include "simhw.h"
//------------------------------------------------------------------------------
// External Functions
extern UINT32 BSPGetSIMCLK(void);
extern BOOL BSPSetSIMClockGatingMode(DWORD port, BOOL startClocks);
extern void BSPSimIomuxSetPin(void);
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Defines
#define FACTOR_NUMBER 16
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
// Global Variables
//Port selection
DWORD g_PortSelect;
//Clock rate factor (ISO 7816 part3)
ClockRateFactor g_crf[FACTOR_NUMBER] = {
{0x0, 372, 4},
{0x1, 372, 5},
{0x2, 558, 6},
{0x3, 744, 8},
{0x4, 1116, 12},
{0x5, 1488, 16},
{0x6, 1860, 20},
{0x7, RFU, RFU},
{0x8, RFU, RFU},
{0x9, 512, 5},
{0xa, 768, 7},
{0xb, 1024, 10},
{0xc, 1536, 15},
{0xd, 2048, 20},
{0xe, RFU, RFU},
{0xf, RFU, RFU}
};
//Baud Rate factor (ISO 7816 part3)
BaudRateFactor g_brf[FACTOR_NUMBER] = {
{0x0, RFU},
{0x1, 1},
{0x2, 2},
{0x3, 4},
{0x4, 8},
{0x5, 16},
{0x6, 32},
{0x7, RFU},
{0x8, 12},
{0x9, 20},
{0xa, RFU},
{0xb, RFU},
{0xc, RFU},
{0xd, RFU},
{0xe, RFU},
{0xf, RFU}
};
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
// Local Functions
static void SIM_MaskInterrupts(PCSP_SIM_REG pSIMReg);
void Dump_Registers(PCSP_SIM_REG pSIMReg);
//-----------------------------------------------------------------------------
//
// Function: SIM_InternalMapRegisterAddresses
//
// This function maps the virtual addresses for SIM registers
//
// Parameters:
// iobase
// [in]Physical iobase address
//
// Returns:
// PVOID pointer of mapped SIM register structure
//
//-----------------------------------------------------------------------------
PVOID SIM_InternalMapRegisterAddresses(DWORD iobase)
{
PCSP_SIM_REG pSIMReg;
PHYSICAL_ADDRESS phyAddr;
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_InternalMapRegisterAddresses\n") ));
phyAddr.QuadPart = iobase;
// Map peripheral physical address to virtual address
pSIMReg = (PCSP_SIM_REG) MmMapIoSpace(phyAddr, sizeof(PCSP_SIM_REG), FALSE);
// Check if virtual mapping failed
if (pSIMReg == NULL)
{
SmartcardDebug( DEBUG_ERROR,( TEXT("SIM_InternalMapRegisterAddresses Failed!\n")));
}
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_InternalMapRegisterAddresses\n") ));
return(pSIMReg);
}
//-----------------------------------------------------------------------------
//
// Function: SIM_Init
//
// This function initializes the SIM module
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
//
// Returns:
// void
//
//-----------------------------------------------------------------------------
void SIM_Init(PCSP_SIM_REG pSIMReg)
{
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_Init\n") ));
BSPSimIomuxSetPin();
BSPSetSIMClockGatingMode(g_PortSelect, TRUE);
//mask all interrupts
SIM_MaskInterrupts(pSIMReg);
if (g_PortSelect == PORT0)
{
//select port 0
INSREG32BF(&pSIMReg->SETUP, SIM_SETUP_SPS, SIM_SETUP_SPS_PORT0);
//config port 0
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_3VOLT, SIM_PORT0_CNTL_3VOLT_DISABLE); // disable 3 volt
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SVEN, SIM_PORT0_CNTL_SVEN_DISABLE); //disable power for port 1
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SCSP, SIM_PORT0_CNTL_SCSP_DISABLE); // Stopped clock = low
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SAPD, SIM_PORT0_CNTL_SAPD_DISABLE); // Disable auto power down
//set port 0 to be open drain
INSREG32BF(&pSIMReg->OD_CONFIG, SIM_OD_CONFIG_OD_P0, SIM_OD_CONFIG_OD_P0_OD);
}
else
{
//select port 1
INSREG32BF(&pSIMReg->SETUP, SIM_SETUP_SPS, SIM_SETUP_SPS_PORT1);
//config port 1
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_3VOLT, SIM_PORT1_CNTL_3VOLT_DISABLE); // disable 3 volt
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SVEN, SIM_PORT1_CNTL_SVEN_DISABLE); //disable power for port 1
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SCSP, SIM_PORT1_CNTL_SCSP_DISABLE); // Stopped clock = low
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SAPD, SIM_PORT1_CNTL_SAPD_DISABLE); // Disable auto power down
//set port 1 to be open drain
INSREG32BF(&pSIMReg->OD_CONFIG, SIM_OD_CONFIG_OD_P1, SIM_OD_CONFIG_OD_P1_OD);
}
//Assume the card clock is about 2MHz sim_clock = 33.6MHz CLOCK_SELECT = 0111 (7)
INSREG32BF(&pSIMReg->CLOCK_SELECT, SIM_CLOCK_SELECT, FI_DEFAULT);
//Configure the TX and RX buffer threshold
INSREG32BF(&pSIMReg->XMT_THRESHOLD, SIM_XMT_THRESHOLD_TDT, 0x1);
INSREG32BF(&pSIMReg->RCV_THRESHOLD, SIM_RCV_THRESHOLD_RDT, 0x1);
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_Init\n") ));
}
//-----------------------------------------------------------------------------
//
// Function: SIM_Open
//
// This function Opens SIM module
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
//
// Returns:
// void
//
//-----------------------------------------------------------------------------
void SIM_Open(PCSP_SIM_REG pSIMReg)
{
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_Open\n") ));
if (!BSPSetSIMClockGatingMode(g_PortSelect, TRUE))
{
ERRORMSG(TRUE, (TEXT("SIM_Open: BSPSetSIMClockGatingMode failed!\r\n")));
return;
}
// Enable Transmiter & Receiver (may need critical section here)
INSREG32BF(&pSIMReg->ENABLE, SIM_ENABLE_XMTEN, SIM_ENABLE_XMTEN_ENABLE);
INSREG32BF(&pSIMReg->ENABLE, SIM_ENABLE_RCVEN, SIM_ENABLE_RCVEN_ENABLE);
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_Open\n") ));
}
//-----------------------------------------------------------------------------
//
// Function: SIM_Close
//
// This function closes SIM module
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
//
// Returns:
// void
//
//-----------------------------------------------------------------------------
void SIM_Close(PCSP_SIM_REG pSIMReg)
{
int uTries;
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_Close\n") ));
uTries = 0;
//Wait for Transmit FIFO empty;
while (!EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_TFE)&& (uTries++ < RETRYS))
{
Sleep(10);
}
// Disable Transmiter & Receiver (may need critical section here)
INSREG32BF(&pSIMReg->ENABLE, SIM_ENABLE_XMTEN, SIM_ENABLE_XMTEN_DISABLE);
INSREG32BF(&pSIMReg->ENABLE, SIM_ENABLE_RCVEN, SIM_ENABLE_RCVEN_DISABLE);
if (!BSPSetSIMClockGatingMode(g_PortSelect, FALSE))
{
ERRORMSG(TRUE, (TEXT("SIM_Open: BSPSetSIMClockGatingMode failed!\r\n")));
return;
}
SmartcardDebug( DEBUG_DRIVER,( TEXT("-SIM_Close\n") ));
}
//-----------------------------------------------------------------------------
//
// Function: SIM_ColdReset
//
// This function performs cold reset to SIM
//
// Parameters:
// pSIMReg
// [in]Pointer of the startingl address of SIM register structures
// *Buffer
// [in]Pointer of the buffer to store the ATR
// *BufferLength
// [in]/[out]Pointer of the length of the buffer to store the ATR
//
// Returns:
// NTSTATUS
//
//-----------------------------------------------------------------------------
NTSTATUS SIM_ColdReset(PCSP_SIM_REG pSIMReg, UCHAR* Buffer, ULONG* BufferLength)
{
NTSTATUS NTStatus = STATUS_SUCCESS;
BOOL SmallVolt = TRUE;
UINT8 i = 0, flag = 0, ATR_RemBytes = 0, Bit_Num;
UCHAR TA1_Byte;
SmartcardDebug( DEBUG_DRIVER,( TEXT("+SIM_ColdReset\n") ));
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_SAMPLE12, SIM_CNTL_SAMPLE12_ENABLE);
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SRST, SIM_PORT0_CNTL_SRST_DISABLE);
if (g_PortSelect == PORT0)
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_3VOLT, SIM_PORT0_CNTL_3VOLT_ENABLE); // enable 3 volt
else
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_3VOLT, SIM_PORT1_CNTL_3VOLT_ENABLE); // enable 3 volt
start:
// SmartCard Cold reset sequence
// Set the CWT comparator register SIM_CHAR_WAIT = 0x2574(9600-12 = 9588) according to ISO 7816-3
INSREG32BF(&pSIMReg->CHAR_WAIT, SIM_CHAR_WAIT_CWT, COLDRESET_CWT);
if (g_PortSelect == PORT0)
{
// Enable CWT, but the CWT starts counting after the STOP bits of a received character
INSREG32BF(&pSIMReg->CNTL, SIM_CNTL_CWTEN, SIM_CNTL_CWTEN_ENABLE);
//enable transmit data out for port 0
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_STEN, SIM_PORT0_CNTL_STEN_ENABLE);
//enable clock for port 0
INSREG32BF(&pSIMReg->PORT0_CNTL, SIM_PORT0_CNTL_SCEN, SIM_PORT0_CNTL_SCEN_ENABLE);
}
else
{
// Enable CWT, but the CWT starts counting after the STOP bits of a received character
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_CNTL_CWTEN, SIM_CNTL_CWTEN_ENABLE);
//enable transmit data out for port 1
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_STEN, SIM_PORT1_CNTL_STEN_ENABLE);
//enable clock for port 1
INSREG32BF(&pSIMReg->PORT1_CNTL, SIM_PORT1_CNTL_SCEN, SIM_PORT1_CNTL_SCEN_ENABLE);
}
// Delay for at least 400 * BAUD_CLK (400<t<40000)
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
while (!EXTREG32BF(&pSIMReg->XMT_STATUS, SIM_XMT_STATUS_GPCNT)); // Wait GP Counter flag
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -