?? psgdrv.c
字號:
else
currentPTSState = PTS_DEFAULT_RETRY_STARTED;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSSendPTS0;
//End PS Debug
#endif
}
else /* No need to perform PTS */
{
PSAcceptSIM();
}
}
/*------------------------------------------------------------------------*/
/*
Name: DetermineNextResetAnswer
Desc: Used to determine the action to be performed on the next character
sent by the card during Answer to Reset. See ISO/IEC 7816-3 6.1.4.2
for details of how things are determined.
Params: None
Returns: Nothing
Caveats: Assumes that the contents of PSTByteFlags are the Previous TDi
character (Inititally T0) and that PSNoHistChars contains low
order Nibble of T0. PSRByteMask must be reset to 0x10 whenever
T0 or TDi is received.
*/
static void DetermineNextResetAnswer(void)
{
while ((PSTByteMask<0x80)&&((PSTByteMask&PSTByteFlags)==0))
{
PSTByteMask += PSTByteMask;
PSTBytePtr++;
}
if (PSTByteMask<0x80) /* TAi..TCi is Expected? */
{
PSIntAction = PSTABCiChar;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSTABCiChar;
//End PS Debug
#endif
}
else if ((PSTByteMask&PSTByteFlags)!=0) /* TDi is expected */
{
PSIntAction = PSTDiChar;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSTDiChar;
//End PS Debug
#endif
}
else if (PSNoHistChars!=0) /* Historic chars are expected */
{
PSIntAction = PSHistChar;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSHistChar;
//End PS Debug
#endif
}
else if (PSCardProtocols>1) /* Protocol other than T=0 */
{
PSIntAction = PSWaitTCK;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSWaitTCK;
//End PS Debug
#endif
}
else /* Answer to reset is complete */
{
PSCheckSum = 0; /* TCK is not available */
PSReturnToIdle(PSNormalCompletion);
}
PSTByteFlags &= ~PSTByteMask;
}
/*------------------------------------------------------------------------*/
/*
Name: PSStartSIMResetSequence
Desc: Kicks off the initialisation sequence for a SIM, unless the number
of reset retries has been exceeded. The values for the Interface
Characters are reset to their default GSM values.
Params: None
Returns: Nothing
Caveats: The defulat values correspond to those used by GSM
*/
static void PSStartSIMResetSequence(void)
{
if (PSResetRemainingRetries>0)
{
if (PSResetRemainingRetries==PS_RESET_ALLOWED_RETRIES)
PSEverFoundInitChar = FALSE;
else if (PSFoundInitChar)
PSEverFoundInitChar = TRUE;
PSDoShutDown(); //Retry, or switch voltage, need power down
PSTi = 0;
PSCurrProtType = 0;
PSCardProtocols = 1; /* Assume T=0 available until we find TD1 */
PSCheckSum = 0;
PSFoundInitChar = FALSE;
PSClockStopped = FALSE;
PSTBytePtr = PSIFChars;
PSIFChars[0] = 0x11; /* TA1 - Clock rates */
PSIFChars[1] = 5; /* TB1 - Programming Current/Voltage */
PSIFChars[2] = 0; /* TC1 - Extra guard time */
PSIFChars[3] = 0; /* TA2 - Not specified */
PSIFChars[4] = 50; /* TB2 - Accurate Programming Voltage */
// PSIFChars[5] = 50; /* TC2 - The Work Waiting Time, delay 9600 etu */
PSIFChars[5] = PS_DEFAULT_WI; /* TC2 - The Work Waiting Time, delay 9600 etu */
PSWorkWaitingTime = MSECS(PSIFChars[5]*PS_WORK_WAIT_FACTOR);
PSRemainingWorkTime = PS_RESET_LO_TIMEOUT;
PSTransferRemainingRetries = PS_TRANSFER_ALLOWED_RETRIES;
PSIntAction = PSIdle;
PSErrAction = PSIdle;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSIdle;
OldErrAction_Dbg = NewErrAction_Dbg;
NewErrAction_Dbg = _PSIdle;
//End PS Debug
#endif
PSCompleter = PSStartResetCompleter;
TimerAIH = SimResetTimerAIH; /* Initialize TimerA sim IH*/
#if SIM_DEBUG == SIM_DEBUG_MAX
IntHandler_Dbg = _SimResetTimerAIH;
#endif
PSResetRemainingRetries--;
}
#if (__SIM_INTERFACE__== SIM_1P8V3V)
else if (SISupplyVoltage == SI_1P8_VOLTS)
{
//Out of retries, start 3V reset sequence
SISupplyVoltage = SI_3_VOLTS;
PSDoStartUp();
}
#endif
else if ( (SIMClockSpeed == SIM_CLOCK_3_9Mhz) && (PSClockSpeed == SIM_CLOCK_3_9Mhz)) // Try to change speed from 3.9Mhz to
// to 1.95Mhz, if the SIM does not support
// 3.9Mhz.
{
#if (__SIM_INTERFACE__== SIM_1P8V3V)
if (SISupplyVoltage == SI_3_VOLTS)
{
SISupplyVoltage = SI_1P8_VOLTS;
}
#endif
PSClockSpeed = SIM_CLOCK_1_95Mhz;
PSDoStartUp();
}
else if (PSEverFoundInitChar)
{
#if SIM_DEBUG == SIM_DEBUG_MAX
PSDeactivateSIM_Dbg = 1;
#endif
PSDeactivateSIM(PSDefectSIM);
}
else
{
#if SIM_DEBUG == SIM_DEBUG_MAX
PSDeactivateSIM_Dbg = 2;
#endif
PSDeactivateSIM(PSNoSIM);
}
}
/*------------------------- Interrupt Action Functions: --------------------
The SIM driver is basically a interrupt handler that must step through a
sequence of transmission and reception of bytes to and from the SIM.
This sequence is defined in ISO/IEC 7816-3.
The sequence of actions is considered to be a simple state machine controlled
in the following manner:
There is a Function pointer PSIntAction, which points to the function
responsible for dealing with a 'Successful' SIM interrupt, i.e. one in which
a byte was successfully transferred.
Each time a 'Successful' interrpt occurs, the function pointer to by
PSIntAction is called, and the corresponding routine not only performs the
required action but also updates PSIntAction to point to the function that
handles next expected event from the SIM hardware.
If an 'unsuccessful' interrupt occurs, the main SIM interrupt handler is
responsible for taking appropriate actions.
In this way, the interrupt handler, together with the Successful interrupt
actions are well structured, simple and efficient.
--------------------------------------------------------------------------*/
/*
Name: PSParityErr
Desc: Interrupt action for Parity Errors. Causes the count of
count of retransmissions to be incremented and abort the
command if the too many have occured.
Params: None
Returns: Nothing
Caveats: Assumes that Character repetition is performed by hardware.
*/
static void PSParityErr(void)
{
if (PSTransferRemainingRetries>0)
PSTransferRemainingRetries--;
else /* The transmission to or from the SIM has been reattempted
too many times. Assume the SIM is defective */
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
PSCompletionCode_Dbg = PSTooManyRetries;
//End PS Debug
#endif
PSReturnToIdle(PSTooManyRetries);
}
/*------------------------------------------------------------------------*/
/*
Name: PSIdle
Desc: Dummy interrupt action routine, used when the SIM driver is
NOT expecting an interrupt, other than a SIM In or Out interrupt.
Params: None
Returns: Nothing
Caveats: Not much to do!
It could log the number of spurious interrupts!
It could also say the SIM is being naughty!
*/
static void PSIdle(void)
{
}
/*------------------------------------------------------------------------*/
/*
Name: PSSendINS
Desc: Interrupt action for TX interrupt following transmission of the
CLA byte of a Command Header. See ISO/IEC 7816-3 8.2.1.
This interrupt causes the INS byte to be sent and changes interrupt
handler to send P1 byte on next interrupt.
Params: None
Returns: Nothing
Caveats: It should be noted that the CLA byte is sent by PSDoCommand to start
the ball rolling. PSSendINS is the first interrupt action in normal
SIM command processing.
*/
void PSSendINS(void)
{
PSSend(PSCommandBuffer.INS);
PSIntAction = PSSendP1;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSSendP1;
//End PS Debug
#endif
}
/*------------------------------------------------------------------------*/
/*
Name: PSSendP1
Desc: Interrupt action for TX interrupt following transmission of the
INS byte of a Command Header. See ISO/IEC 7816-3 8.2.1.
This interrupt causes the P1 byte to be sent and changes interrupt
handler to send P2 byte on next interrupt.
Params: None
Returns: Nothing
Caveats:
*/
static void PSSendP1(void)
{
PSSend(PSCommandBuffer.P1);
PSIntAction = PSSendP2;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSSendP2;
//End PS Debug
#endif
}
/*------------------------------------------------------------------------*/
/*
Name: PSSendP2
Desc: Interrupt action for TX interrupt following transmission of a
P1 byte of a Command Header. See ISO/IEC 7816-3 8.2.1.
This interrupt causes the P2 byte to be sent and changes interrupt
handler to send P3 byte on next interrupt.
Params: None
Returns: Nothing
Caveats:
*/
static void PSSendP2(void)
{
PSSend(PSCommandBuffer.P2);
PSIntAction = PSSendP3;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSSendP3;
//End PS Debug
#endif
}
/*------------------------------------------------------------------------*/
/*
Name: PSSendP3
Desc: Interrupt action for TX interrupt following transmission of a
P2 byte of a Command Header. See ISO/IEC 7816-3 8.2.1.
This interrupt causes the P3 byte to be sent and changes interrupt
handler to change the UART to receive the procedure byte once the
P3 byte has been transmitted.
Params: None
Returns: Nothing
Caveats:
*/
static void PSSendP3(void)
{
PSSend(PSCommandBuffer.P3);
PSIntAction = PSTXOneByte;
#if SIM_DEBUG == SIM_DEBUG_MAX
//PS Debug...
OldIntAction_Dbg = NewIntAction_Dbg;
NewIntAction_Dbg = _PSTXOneByte;
//End PS Debug
#endif
}
/*------------------------------------------------------------------------*/
/*
Name: PSTXOneByte
Desc: Interrupt action for TX interrupt following transmission of a
P3 byte of a Command Header, or any data byte in 'Single Shot' mode.
See ISO/IEC 7816-3 8.2.2.
This interrupt changes the UART to receive mode in order to receive
a Procedure Byte, or Status Bytes.
If there is no further data to transfer The interrupt handler is
changed to wait for the status bytes. If more data is to be
transferred The interrupt handler is changed to wait for a procedure
byte.
Params: None
Returns: Nothing
Caveats:
*/
static void PSTXOneByte(void)
{
INT16 APDULength;
PSChangeTXtoRX();
// Check for FETCH command for which P3 is encoded as 0 for a 256 byte transfer.
if (PSCommandBuffer.INS == 0x12)
{
APDULength = (INT16)GetAPDULength(PSCommandBuffer.P3);
}
else
{
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -