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

📄 psgdrv.c

📁 SIM卡的驱动程序,有利于开发一些与SIM相通的一些工具,或者手机软件SIM驱动的开发
💻 C
📖 第 1 页 / 共 5 页
字号:
      APDULength = PSCommandBuffer.P3;
   }

   if (PSDataCount<APDULength)
      {
      PSIntAction = PSWaitProcByte;

#if SIM_DEBUG == SIM_DEBUG_MAX
      //PS Debug...
      OldIntAction_Dbg = NewIntAction_Dbg;
      NewIntAction_Dbg = _PSWaitProcByte;
      //End PS Debug
#endif
	  }
   else
     {
      PSIntAction = PSWaitStatus;

#if SIM_DEBUG == SIM_DEBUG_MAX
      //PS Debug...
      OldIntAction_Dbg = NewIntAction_Dbg;
      NewIntAction_Dbg = _PSWaitStatus;
      //End PS Debug
#endif

      EnableDMAWaitStatus();
     }
   }

/*------------------------------------------------------------------------*/

/*
Name:    PSWaitProcByte
Desc:    Interrupt action for TX interrupt when a Procedure Byte is expected
         See ISO/IEC 7816-3 8.2.2.
         This Handler Checks the value of the procedure byte and performs
         the appropriate action, depending on its value and the direction
         of the data transfer.
         The interrupt handler is changed as appropriate to the following
         action.
         The possible actions are:
             Await a single byte and return to waiting for a procedure byte.
             Send a single byte and return to waiting for a procedure byte.
             Await remaining bytes from the SIM.
             Send the remaining bytes to the SIM.
             Await the second Status byte if the Procedure Byte indicated
                   that something went wrong.
             Keep waiting for a procedure byte - the procedure byte was NULL.
Params:  None
Returns: Nothing
Caveats: Note this is the 'Critical' decision point in a SIM transfer!
         It is the only relatively complex Interrupt Action Function.
*/

