?? psgdrv.c
字號(hào):
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
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -