⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psgdrv.c

📁 SIM卡的驱动程序,有利于开发一些与SIM相通的一些工具,或者手机软件SIM驱动的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
      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
   {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -