You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
856 lines
27 KiB
856 lines
27 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) SCM Microsystems, 1998 - 1999
|
|
//
|
|
// File: stccmd.c
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
#if defined( SMCLIB_VXD )
|
|
#include "Driver98.h"
|
|
#include "Serial98.h"
|
|
#else
|
|
#include "DriverNT.h"
|
|
#include "SerialNT.h"
|
|
#endif // SMCLIB_VXD
|
|
|
|
#include "SerialIF.h"
|
|
#include "STCCmd.h"
|
|
#include "STC.h"
|
|
|
|
const STC_REGISTER STCInitialize[] =
|
|
{
|
|
{ ADR_SC_CONTROL, 0x01, 0x00 }, // reset
|
|
{ ADR_CLOCK_CONTROL, 0x01, 0x01 },
|
|
{ ADR_CLOCK_CONTROL, 0x01, 0x03 },
|
|
{ ADR_UART_CONTROL, 0x01, 0x27 },
|
|
{ ADR_UART_CONTROL, 0x01, 0x4F },
|
|
{ ADR_IO_CONFIG, 0x01, 0x02 }, // 0x10 eva board
|
|
{ ADR_FIFO_CONFIG, 0x01, 0x81 },
|
|
{ ADR_INT_CONTROL, 0x01, 0x11 },
|
|
{ 0x0E, 0x01, 0xC0 },
|
|
{ 0x00, 0x00, 0x00 },
|
|
};
|
|
|
|
const STC_REGISTER STCClose[] =
|
|
{
|
|
{ ADR_INT_CONTROL, 0x01, 0x00 },
|
|
{ ADR_SC_CONTROL, 0x01, 0x00 }, // reset
|
|
{ ADR_UART_CONTROL, 0x01, 0x40 },
|
|
{ ADR_CLOCK_CONTROL, 0x01, 0x01 },
|
|
{ ADR_CLOCK_CONTROL, 0x01, 0x00 },
|
|
{ 0x00, 0x00, 0x00 },
|
|
};
|
|
|
|
|
|
|
|
NTSTATUS
|
|
STCReset(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
UCHAR Device,
|
|
BOOLEAN WarmReset,
|
|
PUCHAR pATR,
|
|
PULONG pATRLength
|
|
)
|
|
/*++
|
|
STCReset:
|
|
performs a reset of ICC
|
|
|
|
Arguments:
|
|
ReaderExtension context of call
|
|
Device device requested ( ICC_1, ICC_2, PSCR )
|
|
WarmReset kind of ICC reset
|
|
pATR ptr to ATR buffer, NULL if no ATR required
|
|
pATRLength size of ATR buffer / length of ATR
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS
|
|
STATUS_NO_MEDIA
|
|
STATUS_UNRECOGNIZED_MEDIA
|
|
error values from IFRead / IFWrite
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
|
|
// set UART to autolearn mode
|
|
NTStatus = STCInitUART( ReaderExtension, TRUE );
|
|
|
|
if( NTStatus == STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// set default frequency for ATR
|
|
//
|
|
NTStatus = STCSetFDIV( ReaderExtension, FREQ_DIV );
|
|
|
|
if( NTStatus == STATUS_SUCCESS && ( !WarmReset ))
|
|
{
|
|
//
|
|
// deactivate contacts
|
|
//
|
|
NTStatus = STCPowerOff( ReaderExtension );
|
|
}
|
|
|
|
if( NTStatus == STATUS_SUCCESS)
|
|
{
|
|
|
|
//
|
|
// set power to card
|
|
//
|
|
if( NTStatus == STATUS_SUCCESS)
|
|
{
|
|
NTStatus = STCPowerOn( ReaderExtension );
|
|
|
|
if( NTStatus == STATUS_SUCCESS)
|
|
{
|
|
NTStatus = STCReadATR( ReaderExtension, pATR, pATRLength );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( NTStatus != STATUS_SUCCESS )
|
|
{
|
|
STCPowerOff( ReaderExtension );
|
|
}
|
|
return( NTStatus );
|
|
}
|
|
|
|
NTSTATUS
|
|
STCReadATR(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
PUCHAR pATR,
|
|
PULONG pATRLen
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR T0_Yx, T0_K, Protocol;
|
|
ULONG ATRLen, BufferLength;
|
|
|
|
ReaderExtension->ReadTimeout = 250;
|
|
|
|
// read TS if active low reset
|
|
BufferLength = *pATRLen;
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
pATR,
|
|
&BufferLength,
|
|
1
|
|
);
|
|
|
|
if( NTStatus == STATUS_IO_TIMEOUT )
|
|
{
|
|
NTStatus = STCSetRST( ReaderExtension, TRUE );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
BufferLength = *pATRLen;
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
pATR,
|
|
&BufferLength,
|
|
1
|
|
);
|
|
}
|
|
}
|
|
|
|
ReaderExtension->ReadTimeout = 1200;
|
|
Protocol = PROTOCOL_TO;
|
|
ATRLen = 1;
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
BufferLength = *pATRLen - ATRLen;
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
pATR + ATRLen,
|
|
&BufferLength,
|
|
1
|
|
);
|
|
ATRLen++;
|
|
|
|
if ( pATR[0] == 0x03 ) /* Direct convention */
|
|
{
|
|
pATR[0] = 0x3F;
|
|
}
|
|
|
|
if ( ( pATR[0] != 0x3F ) && ( pATR[0] != 0x3B ) )
|
|
{
|
|
NTStatus = STATUS_DATA_ERROR;
|
|
}
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
ULONG Request;
|
|
|
|
// number of historical bytes
|
|
T0_K = (UCHAR) ( pATR[ATRLen-1] & 0x0F );
|
|
|
|
// coding of TA, TB, TC, TD
|
|
T0_Yx = (UCHAR) ( pATR[ATRLen-1] & 0xF0 ) >> 4;
|
|
|
|
while(( NTStatus == STATUS_SUCCESS ) && T0_Yx )
|
|
{
|
|
UCHAR Mask;
|
|
|
|
// evaluate presence of TA, TB, TC, TD
|
|
Mask = T0_Yx;
|
|
Request = 0;
|
|
while( Mask )
|
|
{
|
|
if( Mask & 1 )
|
|
{
|
|
Request++;
|
|
}
|
|
Mask >>= 1;
|
|
}
|
|
|
|
BufferLength = *pATRLen - ATRLen;
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
pATR + ATRLen,
|
|
&BufferLength,
|
|
Request
|
|
);
|
|
ATRLen += Request;
|
|
|
|
if( T0_Yx & TDx )
|
|
{
|
|
// high nibble of TD codes the next set of TA, TB, TC, TD
|
|
T0_Yx = ( pATR[ATRLen-1] & 0xF0 ) >> 4;
|
|
// low nibble of TD codes the protocol
|
|
Protocol = pATR[ATRLen-1] & 0x0F;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
// historical bytes
|
|
BufferLength = *pATRLen - ATRLen;
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
pATR + ATRLen,
|
|
&BufferLength,
|
|
T0_K
|
|
);
|
|
|
|
// check sum
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
ATRLen += T0_K;
|
|
|
|
if( Protocol == PROTOCOL_T1 )
|
|
{
|
|
BufferLength = *pATRLen - ATRLen;
|
|
NTStatus = STCReadICC1(
|
|
ReaderExtension,
|
|
pATR + ATRLen,
|
|
&BufferLength,
|
|
1
|
|
);
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
ATRLen++;
|
|
}
|
|
else if( NTStatus == STATUS_IO_TIMEOUT )
|
|
{
|
|
// some cards don't support the TCK
|
|
NTStatus = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( NTStatus == STATUS_IO_TIMEOUT )
|
|
{
|
|
NTStatus = STATUS_UNRECOGNIZED_MEDIA;
|
|
}
|
|
|
|
if(NTStatus == STATUS_SUCCESS && pATRLen != NULL)
|
|
{
|
|
*pATRLen = ATRLen;
|
|
}
|
|
return( NTStatus );
|
|
}
|
|
|
|
NTSTATUS
|
|
STCWriteICC1(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
PUCHAR Data,
|
|
ULONG DataLen
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
ULONG BytesWritten = 0, Partial;
|
|
USHORT SW = 0;
|
|
UCHAR IOData[STC_BUFFER_SIZE + 10];
|
|
|
|
do
|
|
{
|
|
if(DataLen - BytesWritten > STC_BUFFER_SIZE - PACKET_OVERHEAD)
|
|
{
|
|
Partial = STC_BUFFER_SIZE - PACKET_OVERHEAD;
|
|
}
|
|
else
|
|
{
|
|
Partial = DataLen - BytesWritten;
|
|
}
|
|
|
|
IOData[NAD_IDX] = HOST_TO_ICC1;
|
|
IOData[PCB_IDX] = PCB;
|
|
IOData[LEN_IDX] = (UCHAR) Partial;
|
|
|
|
SysCopyMemory(
|
|
&IOData[DATA_IDX],
|
|
Data + BytesWritten,
|
|
Partial
|
|
);
|
|
|
|
IOData[Partial + 3] = IFCalcLRC(IOData, Partial + 3);
|
|
|
|
NTStatus = IFWrite(
|
|
ReaderExtension,
|
|
IOData,
|
|
Partial + 4
|
|
);
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
// read the status back from the reader
|
|
NTStatus = IFRead(
|
|
ReaderExtension,
|
|
IOData,
|
|
6
|
|
);
|
|
|
|
if(NTStatus == STATUS_SUCCESS &&
|
|
*(PUSHORT) &IOData[DATA_IDX] != SW_SUCCESS ) {
|
|
|
|
SmartcardDebug(
|
|
DEBUG_ERROR,
|
|
("SCMSTCS!STCWriteICC1: Reader reported error %x\n",
|
|
*(PUSHORT) &IOData[DATA_IDX])
|
|
);
|
|
|
|
NTStatus = STATUS_UNSUCCESSFUL;
|
|
}
|
|
}
|
|
|
|
BytesWritten += Partial;
|
|
|
|
} while(BytesWritten < DataLen && NTStatus == STATUS_SUCCESS);
|
|
|
|
return NTStatus;
|
|
}
|
|
|
|
NTSTATUS
|
|
STCReadICC1(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
PUCHAR InData,
|
|
PULONG InDataLen,
|
|
ULONG BytesRead
|
|
)
|
|
{
|
|
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR IOData[ STC_BUFFER_SIZE ];
|
|
ULONG Total = 0;
|
|
|
|
while(NTStatus == STATUS_SUCCESS && Total < BytesRead)
|
|
{
|
|
// read head
|
|
NTStatus = IFRead( ReaderExtension, &IOData[0], 3 );
|
|
|
|
if(NTStatus == STATUS_SUCCESS && IOData[LEN_IDX] < STC_BUFFER_SIZE - 4)
|
|
{
|
|
// read tail
|
|
NTStatus = IFRead(
|
|
ReaderExtension,
|
|
&IOData[DATA_IDX],
|
|
IOData[LEN_IDX] + 1
|
|
);
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
if (IOData[NAD_IDX] == STC1_TO_HOST) {
|
|
|
|
//
|
|
// this is not good. We want to read smart card data,
|
|
// but the reader sent us a status packet, which can
|
|
// only mean that something went wrong
|
|
//
|
|
SmartcardDebug(
|
|
DEBUG_ERROR,
|
|
( "SCMSTCS!STCReadICC1: Reader reported error %x\n",
|
|
*(PUSHORT) &IOData[DATA_IDX])
|
|
);
|
|
|
|
NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
|
|
break;
|
|
}
|
|
|
|
if (Total + IOData[LEN_IDX] > *InDataLen) {
|
|
|
|
NTStatus = STATUS_BUFFER_TOO_SMALL;
|
|
break;
|
|
}
|
|
|
|
SysCopyMemory( &InData[ Total ], &IOData[ DATA_IDX ], IOData[ LEN_IDX ] );
|
|
Total += IOData[ LEN_IDX ];
|
|
}
|
|
}
|
|
}
|
|
|
|
*InDataLen = Total;
|
|
|
|
return NTStatus;
|
|
}
|
|
|
|
NTSTATUS
|
|
STCPowerOff( PREADER_EXTENSION ReaderExtension )
|
|
/*++
|
|
STCPowerOff:
|
|
Deactivates the requested device
|
|
|
|
Arguments:
|
|
ReaderExtension context of call
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS
|
|
error values from IFRead / IFWrite
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR SCCtrl;
|
|
|
|
SCCtrl = 0x00;
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
|
|
|
|
return( NTStatus );
|
|
}
|
|
|
|
NTSTATUS
|
|
STCPowerOn( PREADER_EXTENSION ReaderExtension )
|
|
/*++
|
|
STCPowerOn:
|
|
Deactivates the requested device
|
|
|
|
Arguments:
|
|
ReaderExtension context of call
|
|
|
|
Return Value:
|
|
STATUS_SUCCESS
|
|
error values from IFRead / IFWrite
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR SCCtrl;
|
|
|
|
SCCtrl = 0x40; // vcc
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
SCCtrl = 0x41; // vpp
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
SCCtrl=0xD1; // vcc, clk, io
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
|
|
}
|
|
}
|
|
return( NTStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
STCSetRST(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
BOOLEAN On
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR SCCtrl;
|
|
|
|
NTStatus = STCReadSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1,&SCCtrl );
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
if( On )
|
|
{
|
|
SCCtrl |= 0x20;
|
|
}
|
|
else
|
|
{
|
|
SCCtrl &= ~0x20;
|
|
}
|
|
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1,&SCCtrl );
|
|
}
|
|
return(NTStatus);
|
|
}
|
|
|
|
NTSTATUS
|
|
STCConfigureSTC(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
PSTC_REGISTER pConfiguration
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR Value;
|
|
|
|
do
|
|
{
|
|
|
|
if( pConfiguration->Register == ADR_INT_CONTROL )
|
|
{
|
|
// Read interrupt status register to acknoledge wrong states
|
|
NTStatus = STCReadSTCRegister( ReaderExtension,ADR_INT_STATUS,1,&Value );
|
|
}
|
|
|
|
Value = (UCHAR)pConfiguration->Value;
|
|
NTStatus = STCWriteSTCRegister(
|
|
ReaderExtension,
|
|
pConfiguration->Register,
|
|
pConfiguration->Size,
|
|
(PUCHAR)&pConfiguration->Value
|
|
);
|
|
|
|
// delay to stabilize the oscilator clock:
|
|
if( pConfiguration->Register == ADR_CLOCK_CONTROL )
|
|
{
|
|
SysDelay( 50 );
|
|
}
|
|
pConfiguration++;
|
|
|
|
} while(( NTStatus == STATUS_SUCCESS ) && ( pConfiguration->Size ));
|
|
|
|
return (NTStatus);
|
|
}
|
|
|
|
NTSTATUS STCReadSTCRegister(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
UCHAR Address,
|
|
ULONG Size,
|
|
PUCHAR pValue
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR IOData[ STC_BUFFER_SIZE ] =
|
|
{
|
|
HOST_TO_STC1,
|
|
PCB,
|
|
6,
|
|
CLA_READ_REGISTER,
|
|
INS_READ_REGISTER,
|
|
0x00,
|
|
Address,
|
|
0x00,
|
|
(UCHAR) Size
|
|
};
|
|
|
|
IOData[ 9 ] = IFCalcLRC( IOData, 9 );
|
|
|
|
NTStatus = IFWrite( ReaderExtension, IOData, 10 );
|
|
ASSERT(NTStatus == STATUS_SUCCESS);
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
NTStatus = IFRead( ReaderExtension, IOData, Size + 2 + 4 );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
//
|
|
// check return code & size
|
|
//
|
|
USHORT shrtBuf;
|
|
|
|
RtlRetrieveUshort(&shrtBuf, &IOData[DATA_IDX + Size]);
|
|
|
|
if( shrtBuf == SW_SUCCESS )
|
|
{
|
|
SysCopyMemory( pValue, &IOData[ DATA_IDX ] , Size );
|
|
}
|
|
else
|
|
{
|
|
ASSERT(FALSE);
|
|
NTStatus = STATUS_DATA_ERROR;
|
|
}
|
|
}
|
|
}
|
|
return( NTStatus );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
STCWriteSTCRegister(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
UCHAR Address,
|
|
ULONG Size,
|
|
PUCHAR pValue
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR IOData[STC_BUFFER_SIZE] =
|
|
{
|
|
HOST_TO_STC1,
|
|
PCB,
|
|
(UCHAR)( 5+Size ),
|
|
CLA_WRITE_REGISTER,
|
|
INS_WRITE_REGISTER,
|
|
0x00,
|
|
Address,
|
|
(UCHAR) Size
|
|
};
|
|
|
|
SysCopyMemory( &IOData[ 8 ], pValue, Size );
|
|
|
|
IOData[ 8+Size ] = IFCalcLRC( IOData, 8 + Size );
|
|
|
|
NTStatus = IFWrite( ReaderExtension, IOData, 9 + Size );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
NTStatus = IFRead( ReaderExtension, IOData, 6 );
|
|
|
|
if(( NTStatus == STATUS_SUCCESS ) && ( *(PUSHORT)&IOData[ DATA_IDX ] != 0x0090 ))
|
|
{
|
|
NTStatus = STATUS_DATA_ERROR;
|
|
}
|
|
}
|
|
return( NTStatus );
|
|
}
|
|
|
|
NTSTATUS
|
|
STCSetETU(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
ULONG NewETU
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_DATA_ERROR;
|
|
UCHAR ETU[2];
|
|
|
|
if( NewETU < 0x0FFF )
|
|
{
|
|
NTStatus = STCReadSTCRegister(
|
|
ReaderExtension,
|
|
ADR_ETULENGTH15,
|
|
1,
|
|
ETU
|
|
);
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
//
|
|
// save all RFU bits
|
|
//
|
|
ETU[1] = (UCHAR) NewETU;
|
|
ETU[0] = (UCHAR)(( ETU[0] & 0xF0 ) | ( NewETU >> 8 ));
|
|
|
|
NTStatus = STCWriteSTCRegister(
|
|
ReaderExtension,
|
|
ADR_ETULENGTH15,
|
|
2,
|
|
ETU
|
|
);
|
|
}
|
|
}
|
|
return(NTStatus);
|
|
}
|
|
|
|
NTSTATUS
|
|
STCSetCGT(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
ULONG NewCGT
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_DATA_ERROR;
|
|
UCHAR CGT[2];
|
|
|
|
if( NewCGT < 0x01FF )
|
|
{
|
|
NTStatus = STCReadSTCRegister(
|
|
ReaderExtension,
|
|
ADR_CGT8,
|
|
2,
|
|
CGT
|
|
);
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
//
|
|
// save all RFU bits
|
|
//
|
|
CGT[1] = ( UCHAR )NewCGT;
|
|
CGT[0] = (UCHAR)(( CGT[0] & 0xFE ) | ( NewCGT >> 8 ));
|
|
|
|
NTStatus = STCWriteSTCRegister(
|
|
ReaderExtension,
|
|
ADR_CGT8,
|
|
2,
|
|
CGT
|
|
);
|
|
}
|
|
}
|
|
return(NTStatus);
|
|
}
|
|
|
|
NTSTATUS
|
|
STCSetCWT(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
ULONG NewCWT
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR CWT[4];
|
|
|
|
// little indians...
|
|
CWT[0] = (( PUCHAR )&NewCWT )[3];
|
|
CWT[1] = (( PUCHAR )&NewCWT )[2];
|
|
CWT[2] = (( PUCHAR )&NewCWT )[1];
|
|
CWT[3] = (( PUCHAR )&NewCWT )[0];
|
|
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_CWT31, 4, CWT );
|
|
return(NTStatus);
|
|
}
|
|
|
|
NTSTATUS
|
|
STCSetBWT(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
ULONG NewBWT
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR BWT[4];
|
|
|
|
// little indians...
|
|
BWT[0] = (( PUCHAR )&NewBWT )[3];
|
|
BWT[1] = (( PUCHAR )&NewBWT )[2];
|
|
BWT[2] = (( PUCHAR )&NewBWT )[1];
|
|
BWT[3] = (( PUCHAR )&NewBWT )[0];
|
|
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_BWT31, 4, BWT );
|
|
|
|
return(NTStatus);
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
STCSetFDIV(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
ULONG Factor
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR DIV;
|
|
|
|
NTStatus = STCReadSTCRegister( ReaderExtension, ADR_ETULENGTH15, 1, &DIV );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
switch( Factor )
|
|
{
|
|
case 1:
|
|
DIV &= ~M_DIV0;
|
|
DIV &= ~M_DIV1;
|
|
break;
|
|
|
|
case 2:
|
|
DIV |= M_DIV0;
|
|
DIV &= ~M_DIV1;
|
|
break;
|
|
|
|
case 4 :
|
|
DIV &= ~M_DIV0;
|
|
DIV |= M_DIV1;
|
|
break;
|
|
|
|
case 8 :
|
|
DIV |= M_DIV0;
|
|
DIV |= M_DIV1;
|
|
break;
|
|
|
|
default :
|
|
NTStatus = STATUS_DATA_ERROR;
|
|
}
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_ETULENGTH15, 1, &DIV );
|
|
}
|
|
}
|
|
return(NTStatus);
|
|
}
|
|
|
|
NTSTATUS
|
|
STCInitUART(
|
|
PREADER_EXTENSION ReaderExtension,
|
|
BOOLEAN AutoLearn
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR Value;
|
|
|
|
Value = AutoLearn ? 0x6F : 0x66;
|
|
|
|
NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_UART_CONTROL, 1, &Value );
|
|
|
|
return( NTStatus );
|
|
}
|
|
|
|
NTSTATUS
|
|
STCGetFirmwareRevision(
|
|
PREADER_EXTENSION ReaderExtension
|
|
)
|
|
{
|
|
NTSTATUS NTStatus = STATUS_SUCCESS;
|
|
UCHAR IOData[ STC_BUFFER_SIZE ] =
|
|
{
|
|
HOST_TO_STC1,
|
|
PCB,
|
|
6,
|
|
CLA_READ_FIRMWARE_REVISION,
|
|
INS_READ_FIRMWARE_REVISION,
|
|
0x00,
|
|
0x00,
|
|
0x00,
|
|
0x02
|
|
};
|
|
|
|
IOData[ 9 ] = IFCalcLRC( IOData, 9 );
|
|
|
|
NTStatus = IFWrite( ReaderExtension, IOData, 10 );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
NTStatus = IFRead( ReaderExtension, IOData, 6 );
|
|
|
|
if( NTStatus == STATUS_SUCCESS )
|
|
{
|
|
ReaderExtension->FirmwareMajor = IOData[ DATA_IDX ];
|
|
ReaderExtension->FirmwareMinor = IOData[ DATA_IDX + 1 ];
|
|
}
|
|
}
|
|
return( STATUS_SUCCESS );
|
|
}
|
|
|
|
//---------------------------------------- END OF FILE ----------------------------------------
|