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)
|
#if (NFC_WORK_MODE == NFC_WORK_MODE_CARD_EMULATION)
|
||||||
#define NFC_CARD_FRAME_MAX 64
|
#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_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)
|
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,
|
reason,
|
||||||
DP1312EA_ReadRawRC(CommandReg),
|
DP1312EA_ReadRawRC(CommandReg),
|
||||||
DP1312EA_ReadRawRC(ComIrqReg),
|
DP1312EA_ReadRawRC(ComIrqReg),
|
||||||
DP1312EA_ReadRawRC(ErrorReg),
|
DP1312EA_ReadRawRC(ErrorReg),
|
||||||
DP1312EA_ReadRawRC(Status1Reg),
|
DP1312EA_ReadRawRC(Status1Reg),
|
||||||
DP1312EA_ReadRawRC(Status2Reg),
|
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)
|
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");
|
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_WriteRawRC(ComIrqReg, 0x7F);
|
||||||
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
|
DP1312EA_SetBitMask(FIFOLevelReg, 0x80);
|
||||||
DP1312EA_WriteFIFO((u8 *)frame, length);
|
|
||||||
|
|
||||||
/* AutoColl leaves Transceive active and waiting for StartSend. */
|
|
||||||
DP1312EA_SetBitMask(TxModeReg, 0x80);
|
DP1312EA_SetBitMask(TxModeReg, 0x80);
|
||||||
DP1312EA_SetBitMask(RxModeReg, 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)
|
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);
|
nfc_card_emulation_log_frame("activation RX", frame, frame_len);
|
||||||
|
|
||||||
if (frame_len == 2 && frame[0] == 0xE0) {
|
if (frame_len == 2 && frame[0] == 0xE0) {
|
||||||
nfc_card_emulation_send_frame(ats, sizeof(ats));
|
if (!nfc_card_emulation_send_frame(ats, sizeof(ats))) {
|
||||||
nfc_card_emulation_log_frame("ATS TX", 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;
|
for (poll_count = 0;
|
||||||
poll_count < NFC_CARD_SESSION_POLLS;
|
poll_count < NFC_CARD_RX_POLLS;
|
||||||
poll_count++) {
|
poll_count++) {
|
||||||
u8 irq = DP1312EA_ReadRawRC(ComIrqReg);
|
u8 irq = DP1312EA_ReadRawRC(ComIrqReg);
|
||||||
u8 error = DP1312EA_ReadRawRC(ErrorReg);
|
|
||||||
|
|
||||||
if (error != 0) {
|
if ((irq & NFC_IRQ_ERR) != 0) {
|
||||||
nfc_card_emulation_log_status("ISO-DEP error");
|
nfc_card_emulation_log_status("ISO-DEP receive error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((irq & 0x20) != 0 &&
|
if ((irq & NFC_IRQ_RX) != 0 &&
|
||||||
(DP1312EA_ReadRawRC(FIFOLevelReg) & 0x7F) != 0) {
|
(DP1312EA_ReadRawRC(FIFOLevelReg) & 0x7F) != 0) {
|
||||||
frame_len = nfc_card_emulation_read_frame(
|
frame_len = nfc_card_emulation_read_frame(
|
||||||
frame, sizeof(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);
|
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 {
|
} else {
|
||||||
printf("NFC activation frame is not RATS\r\n");
|
printf("NFC activation frame is not RATS\r\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user