8 #include "iso14443_typeA.h"
9 #include "iso14443_typeB.h"
10 #include "pcd_config.h"
12 const uint16_t fsdi_to_fsd
[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
14 /* pn512 timer setting for 7.2 Frame waiting time P25 */
15 static const uint8_t fwi_table
[] =
64 const uint16_t fsdi_to_fsd_convertion
[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
66 uint8_t tempIBlockBuf
[253]; /* set max block size */
69 /****************************************************************/
71 /****************************************************************/
72 int typeA_request_ats(struct picc_device
*picc
)
77 struct pn51x_request
*req
= picc
->request
;
80 pn51x_reg_set(TxModeReg
, TxCRCEn
); //TXCRC enable
81 pn51x_reg_set(RxModeReg
, RxCRCEn
); //RXCRC enable
82 pn51x_reg_clear(Status2Reg
, MFCrypto1On
); // disable crypto 1 unit add.....
84 /* 14443-4 P12 Request for answer to select */
86 req
->buf
[1] = picc
->pcd
->FSDI
<< 4 | picc
->CID
;
88 req
->bit_frame
= 0x00;
89 req
->command
= CMD_TRANSCEIVE
;
90 req
->direction
= TRANSCEIVE
;
93 picc_wait_for_req(req
);
95 picc
->ATS
[0] = req
->buf
[0];
97 ret
= req
->error_code
;
98 if((ret
) && (retry
>= 2)) {
103 // store ATS ,Figure 4 - Structure of the ATS (14443-4 P13)
104 if(req
->actual
!= picc
->ATS
[0]) {
109 picc
->states
= PICC_ACTIVATED
;
111 CLEAR_BIT(picc
->flags_TCL
, PCD_BLOCK_NUMBER
); // reset block number
112 SET_BIT(picc
->flags_TCL
, CID_PRESENT
); // CID supported by PICC by default
114 if(req
->actual
< 2) {
118 memcpy(&picc
->ATS
[1], &req
->buf
[1], req
->actual
- 1);
120 picc
->FSCI
= picc
->ATS
[1] & 0x0F; // T0: format byte, codes Y(1) and FSCI
121 if(picc
->FSCI
> 8) { /* 14443-4 P12 Table 1 - FSDI to FSD conversion */
125 i
= 1; /* Parse the ATS 14443-4 P14 */
126 if(picc
->ATS
[1] & 0x10) {
129 picc
->speed
= picc
->ATS
[i
];
130 if(picc
->speed
& 0x08) {
131 // b4 = 1 should be interpreted by the PCD as (b8 to b1) = (00000000)b (only ~106 kbit/s in both directions).
132 picc
->speed
= 0x00; // complaint to ISO14443-4: 2008
135 if(picc
->ATS
[1] & 0x20) {
138 picc
->FWI
= (picc
->ATS
[i
] & 0xF0) >> 4; // Set FWT
140 // Until the RFU value 15 is assigned by ISO/IEC, a PCD receiving FWI = 15 should interpret it as FWI = 4.
141 picc
->FWI
= 4; // complaint to ISO14443-4: 2008
143 picc
->SFGI
= picc
->ATS
[i
] & 0x0F;
144 if(picc
->SFGI
> 14) {
145 // Until the RFU value 15 is assigned by ISO/IEC, a PCD receiving SFGI = 15 should interpret it as SFGI = 0.
146 picc
->SFGI
= 0; // complaint to ISO14443-4: 2008
149 if(picc
->ATS
[1] & 0x40) {
152 if((picc
->ATS
[i
] & 0x02) == 0x00) {
153 // CID do not supported by the PICC
154 CLEAR_BIT(picc
->flags_TCL
, CID_PRESENT
);
165 /* Start-up Frame Guard time , 14443-3 P11 (Frame format and timing) */
166 static void typeA_sfg_delay(uint8_t delay
)
228 void typeA_set_timeout(struct picc_device
*picc
, uint8_t timeout
)
231 uint16_t reloadValue
;
232 uint8_t tempWTXM
= picc
->WTXM
;
234 preScaler
= MAKEWORD(fwi_table
[timeout
* 4], fwi_table
[timeout
* 4 + 1]);
235 reloadValue
= MAKEWORD(fwi_table
[timeout
* 4 + 2], fwi_table
[timeout
* 4 + 3]);
237 if(picc
->type
== PICC_TYPEB_TCL
) {
239 if(BITISSET(picc
->flags_TCL
, TYPEB_ATTRIB
)) {
246 if(BITISSET(picc
->flags_TCL
, WTX_REQUEST
)) {
251 preScaler
*= tempWTXM
;
252 if(preScaler
> 0x0FFF) {
257 reloadValue
*= tempWTXM
;
259 CLEAR_BIT(picc
->flags_TCL
, WTX_REQUEST
);
261 pn51x_reg_write(TModeReg
, (uint8_t)(preScaler
>>8) | 0x80);
262 pn51x_reg_write(TPrescalerReg
, (uint8_t)preScaler
);
263 pn51x_reg_write(TReloadVal_Hi
, (uint8_t)(reloadValue
>>8));
264 pn51x_reg_write(TReloadVal_Lo
, (uint8_t)reloadValue
);
265 pn51x_reg_write(CommIRqReg
,0x01); // Clear the TimerIrq bit
268 uint8_t typeA_speed_check(struct picc_device
*picc
)
273 picc
->pcd
->current_speed
= 0x80;
276 /* Divisor Receive */
277 if(picc
->speed
& 0x01) {
278 // DR = 2 supported, PCD to PICC, 1 etu = 64 / fc, bit rate supported is fc / 64 (~ 212 kbit/s)
281 if(picc
->speed
& 0x02) {
282 // DR = 4 supported, PCD to PICC, 1 etu = 32 / fc, bit rate supported is fc / 32 (~ 424 kbit/s)
285 if(picc
->speed
& 0x04) {
286 // DR = 8 supported, PCD to PICC, 1 etu = 16 / fc, bit rate supported is fc / 16 (~ 848 kbit/s)
293 if(picc
->speed
& 0x10) {
294 // DS = 2 supported, PICC to PCD, 1 etu = 64 / fc, bit rate supported is fc / 64 (~ 212 kbit/s)
297 if(picc
->speed
& 0x20) {
298 // DS = 4 supported, PICC to PCD, 1 etu = 32 / fc, bit rate supported is fc / 32 (~ 424 kbit/s)
301 if(picc
->speed
& 0x40) {
302 // DS = 8 supported, PICC to PCD, 1 etu = 16 / fc, bit rate supported is fc / 16 (~ 848 kbit/s)
306 if(picc
->speed
& 0x80) {
307 // Only the same D for both directions supported , if bit is set to 1
308 if(curByte
> priByte
) {
316 if(picc
->speed
& 0x08) {
317 // if b4 = 1, b8 to b1 should be interpreted as (00000000)b, accroding to ISO14443-4: 2008(typeA) and ISO14443-3: 2011(typeB)
318 curByte
= priByte
= 0x00;
321 curByte
= (curByte
<< 2) | priByte
; /* bxx(DS 0-3) xx(DR 0-3) */
326 void typeA_high_speed_config(struct picc_device
*picc
, uint8_t speedParam
, uint8_t typeB
)
328 picc
->pcd
->current_speed
= picc
->speed
& 0x80;
329 if((speedParam
& 0x03) == 0x03) {
330 // DR = 8 supported, PCD to PICC, 1 etu = 16 / fc, bit rate supported is fc / 16 (~ 848 kbit/s)
331 picc
->pcd
->current_speed
|= 0x03;
332 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_848TX
| typeB
); /* TX */
334 else if((speedParam
& 0x03) == 0x02) {
335 // DR = 4 supported, PCD to PICC, 1 etu = 32 / fc, bit rate supported is fc / 32 (~ 424 kbit/s)
336 picc
->pcd
->current_speed
|= 0x02;
337 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_424TX
| typeB
);
339 else if((speedParam
& 0x03) == 0x01) {
340 // DR = 2 supported, PCD to PICC, 1 etu = 64 / fc, bit rate supported is fc / 64 (~ 212 kbit/s)
341 picc
->pcd
->current_speed
|= 0x01;
342 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_212TX
| typeB
);
345 if((speedParam
& 0x0c) == 0x0c) {
346 // DS = 8 supported, PICC to PCD, 1 etu = 16 / fc, bit rate supported is fc / 16 (~ 848 kbit/s)
347 picc
->pcd
->current_speed
|= 0x18;
348 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_848RX
| typeB
); /* RX */
350 else if((speedParam
& 0x0c) == 0x08) {
351 // DS = 4 supported, PICC to PCD, 1 etu = 32 / fc, bit rate supported is fc / 32 (~ 424 kbit/s)
352 picc
->pcd
->current_speed
|= 0x10;
353 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_424RX
| typeB
);
355 else if((speedParam
& 0x0c) == 0x04) {
356 // DS = 2 supported, PICC to PCD, 1 etu = 64 / fc, bit rate supported is fc / 64 (~ 212 kbit/s)
357 picc
->pcd
->current_speed
|= 0x08;
358 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_212RX
| typeB
);
362 /* 14443-4 Protocol control byte field P22 */
363 void typeA_prologue_feild_load(struct picc_device
*picc
)
365 if((picc
->pcd
->PCB
& 0xC0) != 0xC0) {
366 // I-block or R-block ,not S-Block
367 // block number toggle
368 if(BITISSET(picc
->flags_TCL
, PCD_BLOCK_NUMBER
)) {
369 picc
->pcd
->PCB
|= 0x01;
372 picc
->pcd
->PCB
&= 0xFE;
375 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
376 picc
->pcd
->PCB
|= 0x08;
379 picc
->pcd
->PCB
&= 0xF7;
384 /****************************************************************/
386 /****************************************************************/
387 void typeA_pps_check_and_send(struct picc_device
*picc
)
391 struct pn51x_request
*req
= picc
->request
;
393 speedParam
= typeA_speed_check(picc
);
395 /* 14443-4 Protocol and Parameter Selection P16 */
396 req
->buf
[0] = 0xD0 | picc
->CID
;
398 req
->buf
[2] = speedParam
;
399 typeA_sfg_delay(picc
->SFGI
);
400 Delay1ms(5); /* liunote why ? */
402 req
->bit_frame
= 0x00;
403 req
->command
= CMD_TRANSCEIVE
;
404 req
->direction
= TRANSCEIVE
;
406 typeA_set_timeout(picc
, picc
->FWI
); /* set timeout according FWI */
407 picc_wait_for_req(req
); /* Figure 19 - Frame waiting time ,14443-4 P25 */
409 if(!req
->error_code
) {
410 memcpy(RecBuf
, req
->buf
, req
->actual
);
411 if((RecBuf
[0] & 0xF0) == 0xD0) {
412 // return PPSS, PPS successful , (if successful then response the start byte of pps.)
413 typeA_high_speed_config(picc
, speedParam
, TYPEA_106TX
);
419 int typeA_select_(struct picc_device
*picc
, uint8_t blockPCB
)
422 struct pn51x_request
*req
= picc
->request
;
424 picc
->pcd
->PCB
= blockPCB
;
425 typeA_prologue_feild_load(picc
);
427 tempFWI
= (tempFWI
> 0x06) ? 0x06 : tempFWI
;
429 req
->buf
[0] = picc
->pcd
->PCB
;
430 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
431 req
->buf
[1] = picc
->CID
;
437 req
->bit_frame
= 0x00;
438 req
->command
= CMD_TRANSCEIVE
;
439 req
->direction
= TRANSCEIVE
;
441 typeA_set_timeout(picc
, tempFWI
);
442 picc_wait_for_req(req
);
444 pr_debug("%s: ret = %d\n", __func__
, req
->error_code
);
446 return(req
->error_code
);
449 int typeA_deselect_request(struct picc_device
*picc
)
452 struct pn51x_request
*req
= picc
->request
;
454 if(picc
->states
== PICC_ACTIVATED
) {
455 picc
->pcd
->PCB
= 0xC2; // S-block, DESELECT
456 typeA_prologue_feild_load(picc
);
458 req
->buf
[0] = picc
->pcd
->PCB
;
459 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
460 req
->buf
[1] = picc
->CID
;
466 req
->bit_frame
= 0x00;
467 req
->command
= CMD_TRANSCEIVE
;
468 req
->direction
= TRANSCEIVE
;
471 picc_wait_for_req(req
);
473 if(picc
->states
!= PICC_POWEROFF
) {
474 picc
->states
= PICC_IDLE
;
476 if(picc
->type
== PICC_TYPEA_TCL
) {
477 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_106TX
);
478 pcd_config_iso14443_card(CONFIGNOTHING
, TYPEA_106RX
);
480 else if(picc
->type
== PICC_TYPEB_TCL
) {
481 pcd_config_iso14443_card(CONFIGNOTHING
,TYPEB_106TX
);
482 pcd_config_iso14443_card(CONFIGNOTHING
,TYPEB_106RX
);
490 R-block used to convey positive or negative acknowledgements. An R-block never contains an INF field. The
491 acknowledgement relates to the last received block.
493 static int typeA_rblock_command(struct picc_device
*picc
, uint8_t blockPCB
, uint8_t *recBuf
, uint32_t *recLen
)
496 struct pn51x_request
*req
= picc
->request
;
498 picc
->pcd
->PCB
= blockPCB
;
499 typeA_prologue_feild_load(picc
);
501 req
->buf
[0] = picc
->pcd
->PCB
;
502 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
503 req
->buf
[1] = picc
->CID
;
509 req
->bit_frame
= 0x00;
510 req
->command
= CMD_TRANSCEIVE
;
511 req
->direction
= TRANSCEIVE
;
513 typeA_set_timeout(picc
, picc
->FWI
);
514 picc_wait_for_req(req
);
515 memcpy(recBuf
, req
->buf
, req
->actual
);
516 *recLen
= req
->actual
;
521 static int typeA_data_send_error_check(struct picc_device
*picc
, uint8_t *senBuf
, uint32_t senLen
, uint8_t *recBuf
, uint32_t *recLen
)
523 uint8_t timeoutRetry
= 0;
524 uint8_t frameRetry
= 0;
525 uint8_t ackRetry
= 0;
530 struct pn51x_request
*req
= picc
->request
;
534 /* send block according picc PCB */
536 picc
->pcd
->PCB
= picc
->PCB
;
537 typeA_sfg_delay(picc
->SFGI
);
538 typeA_prologue_feild_load(picc
);
540 req
->buf
[0] = picc
->pcd
->PCB
;
541 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
542 req
->buf
[1] = picc
->CID
;
543 memcpy(req
->buf
+2, senBuf
, senLen
);
544 req
->length
= 2+senLen
;
547 memcpy(req
->buf
+ 1, senBuf
, senLen
);
548 req
->length
= 1 + senLen
;
550 req
->bit_frame
= 0x00;
551 req
->command
= CMD_TRANSCEIVE
;
552 req
->direction
= TRANSCEIVE
;
554 typeA_set_timeout(picc
, picc
->FWI
);
555 picc_wait_for_req(req
);
556 memcpy(recBuf
, req
->buf
, req
->actual
);
557 *recLen
= req
->actual
;
558 ret
= req
->error_code
;
561 if(ret
== -ERROR_NOTAG
) { //Time Out
562 CLEAR_BIT(picc
->flags_TCL
, WTX_REQ_BEFORE
);
563 /* Figure 22 -Chaining ,14443-4 P28 */
564 if(BITISSET(picc
->flags_TCL
, PICC_CHAINING
)) {
566 ret
= -PICC_ERRORCODE_MUTE
;
569 ret
= typeA_rblock_command(picc
, 0xA2, recBuf
, recLen
); // R-Block: ACK
573 if(timeoutRetry
== 2) {
574 ret
= -PICC_ERRORCODE_MUTE
;
577 ret
= typeA_rblock_command(picc
, 0xB2, recBuf
, recLen
); // R-Block: NAK
582 CLEAR_BIT(picc
->flags_TCL
, WTX_REQ_BEFORE
);
583 if((recBuf
[0] & 0xC0) == 0xC0) { /* S-BLOCK */
585 if((recBuf
[0] & 0x30) == 0x30) {
587 if(recBuf
[0] & 0x08) {
589 if(BITISCLEAR(picc
->flags_TCL
, CID_PRESENT
)) { /* if picc not support cid */
590 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
594 if(recBuf
[0] & 0x04) { /* NAD don't support */
595 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
599 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
600 picc
->WTXM
= recBuf
[2];
604 picc
->WTXM
= recBuf
[1];
606 if((picc
->WTXM
== 0) || (picc
->WTXM
> 59)) {
607 // WTXM must be code in the range from 1 to 59, or it will be treat as a protocol error. ISO/IEC 14443-4:2008
608 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
611 /* ack WTXM with S-block 14443-4 P25
612 The PCD shall acknowledge by sending an S(WTX) response containing also a 1 byte long INF field that consists
613 of two parts (see Figure 21) and contains the same WTXM as received in the request:
615 picc
->pcd
->PCB
= 0xF2;
616 typeA_sfg_delay(picc
->SFGI
);
617 typeA_prologue_feild_load(picc
);
619 req
->buf
[0] = picc
->pcd
->PCB
;
620 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
621 req
->buf
[1] = picc
->CID
;
622 req
->buf
[2] = picc
->WTXM
;
626 req
->buf
[1] = picc
->WTXM
;
630 req
->bit_frame
= 0x00;
631 req
->command
= CMD_TRANSCEIVE
;
632 req
->direction
= TRANSCEIVE
;
634 typeA_set_timeout(picc
, picc
->FWI
);
635 picc_wait_for_req(req
);
636 memcpy(recBuf
, req
->buf
, req
->actual
);
637 *recLen
= req
->actual
;
638 ret
= req
->error_code
;
639 SET_BIT(picc
->flags_TCL
, WTX_REQUEST
); // the time FWTtemp starts after the PCD has sent the S(WTX) response
640 SET_BIT(picc
->flags_TCL
, WTX_REQ_BEFORE
);
643 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
647 else if((recBuf
[0] & 0xC0) == 0x80) { /* R-BLOCK b101X-X01X */
649 if(recBuf
[0] & 0x14) {
650 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
); //PICC Never send a R(NAK) and Never used NAD
653 if((recBuf
[0] & 0x20) == 0x00) {
654 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
); // R(ACK) bit 6 must set to 1
657 if(recBuf
[0] & 0x08) {
658 if(BITISCLEAR(picc
->flags_TCL
, CID_PRESENT
)) { /* receiver pcd having CID, but pcc don't set */
659 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
664 if((picc
->PCB
^ recBuf
[0]) & 0x01) {/* R-block block number must equal I block block number */
666 // the block number of R-block do not equal the block number of the last I-block
669 if(resendCount
== 2) {
670 ret
= -SLOTERROR_TCL_3RETRANSMIT_FAIL
;
673 picc
->PCB
&= 0x1F; /* back to I block */
674 for(i
= 0; i
< senLen
; i
++) {
675 senBuf
[i
] = tempIBlockBuf
[i
];
678 //re-transmit last I-block
683 if(BITISSET(picc
->flags_TCL
, PCD_CHAINING
)) {
684 // PCD Chaining continue
685 TOGGLE_BIT(picc
->flags_TCL
, PCD_BLOCK_NUMBER
);
688 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
694 else if((recBuf
[0] & 0xC0) == 0x00) {
696 if(recBuf
[0] & 0x08) {
697 if(BITISCLEAR(picc
->flags_TCL
, CID_PRESENT
)) {
698 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
703 if((recBuf
[0] & 0x02) == 0x00) { /* must set 1 ,14443-4 P23 Figure 15 - Coding of I-block PCB */
704 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
708 if(recBuf
[0] & 0x04) { // Not used NAD
709 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
713 if(BITISSET(picc
->flags_TCL
, PCD_CHAINING
)) { /* last sent block should not be a chain block before receive a I block */
714 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
718 if((picc
->PCB
^ recBuf
[0]) & 0x01) { //Block number error
719 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
723 TOGGLE_BIT(picc
->flags_TCL
, PCD_BLOCK_NUMBER
);
725 if(recBuf
[0] & 0x10) { /* will continue for chaining I block */
726 SET_BIT(picc
->flags_TCL
, PICC_CHAINING
);
729 CLEAR_BIT(picc
->flags_TCL
, PICC_CHAINING
);
735 ret
= (-SLOTERROR_TCL_BLOCK_INVALID
);
739 else if(ret
== -ERROR_PROTOCOL
) {
740 if(BITISSET(picc
->flags_TCL
, WTX_REQ_BEFORE
)) {
741 SET_BIT(picc
->flags_TCL
, WTX_REQUEST
);
742 CLEAR_BIT(picc
->flags_TCL
, WTX_REQ_BEFORE
);
745 if(BITISSET(picc
->flags_TCL
, PICC_CHAINING
)) {
747 ret
= -SLOTERROR_T1_3RETRY_FAIL_RESYNCH_FAIL
;
750 typeA_sfg_delay(picc
->SFGI
);
751 ret
= typeA_rblock_command(picc
, 0xA2,recBuf
,recLen
); /* send R-block ACK , then get recv buf to recbuf */
755 if(frameRetry
== 2) {
756 ret
= -SLOTERROR_T1_3RETRY_FAIL_RESYNCH_FAIL
;
759 typeA_sfg_delay(picc
->SFGI
);
760 ret
= typeA_rblock_command(picc
, 0xB2,recBuf
,recLen
); /* send R-block NAK , then get recv buf to recbuf */
765 CLEAR_BIT(picc
->flags_TCL
, WTX_REQ_BEFORE
);
766 ret
= -PICC_ERRORCODE_MUTE
;
776 int typeA_standard_apdu_handler(struct picc_device
*picc
, uint8_t *cmdBuf
, uint32_t senLen
, uint8_t *recBuf
, uint32_t *recLen
, uint8_t *level
)
785 uint32_t ChainLastLen
= 0;
786 uint32_t LastCCIDRemainLen
= 0x00;
794 for(i
= 0; i
< ChainLastLen
; i
++) { /* ChainLastLen = 0 liunote why ? */
795 recBuf
[i
] = tempIBlockBuf
[i
];
797 tempRecLen
= ChainLastLen
;
798 *recLen
= ChainLastLen
;
801 else if(((*level
== 0x03) || (*level
== 0x02)) && (LastCCIDRemainLen
!= 0)) {
804 pSenAddr
[i
+ LastCCIDRemainLen
] = pSenAddr
[i
];
806 for(i
=0; i
< LastCCIDRemainLen
; i
++) {
807 pSenAddr
[i
] = tempIBlockBuf
[i
];
809 senLen
+= LastCCIDRemainLen
;
810 LastCCIDRemainLen
= 0;
813 while(senLen
) { /* start send */
814 CLEAR_BIT(picc
->flags_TCL
, PICC_CHAINING
);
815 if((senLen
<= picc
->FSC
) && ((*level
== 0x02) || (*level
== 0x00))) {
816 CLEAR_BIT(picc
->flags_TCL
, PCD_CHAINING
); /* don't need chaining ,because send lenght litter than FSC */
817 picc
->PCB
= 0x02; // I-block, no chaining
818 if(BITISSET(picc
->flags_TCL
, PCD_BLOCK_NUMBER
)) {
821 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
825 ret
= typeA_data_send_error_check(picc
, pSenAddr
, tempSenLen
, pRecAddr
, &tempRecLen
);
830 /* 14443-4 P21 get the Information field */
831 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
837 tempRecLen
-= offset
;
838 for(i
= 0; i
< tempRecLen
; i
++) {
839 pRecAddr
[i
] = pRecAddr
[i
+ offset
];
842 if(tempRecLen
== 1) { /* only 1 byte Information field , liunote ,why set as below ? */
848 *recLen
= tempRecLen
;
852 CLEAR_BIT(picc
->flags_TCL
, PICC_CHAINING
);
857 SET_BIT(picc
->flags_TCL
, PCD_CHAINING
);
859 if(BITISSET(picc
->flags_TCL
, PCD_BLOCK_NUMBER
)) {
862 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
865 ret
= typeA_data_send_error_check(picc
, pSenAddr
, picc
->FSC
, pRecAddr
, &tempRecLen
);
866 CLEAR_BIT(picc
->flags_TCL
, PCD_CHAINING
);
869 pSenAddr
+= picc
->FSC
;
870 if(((*level
== 0x01) || (*level
== 0x03)) && (senLen
< picc
->FSC
)) {
871 LastCCIDRemainLen
= senLen
; /* need send at next, while don't send ? liunote (typeA_data_send_error_check will continue chaining ) */
872 for(i
= 0; i
< LastCCIDRemainLen
; i
++) {
873 tempIBlockBuf
[i
] = pSenAddr
[i
];
878 CLEAR_BIT(picc
->flags_TCL
, PICC_CHAINING
);
884 CLEAR_BIT(picc
->flags_TCL
, PICC_CHAINING
);
889 // PICC Chaining // only recv ?
890 while(BITISSET(picc
->flags_TCL
, PICC_CHAINING
)) {
892 if(BITISSET(picc
->flags_TCL
, PCD_BLOCK_NUMBER
)) {
895 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
898 pRecAddr
+= tempRecLen
;
899 ret
= typeA_data_send_error_check(picc
, pSenAddr
, 0, pRecAddr
, &tempRecLen
);
902 if(BITISSET(picc
->flags_TCL
, CID_PRESENT
)) {
908 tempRecLen
-= offset
;
909 for(i
= 0; i
< tempRecLen
; i
++) { /* only get the inf data*/
910 pRecAddr
[i
] = pRecAddr
[i
+ offset
];
912 *recLen
+= tempRecLen
;
914 if(*recLen
> APDURECLENTHREHOLD
) {
915 if(*level
== 0x10) { //Continue Chaining
919 *level
= 0x01; //Chaining Beginning
921 ChainLastLen
= (uint8_t)(*recLen
- APDURECLENTHREHOLD
);
922 for(i
= 0; i
< ChainLastLen
; i
++) {
923 tempIBlockBuf
[i
] = recBuf
[i
+ APDURECLENTHREHOLD
];
925 *recLen
= APDURECLENTHREHOLD
;
926 picc
->pcd
->piccPoll
= FALSE
;
927 picc
->pcd
->poll_interval
= 1000; // 1000ms, start another poll
932 CLEAR_BIT(picc
->flags_TCL
, PICC_CHAINING
);
943 picc
->pcd
->piccPoll
= FALSE
;
944 picc
->pcd
->poll_interval
= 1000; // 1000ms, start another poll
947 picc
->pcd
->piccPoll
= TRUE
;
951 CLEAR_BIT(picc
->flags_TCL
, PCD_CHAINING
);
952 CLEAR_BIT(picc
->flags_TCL
, PICC_CHAINING
);