fix(nfc): separate ATS transmit and receive
This commit is contained in:
@@ -45,19 +45,27 @@ static volatile int g_nfc_irq_trigger = 0;
|
||||
|
||||
#if (NFC_WORK_MODE == NFC_WORK_MODE_CARD_EMULATION)
|
||||
#define NFC_CARD_FRAME_MAX 64
|
||||
#define NFC_CARD_SESSION_POLLS 200
|
||||
#define NFC_CARD_TX_POLLS 20
|
||||
#define NFC_CARD_RX_POLLS 200
|
||||
#define NFC_CARD_SESSION_POLL_MS 1
|
||||
|
||||
#define NFC_IRQ_TX 0x40
|
||||
#define NFC_IRQ_RX 0x20
|
||||
#define NFC_IRQ_ERR 0x02
|
||||
|
||||
static void nfc_card_emulation_log_status(const char *reason)
|
||||
{
|
||||
printf("NFC card emulation %s: cmd=%02X irq=%02X err=%02X status1=%02X status2=%02X fifo=%02X\r\n",
|
||||
printf("NFC card emulation %s: cmd=%02X irq=%02X err=%02X status1=%02X status2=%02X fifo=%02X txm=%02X rxm=%02X framing=%02X\r\n",
|
||||
reason,
|
||||
DP1312EA_ReadRawRC(CommandReg),
|
||||
DP1312EA_ReadRawRC(ComIrqReg),
|
||||
DP1312EA_ReadRawRC(ErrorReg),
|
||||
DP1312EA_ReadRawRC(Status1Reg),
|
||||
DP1312EA_ReadRawRC(Status2Reg),
|
||||
DP1312EA_ReadRawRC(FIFOLevelReg));
|
||||
DP1312EA_ReadRawRC(FIFOLevelReg),
|
||||
DP1312EA_ReadRawRC(TxModeReg),
|
||||
DP1312EA_ReadRawRC(RxModeReg),
|
||||
DP1312EA_ReadRawRC(BitFramingReg));
|
||||
}
|
||||
|
||||
static u8 nfc_card_emulation_read_frame(u8 *frame, u8 capacity)
|
||||
@@ -94,16 +102,46 @@ static void nfc_card_emulation_log_frame(const char *prefix,
|
||||
printf("\r\n");
|
||||
}
|
||||
|
||||
static void nfc_card_emulation_send_frame(const u8 *frame, u8 length)
|
||||
static u8 nfc_card_emulation_send_frame(const u8 *frame, u8 length)
|
||||
{
|
||||
u16 poll_count;
|
||||
u8 irq;
|
||||
|
||||
/* Stop the AutoColl-created Transceive before starting a clean TX. */
|
||||
DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE);
|
||||
DP1312EA_WriteRawRC(ComIrqReg, 0x7F);
|
||||
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
|
||||
DP1312EA_WriteFIFO((u8 *)frame, length);
|
||||
|
||||
/* AutoColl leaves Transceive active and waiting for StartSend. */
|
||||
DP1312EA_SetBitMask(TxModeReg, 0x80);
|
||||
DP1312EA_SetBitMask(RxModeReg, 0x80);
|
||||
DP1312EA_WriteRawRC(BitFramingReg, 0x80);
|
||||
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
|
||||
DP1312EA_WriteFIFO((u8 *)frame, length);
|
||||
DP1312EA_WriteRawRC(CommandReg, DP1312EA_TRANSMIT);
|
||||
DP1312EA_SetBitMask(BitFramingReg, 0x80);
|
||||
|
||||
for (poll_count = 0; poll_count < NFC_CARD_TX_POLLS; poll_count++) {
|
||||
irq = DP1312EA_ReadRawRC(ComIrqReg);
|
||||
if ((irq & NFC_IRQ_TX) != 0) {
|
||||
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
|
||||
return 1;
|
||||
}
|
||||
if ((irq & NFC_IRQ_ERR) != 0) {
|
||||
break;
|
||||
}
|
||||
ql_rtos_task_sleep_ms(NFC_CARD_SESSION_POLL_MS);
|
||||
}
|
||||
|
||||
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
|
||||
nfc_card_emulation_log_status("ATS transmit failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nfc_card_emulation_start_receive(void)
|
||||
{
|
||||
DP1312EA_WriteRawRC(CommandReg, DP1312EA_IDLE);
|
||||
DP1312EA_WriteRawRC(ComIrqReg, 0x7F);
|
||||
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
|
||||
DP1312EA_WriteRawRC(BitFramingReg, 0x00);
|
||||
DP1312EA_WriteRawRC(CommandReg, DP1312EA_RECEIVE);
|
||||
}
|
||||
|
||||
static void nfc_card_emulation_configure_iso_dep(void)
|
||||
@@ -166,21 +204,28 @@ static void nfc_card_emulation_task(void)
|
||||
nfc_card_emulation_log_frame("activation RX", frame, frame_len);
|
||||
|
||||
if (frame_len == 2 && frame[0] == 0xE0) {
|
||||
nfc_card_emulation_send_frame(ats, sizeof(ats));
|
||||
nfc_card_emulation_log_frame("ATS TX", ats, sizeof(ats));
|
||||
if (!nfc_card_emulation_send_frame(ats, sizeof(ats))) {
|
||||
nfc_card_emulation_log_status("session complete");
|
||||
nfc_card_emulation_start();
|
||||
last_command = DP1312EA_AUTOCOLL;
|
||||
ql_rtos_task_sleep_ms(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
nfc_card_emulation_log_frame("ATS TX complete", ats,
|
||||
sizeof(ats));
|
||||
nfc_card_emulation_start_receive();
|
||||
for (poll_count = 0;
|
||||
poll_count < NFC_CARD_SESSION_POLLS;
|
||||
poll_count < NFC_CARD_RX_POLLS;
|
||||
poll_count++) {
|
||||
u8 irq = DP1312EA_ReadRawRC(ComIrqReg);
|
||||
u8 error = DP1312EA_ReadRawRC(ErrorReg);
|
||||
|
||||
if (error != 0) {
|
||||
nfc_card_emulation_log_status("ISO-DEP error");
|
||||
if ((irq & NFC_IRQ_ERR) != 0) {
|
||||
nfc_card_emulation_log_status("ISO-DEP receive error");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((irq & 0x20) != 0 &&
|
||||
if ((irq & NFC_IRQ_RX) != 0 &&
|
||||
(DP1312EA_ReadRawRC(FIFOLevelReg) & 0x7F) != 0) {
|
||||
frame_len = nfc_card_emulation_read_frame(
|
||||
frame, sizeof(frame));
|
||||
@@ -191,6 +236,10 @@ static void nfc_card_emulation_task(void)
|
||||
|
||||
ql_rtos_task_sleep_ms(NFC_CARD_SESSION_POLL_MS);
|
||||
}
|
||||
|
||||
if (poll_count == NFC_CARD_RX_POLLS) {
|
||||
nfc_card_emulation_log_status("ISO-DEP receive timeout");
|
||||
}
|
||||
} else {
|
||||
printf("NFC activation frame is not RATS\r\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user