static void PSWaitProcByte(void)
   {
   UINT8 RXByte, RXAck;
   DMA_THRESHOLD_PARAMS ThresholdParams;
   RXByte = PSGet();

   

   //GSMcprintf( MEMPutChar, "PSWaitProcByte\n" );

   if( *(UINT16 *)SIM_STAT_REG & SIM_ME_RX_FAIL )
   return;            //parity error, ignore it

   if (RXByte!=0x60)  /* Null byte... We have to be patient */
      {
      RXAck = (RXByte^PSCommandBuffer.INS)&0xFE;
      if (RXAck==0xFE) /* INS has been Acked - Transfer next byte only */
         {
         /* Note: no need to manipulate VPP on a GSM SIM
            If there is, then, check RXByte&0x01 */
         if (PSDirection==PS_WRITE)
            {
            PSChangeRXtoTX();
            // In enhanced mode, extend the guard period of Tx to avoid the SIM missing the start bit 
            // when change the direction of transmission from Rx to Tx.
            if (currentPTSState == PTS_IN_ENHANCED_MODE)
               PSSetGuardPeriod(PS_EXTENDED_GUARD_PERIOD);
            PSSend(PSDataBuffer[PSDataCount++]);
            PSIntAction = PSTXOneByte;

#if SIM_DEBUG == SIM_DEBUG_MAX
            //PS Debug...
            OldIntAction_Dbg = NewIntAction_Dbg;
            NewIntAction_Dbg = _PSTXOneByte;
            //End PS Debug
#endif
            }
         else
            {
            PSIntAction = PSRXOneByte;
#if SIM_DEBUG == SIM_DEBUG_MAX
            //PS Debug...
            OldIntAction_Dbg = NewIntAction_Dbg;
            NewIntAction_Dbg = _PSRXOneByte;
            //End PS Debug
#endif
			}
         }
      else if (RXAck==0x00) /* INS has been Acked - Transfer remaining bytes */
         {
         /* Note: no need to manipulate VPP on a GSM SIM
            If there is then, check RXByte&0x01 */
         if (PSDirection==PS_WRITE)
            {
            PSChangeRXtoTX();
            // In enhanced mode, extend the guard period of Tx to avoid the SIM missing the start bit 
            // when change the direction of transmission from Rx to Tx.
            if (currentPTSState == PTS_IN_ENHANCED_MODE)
               PSSetGuardPeriod(PS_EXTENDED_GUARD_PERIOD);
            PSSend(PSDataBuffer[PSDataCount++]);
            PSIntAction = PSTXData;
#if SIM_DEBUG == SIM_DEBUG_MAX
            //PS Debug...
            OldIntAction_Dbg = NewIntAction_Dbg;
            NewIntAction_Dbg = _PSTXData;
            //End PS Debug
#endif
            }
         else
            {
               PSIntAction = PSRXData;
#if SIM_DEBUG == SIM_DEBUG_MAX
               //PS Debug...
               OldIntAction_Dbg = NewIntAction_Dbg;
               NewIntAction_Dbg = _PSRXData;
               //End PS Debug
#endif
               
               PSTxDelayDisable();  /* CX805 we must disable Tx DMA Delay during receive DMA, GSMSW1625*/
               SetDMAController (SIMConfigDataPtr->pDMARegs, /* DMA Channel to be used */
                                 DEV_SEL_SIM,	                   /* SIM peripheral         */ 
                                (DMA_AUTO_STOP_ON | DMA_SRC_BYTE | DMA_DST_BYTE  | DMA_THR_INTEN), // DMA_AUTO_STOP and byte to byte xfer */
                                 DEV_TO_MEM,   
                                 SIMConfigDataPtr->pSIM_Src,
                                 SIMConfigDataPtr->BaseAddress,
                                 SIMConfigDataPtr->Length);

               // Check for FETCH command for which P3 is encoded as 0 for a 256 byte transfer.
               if (PSCommandBuffer.INS == 0x12) 
               {
                  SIMConfigDataPtr->EndAddress =(CHAR *)(SIMConfigDataPtr->BaseAddress + 
                                                GetAPDULength(PSCommandBuffer.P3) +1);
			   }
			   else
			   {
                  SIMConfigDataPtr->EndAddress =(CHAR *)(SIMConfigDataPtr->BaseAddress + 
                                                                 PSCommandBuffer.P3 +1);
			   }
               ThresholdParams.Threshold = (VOID *) SIMConfigDataPtr->EndAddress;
			   ThresholdParams.Mode = NON_CIRCULAR; // as non circular usage of DMA, no need to specify base and end address
													// for threshold setup
               
               SetDMAThreshold (SIMConfigDataPtr->pDMARegs, &ThresholdParams); 

               DEVICE_SPEC_EnableInterrupts(eIRQ1_NONE, eIRQ2_NONE,     // Enable nothing
                                            eIRQ1_SIM,  eIRQ2_NONE);    // Disable sim irq
               PSRxDMAEnabled=TRUE;
               DEVICE_SPEC_EnableInterrupts(SIM_DMA_IRQ, eIRQ2_NONE,     // Enable sim DMA
                                            eIRQ1_NONE,  eIRQ2_NONE);    // Disable nothing

               EnableDMA (SIMConfigDataPtr->pDMARegs);       
               DEVICE_SPEC_EnableInterrupts(eIRQ1_SIM,  eIRQ2_NONE,     // Enable sim irq
                                            eIRQ1_NONE, eIRQ2_NONE);    // Disable nothing
            }
         }
      else
         {
         RXAck = RXByte&0xF0;
         if (RXAck==0x60||RXAck==0x90) /* SIM has sent bad status - wait for
                                          second status byte */
            {
            PSStatusBuffer.SW1 = RXByte;
            PSBadSIMStatus = TRUE;
            PSIntAction = PSWaitSW2;
#if SIM_DEBUG == SIM_DEBUG_MAX
            //PS Debug...
            OldIntAction_Dbg = NewIntAction_Dbg;
            NewIntAction_Dbg = _PSWaitSW2;
            //End PS Debug
#endif
            }
         /* else it is a mystery byte - ignore it ?????? */
         }
      }
   }

/*------------------------------------------------------------------------*/

