Source code of Windows XP (NT5)
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.

909 lines
28 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) SCM Microsystems, 1998 - 1999
  6. //
  7. // File: stccmd.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #if defined( SMCLIB_VXD )
  11. #include "Driver98.h"
  12. #include "Serial98.h"
  13. #else
  14. #include "DriverNT.h"
  15. #include "SerialNT.h"
  16. #endif // SMCLIB_VXD
  17. #include "SerialIF.h"
  18. #include "STCCmd.h"
  19. #include "STC.h"
  20. const STC_REGISTER STCInitialize[] =
  21. {
  22. { ADR_SC_CONTROL, 0x01, 0x00 }, // reset
  23. { ADR_CLOCK_CONTROL, 0x01, 0x01 },
  24. { ADR_CLOCK_CONTROL, 0x01, 0x03 },
  25. { ADR_UART_CONTROL, 0x01, 0x27 },
  26. { ADR_UART_CONTROL, 0x01, 0x4F },
  27. { ADR_IO_CONFIG, 0x01, 0x02 }, // 0x10 eva board
  28. { ADR_FIFO_CONFIG, 0x01, 0x81 },
  29. { ADR_INT_CONTROL, 0x01, 0x11 },
  30. { 0x0E, 0x01, 0xC0 },
  31. { 0x00, 0x00, 0x00 },
  32. };
  33. const STC_REGISTER STCClose[] =
  34. {
  35. { ADR_INT_CONTROL, 0x01, 0x00 },
  36. { ADR_SC_CONTROL, 0x01, 0x00 }, // reset
  37. { ADR_UART_CONTROL, 0x01, 0x40 },
  38. { ADR_CLOCK_CONTROL, 0x01, 0x01 },
  39. { ADR_CLOCK_CONTROL, 0x01, 0x00 },
  40. { 0x00, 0x00, 0x00 },
  41. };
  42. NTSTATUS
  43. STCReset(
  44. PREADER_EXTENSION ReaderExtension,
  45. UCHAR Device,
  46. BOOLEAN WarmReset,
  47. PUCHAR pATR,
  48. PULONG pATRLength
  49. )
  50. /*++
  51. STCReset:
  52. performs a reset of ICC
  53. Arguments:
  54. ReaderExtension context of call
  55. Device device requested ( ICC_1, ICC_2, PSCR )
  56. WarmReset kind of ICC reset
  57. pATR ptr to ATR buffer, NULL if no ATR required
  58. pATRLength size of ATR buffer / length of ATR
  59. Return Value:
  60. STATUS_SUCCESS
  61. STATUS_NO_MEDIA
  62. STATUS_UNRECOGNIZED_MEDIA
  63. error values from IFRead / IFWrite
  64. --*/
  65. {
  66. NTSTATUS NTStatus = STATUS_SUCCESS;
  67. // set UART to autolearn mode
  68. NTStatus = STCInitUART( ReaderExtension, TRUE );
  69. if( NTStatus == STATUS_SUCCESS)
  70. {
  71. //
  72. // set default frequency for ATR
  73. //
  74. NTStatus = STCSetFDIV( ReaderExtension, FREQ_DIV );
  75. if( NTStatus == STATUS_SUCCESS && ( !WarmReset ))
  76. {
  77. //
  78. // deactivate contacts
  79. //
  80. NTStatus = STCPowerOff( ReaderExtension );
  81. }
  82. if( NTStatus == STATUS_SUCCESS)
  83. {
  84. BOOLEAN Detected;
  85. //
  86. // short circuit test
  87. //
  88. NTStatus = STCShortCircuitTest( ReaderExtension, &Detected );
  89. if( ( NTStatus == STATUS_SUCCESS ) && ( Detected ))
  90. {
  91. NTStatus = STATUS_DATA_ERROR;
  92. }
  93. //
  94. // set power to card
  95. //
  96. if( NTStatus == STATUS_SUCCESS)
  97. {
  98. NTStatus = STCPowerOn( ReaderExtension );
  99. if( NTStatus == STATUS_SUCCESS)
  100. {
  101. NTStatus = STCReadATR( ReaderExtension, pATR, pATRLength );
  102. }
  103. }
  104. }
  105. }
  106. if( NTStatus != STATUS_SUCCESS )
  107. {
  108. STCPowerOff( ReaderExtension );
  109. }
  110. return( NTStatus );
  111. }
  112. NTSTATUS
  113. STCReadATR(
  114. PREADER_EXTENSION ReaderExtension,
  115. PUCHAR pATR,
  116. PULONG pATRLen
  117. )
  118. {
  119. NTSTATUS NTStatus = STATUS_SUCCESS;
  120. UCHAR T0_Yx, T0_K, Protocol;
  121. ULONG ATRLen, BufferLength;
  122. ReaderExtension->ReadTimeout = 250;
  123. // read TS if active low reset
  124. BufferLength = *pATRLen;
  125. NTStatus = STCReadICC1(
  126. ReaderExtension,
  127. pATR,
  128. &BufferLength,
  129. 1
  130. );
  131. if( NTStatus == STATUS_IO_TIMEOUT )
  132. {
  133. NTStatus = STCSetRST( ReaderExtension, TRUE );
  134. if( NTStatus == STATUS_SUCCESS )
  135. {
  136. BufferLength = *pATRLen;
  137. NTStatus = STCReadICC1(
  138. ReaderExtension,
  139. pATR,
  140. &BufferLength,
  141. 1
  142. );
  143. }
  144. }
  145. ReaderExtension->ReadTimeout = 1200;
  146. Protocol = PROTOCOL_TO;
  147. ATRLen = 1;
  148. if( NTStatus == STATUS_SUCCESS )
  149. {
  150. BufferLength = *pATRLen - ATRLen;
  151. NTStatus = STCReadICC1(
  152. ReaderExtension,
  153. pATR + ATRLen,
  154. &BufferLength,
  155. 1
  156. );
  157. ATRLen++;
  158. if ( pATR[0] == 0x03 ) /* Direct convention */
  159. {
  160. pATR[0] = 0x3F;
  161. }
  162. if ( ( pATR[0] != 0x3F ) && ( pATR[0] != 0x3B ) )
  163. {
  164. NTStatus = STATUS_DATA_ERROR;
  165. }
  166. if( NTStatus == STATUS_SUCCESS )
  167. {
  168. ULONG Request;
  169. // number of historical bytes
  170. T0_K = (UCHAR) ( pATR[ATRLen-1] & 0x0F );
  171. // coding of TA, TB, TC, TD
  172. T0_Yx = (UCHAR) ( pATR[ATRLen-1] & 0xF0 ) >> 4;
  173. while(( NTStatus == STATUS_SUCCESS ) && T0_Yx )
  174. {
  175. UCHAR Mask;
  176. // evaluate presence of TA, TB, TC, TD
  177. Mask = T0_Yx;
  178. Request = 0;
  179. while( Mask )
  180. {
  181. if( Mask & 1 )
  182. {
  183. Request++;
  184. }
  185. Mask >>= 1;
  186. }
  187. BufferLength = *pATRLen - ATRLen;
  188. NTStatus = STCReadICC1(
  189. ReaderExtension,
  190. pATR + ATRLen,
  191. &BufferLength,
  192. Request
  193. );
  194. ATRLen += Request;
  195. if( T0_Yx & TDx )
  196. {
  197. // high nibble of TD codes the next set of TA, TB, TC, TD
  198. T0_Yx = ( pATR[ATRLen-1] & 0xF0 ) >> 4;
  199. // low nibble of TD codes the protocol
  200. Protocol = pATR[ATRLen-1] & 0x0F;
  201. }
  202. else
  203. {
  204. break;
  205. }
  206. }
  207. if( NTStatus == STATUS_SUCCESS )
  208. {
  209. // historical bytes
  210. BufferLength = *pATRLen - ATRLen;
  211. NTStatus = STCReadICC1(
  212. ReaderExtension,
  213. pATR + ATRLen,
  214. &BufferLength,
  215. T0_K
  216. );
  217. // check sum
  218. if( NTStatus == STATUS_SUCCESS )
  219. {
  220. ATRLen += T0_K;
  221. if( Protocol == PROTOCOL_T1 )
  222. {
  223. BufferLength = *pATRLen - ATRLen;
  224. NTStatus = STCReadICC1(
  225. ReaderExtension,
  226. pATR + ATRLen,
  227. &BufferLength,
  228. 1
  229. );
  230. if( NTStatus == STATUS_SUCCESS )
  231. {
  232. ATRLen++;
  233. }
  234. else if( NTStatus == STATUS_IO_TIMEOUT )
  235. {
  236. // some cards don't support the TCK
  237. NTStatus = STATUS_SUCCESS;
  238. }
  239. }
  240. }
  241. }
  242. }
  243. }
  244. if( NTStatus == STATUS_IO_TIMEOUT )
  245. {
  246. NTStatus = STATUS_UNRECOGNIZED_MEDIA;
  247. }
  248. if(NTStatus == STATUS_SUCCESS && pATRLen != NULL)
  249. {
  250. *pATRLen = ATRLen;
  251. }
  252. return( NTStatus );
  253. }
  254. NTSTATUS
  255. STCWriteICC1(
  256. PREADER_EXTENSION ReaderExtension,
  257. PUCHAR Data,
  258. ULONG DataLen
  259. )
  260. /*++
  261. Routine Description:
  262. Arguments:
  263. Return Value:
  264. --*/
  265. {
  266. NTSTATUS NTStatus = STATUS_SUCCESS;
  267. ULONG BytesWritten = 0, Partial;
  268. USHORT SW = 0;
  269. UCHAR IOData[STC_BUFFER_SIZE + 10];
  270. do
  271. {
  272. if(DataLen - BytesWritten > STC_BUFFER_SIZE - PACKET_OVERHEAD)
  273. {
  274. Partial = STC_BUFFER_SIZE - PACKET_OVERHEAD;
  275. }
  276. else
  277. {
  278. Partial = DataLen - BytesWritten;
  279. }
  280. IOData[NAD_IDX] = HOST_TO_ICC1;
  281. IOData[PCB_IDX] = PCB;
  282. IOData[LEN_IDX] = (UCHAR) Partial;
  283. SysCopyMemory(
  284. &IOData[DATA_IDX],
  285. Data + BytesWritten,
  286. Partial
  287. );
  288. IOData[Partial + 3] = IFCalcLRC(IOData, Partial + 3);
  289. NTStatus = IFWrite(
  290. ReaderExtension,
  291. IOData,
  292. Partial + 4
  293. );
  294. if( NTStatus == STATUS_SUCCESS )
  295. {
  296. // read the status back from the reader
  297. NTStatus = IFRead(
  298. ReaderExtension,
  299. IOData,
  300. 6
  301. );
  302. if(NTStatus == STATUS_SUCCESS &&
  303. *(PUSHORT) &IOData[DATA_IDX] != SW_SUCCESS ) {
  304. SmartcardDebug(
  305. DEBUG_ERROR,
  306. ("SCMSTCS!STCWriteICC1: Reader reported error %x\n",
  307. *(PUSHORT) &IOData[DATA_IDX])
  308. );
  309. NTStatus = STATUS_UNSUCCESSFUL;
  310. }
  311. }
  312. BytesWritten += Partial;
  313. } while(BytesWritten < DataLen && NTStatus == STATUS_SUCCESS);
  314. return NTStatus;
  315. }
  316. NTSTATUS
  317. STCReadICC1(
  318. PREADER_EXTENSION ReaderExtension,
  319. PUCHAR InData,
  320. PULONG InDataLen,
  321. ULONG BytesRead
  322. )
  323. {
  324. NTSTATUS NTStatus = STATUS_SUCCESS;
  325. UCHAR IOData[ STC_BUFFER_SIZE ];
  326. ULONG Total = 0;
  327. while(NTStatus == STATUS_SUCCESS && Total < BytesRead)
  328. {
  329. // read head
  330. NTStatus = IFRead( ReaderExtension, &IOData[0], 3 );
  331. if(NTStatus == STATUS_SUCCESS && IOData[LEN_IDX] < STC_BUFFER_SIZE - 4)
  332. {
  333. // read tail
  334. NTStatus = IFRead(
  335. ReaderExtension,
  336. &IOData[DATA_IDX],
  337. IOData[LEN_IDX] + 1
  338. );
  339. if( NTStatus == STATUS_SUCCESS )
  340. {
  341. if (IOData[NAD_IDX] == STC1_TO_HOST) {
  342. //
  343. // this is not good. We want to read smart card data,
  344. // but the reader sent us a status packet, which can
  345. // only mean that something went wrong
  346. //
  347. SmartcardDebug(
  348. DEBUG_ERROR,
  349. ( "SCMSTCS!STCReadICC1: Reader reported error %x\n",
  350. *(PUSHORT) &IOData[DATA_IDX])
  351. );
  352. NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
  353. break;
  354. }
  355. if (Total + IOData[LEN_IDX] > *InDataLen) {
  356. NTStatus = STATUS_BUFFER_TOO_SMALL;
  357. break;
  358. }
  359. SysCopyMemory( &InData[ Total ], &IOData[ DATA_IDX ], IOData[ LEN_IDX ] );
  360. Total += IOData[ LEN_IDX ];
  361. }
  362. }
  363. }
  364. *InDataLen = Total;
  365. return NTStatus;
  366. }
  367. NTSTATUS
  368. STCPowerOff( PREADER_EXTENSION ReaderExtension )
  369. /*++
  370. STCPowerOff:
  371. Deactivates the requested device
  372. Arguments:
  373. ReaderExtension context of call
  374. Return Value:
  375. STATUS_SUCCESS
  376. error values from IFRead / IFWrite
  377. --*/
  378. {
  379. NTSTATUS NTStatus = STATUS_SUCCESS;
  380. UCHAR SCCtrl;
  381. SCCtrl = 0x00;
  382. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
  383. return( NTStatus );
  384. }
  385. NTSTATUS
  386. STCPowerOn( PREADER_EXTENSION ReaderExtension )
  387. /*++
  388. STCPowerOn:
  389. Deactivates the requested device
  390. Arguments:
  391. ReaderExtension context of call
  392. Return Value:
  393. STATUS_SUCCESS
  394. error values from IFRead / IFWrite
  395. --*/
  396. {
  397. NTSTATUS NTStatus = STATUS_SUCCESS;
  398. UCHAR SCCtrl;
  399. SCCtrl = 0x40; // vcc
  400. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
  401. if( NTStatus == STATUS_SUCCESS )
  402. {
  403. SCCtrl = 0x41; // vpp
  404. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
  405. if( NTStatus == STATUS_SUCCESS )
  406. {
  407. SCCtrl=0xD1; // vcc, clk, io
  408. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1, &SCCtrl );
  409. }
  410. }
  411. return( NTStatus );
  412. }
  413. NTSTATUS
  414. STCSetRST(
  415. PREADER_EXTENSION ReaderExtension,
  416. BOOLEAN On
  417. )
  418. {
  419. NTSTATUS NTStatus = STATUS_SUCCESS;
  420. UCHAR SCCtrl;
  421. NTStatus = STCReadSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1,&SCCtrl );
  422. if( NTStatus == STATUS_SUCCESS )
  423. {
  424. if( On )
  425. {
  426. SCCtrl |= 0x20;
  427. }
  428. else
  429. {
  430. SCCtrl &= ~0x20;
  431. }
  432. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_SC_CONTROL, 1,&SCCtrl );
  433. }
  434. return(NTStatus);
  435. }
  436. NTSTATUS
  437. STCConfigureSTC(
  438. PREADER_EXTENSION ReaderExtension,
  439. PSTC_REGISTER pConfiguration
  440. )
  441. {
  442. NTSTATUS NTStatus = STATUS_SUCCESS;
  443. UCHAR Value;
  444. do
  445. {
  446. if( pConfiguration->Register == ADR_INT_CONTROL )
  447. {
  448. // Read interrupt status register to acknoledge wrong states
  449. NTStatus = STCReadSTCRegister( ReaderExtension,ADR_INT_STATUS,1,&Value );
  450. }
  451. Value = (UCHAR)pConfiguration->Value;
  452. NTStatus = STCWriteSTCRegister(
  453. ReaderExtension,
  454. pConfiguration->Register,
  455. pConfiguration->Size,
  456. (PUCHAR)&pConfiguration->Value
  457. );
  458. // delay to stabilize the oscilator clock:
  459. if( pConfiguration->Register == ADR_CLOCK_CONTROL )
  460. {
  461. SysDelay( 50 );
  462. }
  463. pConfiguration++;
  464. } while(( NTStatus == STATUS_SUCCESS ) && ( pConfiguration->Size ));
  465. return (NTStatus);
  466. }
  467. NTSTATUS STCReadSTCRegister(
  468. PREADER_EXTENSION ReaderExtension,
  469. UCHAR Address,
  470. ULONG Size,
  471. PUCHAR pValue
  472. )
  473. {
  474. NTSTATUS NTStatus = STATUS_SUCCESS;
  475. UCHAR IOData[ STC_BUFFER_SIZE ] =
  476. {
  477. HOST_TO_STC1,
  478. PCB,
  479. 6,
  480. CLA_READ_REGISTER,
  481. INS_READ_REGISTER,
  482. 0x00,
  483. Address,
  484. 0x00,
  485. (UCHAR) Size
  486. };
  487. IOData[ 9 ] = IFCalcLRC( IOData, 9 );
  488. NTStatus = IFWrite( ReaderExtension, IOData, 10 );
  489. ASSERT(NTStatus == STATUS_SUCCESS);
  490. if( NTStatus == STATUS_SUCCESS )
  491. {
  492. NTStatus = IFRead( ReaderExtension, IOData, Size + 2 + 4 );
  493. if( NTStatus == STATUS_SUCCESS )
  494. {
  495. //
  496. // check return code & size
  497. //
  498. USHORT shrtBuf;
  499. RtlRetrieveUshort(&shrtBuf, &IOData[DATA_IDX + Size]);
  500. if( shrtBuf == SW_SUCCESS )
  501. {
  502. SysCopyMemory( pValue, &IOData[ DATA_IDX ] , Size );
  503. }
  504. else
  505. {
  506. ASSERT(FALSE);
  507. NTStatus = STATUS_DATA_ERROR;
  508. }
  509. }
  510. }
  511. return( NTStatus );
  512. }
  513. NTSTATUS
  514. STCWriteSTCRegister(
  515. PREADER_EXTENSION ReaderExtension,
  516. UCHAR Address,
  517. ULONG Size,
  518. PUCHAR pValue
  519. )
  520. {
  521. NTSTATUS NTStatus = STATUS_SUCCESS;
  522. UCHAR IOData[STC_BUFFER_SIZE] =
  523. {
  524. HOST_TO_STC1,
  525. PCB,
  526. (UCHAR)( 5+Size ),
  527. CLA_WRITE_REGISTER,
  528. INS_WRITE_REGISTER,
  529. 0x00,
  530. Address,
  531. (UCHAR) Size
  532. };
  533. SysCopyMemory( &IOData[ 8 ], pValue, Size );
  534. IOData[ 8+Size ] = IFCalcLRC( IOData, 8 + Size );
  535. NTStatus = IFWrite( ReaderExtension, IOData, 9 + Size );
  536. if( NTStatus == STATUS_SUCCESS )
  537. {
  538. NTStatus = IFRead( ReaderExtension, IOData, 6 );
  539. if(( NTStatus == STATUS_SUCCESS ) && ( *(PUSHORT)&IOData[ DATA_IDX ] != 0x0090 ))
  540. {
  541. NTStatus = STATUS_DATA_ERROR;
  542. }
  543. }
  544. return( NTStatus );
  545. }
  546. NTSTATUS
  547. STCSetETU(
  548. PREADER_EXTENSION ReaderExtension,
  549. ULONG NewETU
  550. )
  551. {
  552. NTSTATUS NTStatus = STATUS_DATA_ERROR;
  553. UCHAR ETU[2];
  554. if( NewETU < 0x0FFF )
  555. {
  556. NTStatus = STCReadSTCRegister(
  557. ReaderExtension,
  558. ADR_ETULENGTH15,
  559. 1,
  560. ETU
  561. );
  562. if( NTStatus == STATUS_SUCCESS )
  563. {
  564. //
  565. // save all RFU bits
  566. //
  567. ETU[1] = (UCHAR) NewETU;
  568. ETU[0] = (UCHAR)(( ETU[0] & 0xF0 ) | ( NewETU >> 8 ));
  569. NTStatus = STCWriteSTCRegister(
  570. ReaderExtension,
  571. ADR_ETULENGTH15,
  572. 2,
  573. ETU
  574. );
  575. }
  576. }
  577. return(NTStatus);
  578. }
  579. NTSTATUS
  580. STCSetCGT(
  581. PREADER_EXTENSION ReaderExtension,
  582. ULONG NewCGT
  583. )
  584. {
  585. NTSTATUS NTStatus = STATUS_DATA_ERROR;
  586. UCHAR CGT[2];
  587. if( NewCGT < 0x01FF )
  588. {
  589. NTStatus = STCReadSTCRegister(
  590. ReaderExtension,
  591. ADR_CGT8,
  592. 2,
  593. CGT
  594. );
  595. if( NTStatus == STATUS_SUCCESS )
  596. {
  597. //
  598. // save all RFU bits
  599. //
  600. CGT[1] = ( UCHAR )NewCGT;
  601. CGT[0] = (UCHAR)(( CGT[0] & 0xFE ) | ( NewCGT >> 8 ));
  602. NTStatus = STCWriteSTCRegister(
  603. ReaderExtension,
  604. ADR_CGT8,
  605. 2,
  606. CGT
  607. );
  608. }
  609. }
  610. return(NTStatus);
  611. }
  612. NTSTATUS
  613. STCSetCWT(
  614. PREADER_EXTENSION ReaderExtension,
  615. ULONG NewCWT
  616. )
  617. {
  618. NTSTATUS NTStatus = STATUS_SUCCESS;
  619. UCHAR CWT[4];
  620. // little indians...
  621. CWT[0] = (( PUCHAR )&NewCWT )[3];
  622. CWT[1] = (( PUCHAR )&NewCWT )[2];
  623. CWT[2] = (( PUCHAR )&NewCWT )[1];
  624. CWT[3] = (( PUCHAR )&NewCWT )[0];
  625. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_CWT31, 4, CWT );
  626. return(NTStatus);
  627. }
  628. NTSTATUS
  629. STCSetBWT(
  630. PREADER_EXTENSION ReaderExtension,
  631. ULONG NewBWT
  632. )
  633. {
  634. NTSTATUS NTStatus = STATUS_SUCCESS;
  635. UCHAR BWT[4];
  636. // little indians...
  637. BWT[0] = (( PUCHAR )&NewBWT )[3];
  638. BWT[1] = (( PUCHAR )&NewBWT )[2];
  639. BWT[2] = (( PUCHAR )&NewBWT )[1];
  640. BWT[3] = (( PUCHAR )&NewBWT )[0];
  641. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_BWT31, 4, BWT );
  642. return(NTStatus);
  643. }
  644. NTSTATUS
  645. STCShortCircuitTest(
  646. PREADER_EXTENSION ReaderExtension,
  647. BOOLEAN *Detected
  648. )
  649. {
  650. NTSTATUS NTStatus = STATUS_SUCCESS;
  651. // set vcc to 1
  652. #if 0 // eva board
  653. UCHAR Value_VCC;
  654. UCHAR Value_SENSE;
  655. NTStatus = STCReadSTCRegister( ReaderExtension,ADR_SC_CONTROL,1,&Value_VCC );
  656. if( NTStatus == STATUS_SUCCESS )
  657. {
  658. Value_VCC |= M_VCE;
  659. NTStatus = STCWriteSTCRegister( ReaderExtension,ADR_SC_CONTROL,1,&Value_VCC );
  660. if( NTStatus == STATUS_SUCCESS )
  661. {
  662. // read sense int status
  663. NTStatus = STCReadSTCRegister( ReaderExtension,ADR_INT_STATUS,1,&Value_SENSE );
  664. if( Value_SENSE &= M_SENSE )
  665. {
  666. *Detected = TRUE;
  667. }
  668. else
  669. {
  670. *Detected = FALSE;
  671. }
  672. }
  673. Value_VCC &= ~M_VCE;
  674. NTStatus = STCWriteSTCRegister( ReaderExtension,ADR_SC_CONTROL,1,&Value_VCC);
  675. }
  676. #else
  677. *Detected = FALSE;
  678. #endif
  679. return(NTStatus);
  680. }
  681. NTSTATUS
  682. STCSetFDIV(
  683. PREADER_EXTENSION ReaderExtension,
  684. ULONG Factor
  685. )
  686. {
  687. NTSTATUS NTStatus = STATUS_SUCCESS;
  688. UCHAR DIV;
  689. NTStatus = STCReadSTCRegister( ReaderExtension, ADR_ETULENGTH15, 1, &DIV );
  690. if( NTStatus == STATUS_SUCCESS )
  691. {
  692. switch( Factor )
  693. {
  694. case 1:
  695. DIV &= ~M_DIV0;
  696. DIV &= ~M_DIV1;
  697. break;
  698. case 2:
  699. DIV |= M_DIV0;
  700. DIV &= ~M_DIV1;
  701. break;
  702. case 4 :
  703. DIV &= ~M_DIV0;
  704. DIV |= M_DIV1;
  705. break;
  706. case 8 :
  707. DIV |= M_DIV0;
  708. DIV |= M_DIV1;
  709. break;
  710. default :
  711. NTStatus = STATUS_DATA_ERROR;
  712. }
  713. if( NTStatus == STATUS_SUCCESS )
  714. {
  715. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_ETULENGTH15, 1, &DIV );
  716. }
  717. }
  718. return(NTStatus);
  719. }
  720. NTSTATUS
  721. STCInitUART(
  722. PREADER_EXTENSION ReaderExtension,
  723. BOOLEAN AutoLearn
  724. )
  725. {
  726. NTSTATUS NTStatus = STATUS_SUCCESS;
  727. UCHAR Value;
  728. Value = AutoLearn ? 0x6F : 0x66;
  729. NTStatus = STCWriteSTCRegister( ReaderExtension, ADR_UART_CONTROL, 1, &Value );
  730. return( NTStatus );
  731. }
  732. NTSTATUS
  733. STCGetFirmwareRevision(
  734. PREADER_EXTENSION ReaderExtension
  735. )
  736. {
  737. NTSTATUS NTStatus = STATUS_SUCCESS;
  738. UCHAR IOData[ STC_BUFFER_SIZE ] =
  739. {
  740. HOST_TO_STC1,
  741. PCB,
  742. 6,
  743. CLA_READ_FIRMWARE_REVISION,
  744. INS_READ_FIRMWARE_REVISION,
  745. 0x00,
  746. 0x00,
  747. 0x00,
  748. 0x02
  749. };
  750. IOData[ 9 ] = IFCalcLRC( IOData, 9 );
  751. NTStatus = IFWrite( ReaderExtension, IOData, 10 );
  752. if( NTStatus == STATUS_SUCCESS )
  753. {
  754. NTStatus = IFRead( ReaderExtension, IOData, 6 );
  755. if( NTStatus == STATUS_SUCCESS )
  756. {
  757. ReaderExtension->FirmwareMajor = IOData[ DATA_IDX ];
  758. ReaderExtension->FirmwareMinor = IOData[ DATA_IDX + 1 ];
  759. }
  760. }
  761. return( STATUS_SUCCESS );
  762. }
  763. //---------------------------------------- END OF FILE ----------------------------------------