/*
Name:    PSRXOneByte
Desc:    Interrupt action for RX interrupt following reception of a data byte
         in 'Single Shot' mode.
         See ISO/IEC 7816-3 8.2.2.
         The handler stores the byte in the data buffer.
         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 PSRXOneByte(void)
   {
   INT16 APDULength;

   PSDataBuffer[PSDataCount++] = PSGet();

   // 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
   {
      APDULength = PSCommandBuffer.P3;
   }

   if (APDULength<=PSDataCount)
      {
      PSIntAction = PSWaitStatus;
#if SIM_DEBUG == SIM_DEBUG_MAX
      //PS Debug...
      OldIntAction_Dbg = NewIntAction_Dbg;
      NewIntAction_Dbg = _PSWaitStatus;
      //End PS Debug
#endif

      EnableDMAWaitStatus();
     }
   else
      {
      PSIntAction = PSWaitProcByte;
#if SIM_DEBUG == SIM_DEBUG_MAX
      //PS Debug...
      OldIntAction_Dbg = NewIntAction_Dbg;
      NewIntAction_Dbg = _PSWaitProcByte;
      //End PS Debug
#endif

	  }
   }

/*------------------------------------------------------------------------*/

/*
Name:    PSRXData
Desc:    Interrupt action for RX interrupt following reception of a data byte
         in normal mode.
         See ISO/IEC 7816-3 8.2.2.
         The handler stores the byte in the data buffer.
         If there is no further data to transfer The interrupt handler is
         changed to wait for the status bytes, otherwise it waits for the
         next byte.
Params:  None
Returns: Nothing
Caveats:
*/

static void PSRXData(void)
  {
   INT16 APDULength;

     SIMbuffPtr = (UINT8 *)SIMBuffer;

   // 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
   {
      APDULength = PSCommandBuffer.P3;
   }
     if( PSDataCount < APDULength  )    
        {
        DMABufferHasData = TRUE;
        }
     PSWaitStatus();
  }

/*------------------------------------------------------------------------*/

/*
Name:    PSTXData
Desc:    Interrupt action for TX interrupt following transmission of a data
         byte in normal mode.
         See ISO/IEC 7816-3 8.2.2.
         If there is further data to transfer, the next byte is transmitted.
         Otherwise the UART is changed to receive mode, and the interrupt
         handler changed to wait for the status bytes.
Params:  None
Returns: Nothing
Caveats:
*/

static void PSTXData(void)
   {

   //GSMcprintf( MEMPutChar, "PSTXData\n" );

   if (PSDataCount<PSCommandBuffer.P3)
      {
      PSSend(PSDataBuffer[PSDataCount++]);
      }
   else
      {
      PSChangeTXtoRX();
      PSIntAction = PSWaitStatus;
#if SIM_DEBUG == SIM_DEBUG_MAX
      //PS Debug...
      OldIntAction_Dbg = NewIntAction_Dbg;
      NewIntAction_Dbg = _PSWaitStatus;
      //End PS Debug
#endif

      EnableDMAWaitStatus();
      }
   }

/*------------------------------------------------------------------------*/

/*
Name:    PSWaitStatus
Desc:    Interrupt action for RX interrupt when a Status Byte, SW1 is expected
         See ISO/IEC 7816-3 8.2.2.
         Once correctly received, the interrupt handler is changed to expect
         the second status byte.
Params:  None
Returns: Nothing
Caveats:
*/

static void PSWaitStatus(void)
   {
   UINT8 RXByte, RXAck;
   INT16 APDULength;


   // 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
   {
      APDULength = PSCommandBuffer.P3;
   }

   //GSMcprintf( MEMPutChar, "PSWaitStatus\n" );

   if( DMABufferHasData )
      {
      SIMbuffPtr += APDULength;
      }
   RXByte = *SIMbuffPtr++;    //Read status byte
   if (RXByte!=0x60) /* Its a NULL byte - must be patient */
      {                                                    
      RXAck = RXByte&0xF0;
      if (RXAck==0x60||RXAck==0x90)
         {
         PSStatusBuffer.SW1 = RXByte;
		 PSIntAction = PSWaitSW2;
#if SIM_DEBUG == SIM_DEBUG_MAX
         //PS Debug...
         OldIntAction_Dbg = NewIntAction_Dbg;
         NewIntAction_Dbg = _PSWaitSW2;
         //End PS Debug
#endif

         }
      /* else it is a mystery byte - ignore it ?????? */
      }
   else
      {
      PSIntAction =	PSWaitStatusByteByByte;
#if SIM_DEBUG == SIM_DEBUG_MAX
      //PS Debug...
      OldIntAction_Dbg = NewIntAction_Dbg;
      NewIntAction_Dbg = _PSWaitStatusByteByByte;
      //End PS Debug
#endif
	  }
   }

⌨️ 快捷键说明

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