From e3511c5350483c8cc94c5900476acfb3d8719b59 Mon Sep 17 00:00:00 2001 From: dxl <64101226@qq.com> Date: Sat, 1 Aug 2026 16:15:35 +0800 Subject: [PATCH] Used HAL layer in appmain.c and cmd added. in cmd.c and add some code for test CEP in em4x50.c(Do not timeout--) in em4x70.c in emvsim.c in epa.c in felica.c in felicasim.c in felicasim.c in hfops.c in hfsnoop.c in hitag2.c in hitag_common.c(Cross-platform implementation is incomplete.) in hitagS.c in hitagu.c in i2c.c(Incomplete, continue to abstract.) in i2c_direct.c in iclass.c in iso14443a.c(Sniff no finish yet) in iso14443b.c and fixed bug for st25 in iso15693.c in legicrf.c in legicrfsim.c in lfadc.c(lf_count_edge_periods_ex() improved) in lfops.c(TI tag no finish yet) in lfsampling.c in lfzx.c in mifarecmd.c in mifaredesfire.c in mifaresim.c in mifaresniff_disabled.c in mifareutil.c in pcf7931.c in sam_xxx in secc & seos in start.c in thinfilm.c in utils --- armsrc/Standalone/dankarmulti.c | 5 +- armsrc/Standalone/hf_14asniff.c | 2 +- armsrc/Standalone/hf_14bsniff.c | 2 +- armsrc/Standalone/hf_15sim.c | 5 +- armsrc/Standalone/hf_15sniff.c | 5 +- armsrc/Standalone/hf_aveful.c | 5 +- armsrc/Standalone/hf_bog.c | 25 +- armsrc/Standalone/hf_cardhopper.c | 13 +- armsrc/Standalone/hf_colin.c | 5 +- armsrc/Standalone/hf_craftbyte.c | 5 +- armsrc/Standalone/hf_doegox_auth0.c | 25 +- armsrc/Standalone/hf_doegox_commit.c | 25 +- armsrc/Standalone/hf_emvpng.c | 5 +- armsrc/Standalone/hf_iceclass.c | 5 +- armsrc/Standalone/hf_legic.c | 5 +- armsrc/Standalone/hf_legicsim.c | 5 +- armsrc/Standalone/hf_mattyrun.c | 5 +- armsrc/Standalone/hf_mfcsim.c | 5 +- armsrc/Standalone/hf_msdsal.c | 5 +- armsrc/Standalone/hf_reblay.c | 5 +- armsrc/Standalone/hf_st25_tearoff.c | 7 +- armsrc/Standalone/hf_tcprst.c | 5 +- armsrc/Standalone/hf_tmudford.c | 5 +- armsrc/Standalone/hf_unisniff.c | 2 +- armsrc/Standalone/hf_young.c | 5 +- armsrc/Standalone/lf_em4100emul.c | 5 +- armsrc/Standalone/lf_em4100rswb.c | 5 +- armsrc/Standalone/lf_em4100rsww.c | 5 +- armsrc/Standalone/lf_em4100rwc.c | 5 +- armsrc/Standalone/lf_hidbrute.c | 5 +- armsrc/Standalone/lf_hidfcbrute.c | 6 +- armsrc/Standalone/lf_icehid.c | 5 +- armsrc/Standalone/lf_multihid.c | 5 +- armsrc/Standalone/lf_nedap_sim.c | 3 +- armsrc/Standalone/lf_nexid.c | 5 +- armsrc/Standalone/lf_prox2brute.c | 3 +- armsrc/Standalone/lf_proxbrute.c | 5 +- armsrc/Standalone/lf_samyrun.c | 4 +- armsrc/Standalone/lf_skeleton.c | 3 +- armsrc/Standalone/lf_tharexde.c | 10 +- armsrc/appmain.c | 521 ++++++++++++++++++----- armsrc/appmain.h | 13 - armsrc/cmd.c | 18 +- armsrc/em4x50.c | 197 ++++----- armsrc/em4x70.c | 69 ++- armsrc/emvsim.c | 5 +- armsrc/epa.c | 5 +- armsrc/felica.c | 47 ++- armsrc/felicasim.c | 9 +- armsrc/fpgaloader.h | 182 -------- armsrc/hfops.c | 20 +- armsrc/hfsnoop.c | 42 +- armsrc/hitag2.c | 37 +- armsrc/hitagS.c | 23 +- armsrc/hitag_common.c | 608 +++++++++++++++------------ armsrc/hitag_common.h | 19 +- armsrc/hitagu.c | 29 +- armsrc/i2c.c | 69 ++- armsrc/i2c.h | 2 +- armsrc/i2c_direct.c | 5 +- armsrc/iclass.c | 5 +- armsrc/iso14443a.c | 128 +++--- armsrc/iso14443b.c | 137 +++--- armsrc/iso15693.c | 110 ++--- armsrc/legicrf.c | 24 +- armsrc/legicrfsim.c | 22 +- armsrc/lfadc.c | 187 ++++---- armsrc/lfadc.h | 29 +- armsrc/lfops.c | 73 ++-- armsrc/lfsampling.c | 43 +- armsrc/lfzx.c | 13 +- armsrc/mifarecmd.c | 9 +- armsrc/mifaredesfire.c | 5 +- armsrc/mifaresim.c | 4 +- armsrc/mifaresniff_disabled.c | 20 +- armsrc/mifareutil.c | 2 +- armsrc/pcf7931.c | 15 +- armsrc/sam_common.c | 2 +- armsrc/sam_picopass.c | 5 +- armsrc/sam_sc.c | 2 +- armsrc/sam_seos.c | 5 +- armsrc/secc.c | 9 +- armsrc/seos.c | 3 +- armsrc/start.c | 25 +- armsrc/thinfilm.c | 59 ++- armsrc/util.c | 99 +---- armsrc/util.h | 7 +- include/hitag.h | 2 +- 88 files changed, 1770 insertions(+), 1454 deletions(-) delete mode 100644 armsrc/fpgaloader.h diff --git a/armsrc/Standalone/dankarmulti.c b/armsrc/Standalone/dankarmulti.c index f127a1b74..66c43c9e4 100644 --- a/armsrc/Standalone/dankarmulti.c +++ b/armsrc/Standalone/dankarmulti.c @@ -19,8 +19,9 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_apis.h" +#include "fpga_loader.h" +#include "ticks_apis.h" #include "util.h" #include "dbprint.h" diff --git a/armsrc/Standalone/hf_14asniff.c b/armsrc/Standalone/hf_14asniff.c index dc0c0905c..15c85cfd8 100644 --- a/armsrc/Standalone/hf_14asniff.c +++ b/armsrc/Standalone/hf_14asniff.c @@ -73,7 +73,7 @@ #include "spiffs.h" #include "appmain.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "BigBuf.h" #define HF_14ASNIFF_LOGFILE "hf_14asniff.trace" diff --git a/armsrc/Standalone/hf_14bsniff.c b/armsrc/Standalone/hf_14bsniff.c index d3adaeb23..e7111eccc 100644 --- a/armsrc/Standalone/hf_14bsniff.c +++ b/armsrc/Standalone/hf_14bsniff.c @@ -46,7 +46,7 @@ #include "spiffs.h" #include "appmain.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "BigBuf.h" #define HF_14BSNIFF_LOGFILE "hf_14bsniff.trace" diff --git a/armsrc/Standalone/hf_15sim.c b/armsrc/Standalone/hf_15sim.c index eb5736ca5..fb72941f0 100644 --- a/armsrc/Standalone/hf_15sim.c +++ b/armsrc/Standalone/hf_15sim.c @@ -21,7 +21,8 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "iso15693.h" #include "iso15.h" #include "protocols.h" @@ -30,7 +31,7 @@ #include "spiffs.h" #include "appmain.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "BigBuf.h" #include "crc16.h" diff --git a/armsrc/Standalone/hf_15sniff.c b/armsrc/Standalone/hf_15sniff.c index ad1d3f8b6..04c031c42 100644 --- a/armsrc/Standalone/hf_15sniff.c +++ b/armsrc/Standalone/hf_15sniff.c @@ -67,14 +67,15 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "iso15693.h" #include "iso15.h" #include "util.h" #include "spiffs.h" #include "appmain.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "BigBuf.h" diff --git a/armsrc/Standalone/hf_aveful.c b/armsrc/Standalone/hf_aveful.c index 695ea9254..ea9032dfa 100644 --- a/armsrc/Standalone/hf_aveful.c +++ b/armsrc/Standalone/hf_aveful.c @@ -33,11 +33,12 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" // SpinDelay +#include "ticks_apis.h" // SpinDelay #include "protocols.h" // MIFARE_ULEV1_VERSION, MIFARE_ULEV1_READSIG, MIFARE_ULEV1_READ_CNT, MIFARE_ULEV1_CHECKTEAR #include // memcmp #include "mifareutil.h" diff --git a/armsrc/Standalone/hf_bog.c b/armsrc/Standalone/hf_bog.c index b906a71eb..7c4b3e5d5 100644 --- a/armsrc/Standalone/hf_bog.c +++ b/armsrc/Standalone/hf_bog.c @@ -37,9 +37,10 @@ from the client to view the stored quadlets. #include "util.h" #include "spiffs.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "BigBuf.h" #include "string.h" @@ -89,9 +90,9 @@ static void RAMFUNC SniffAndStore(uint8_t param) { Uart14aInit(receivedCmd, MAX_FRAME_SIZE, receivedCmdPar); // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE) == false) { + if (FpgaSetupSscRxDmaRepeat((uint8_t *)dmaBuf, DMA_BUFFER_SIZE) == false) { if (g_dbglevel > DBG_ERROR) { - Dbprintf("FpgaSetupSscDma failed. Exiting"); + Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); } return; } @@ -118,7 +119,7 @@ static void RAMFUNC SniffAndStore(uint8_t param) { LED_A_ON(); int register readBufDataP = data - dmaBuf; - int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + int register dmaBufDataP = DMA_BUFFER_SIZE - FPGA_SSC_DMA_RX_Remaining_Count(); if (readBufDataP <= dmaBufDataP) dataLen = dmaBufDataP - readBufDataP; else @@ -132,16 +133,8 @@ static void RAMFUNC SniffAndStore(uint8_t param) { if (dataLen < 1) continue; - // primary buffer was stopped( <-- we lost data! - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - // Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + if (FPGA_SSC_DMA_RX_Done()) { + FPGA_SSC_DMA_RX_Refresh_Repeat(dmaBuf, DMA_BUFFER_SIZE); } LED_A_OFF(); @@ -216,7 +209,7 @@ static void RAMFUNC SniffAndStore(uint8_t param) { } } // end main loop - FpgaDisableSscDma(); + FPGA_SSC_DMA_RX_Disable(); set_tracing(false); Dbprintf("Stopped sniffing"); diff --git a/armsrc/Standalone/hf_cardhopper.c b/armsrc/Standalone/hf_cardhopper.c index 8baa511d2..cc600a865 100644 --- a/armsrc/Standalone/hf_cardhopper.c +++ b/armsrc/Standalone/hf_cardhopper.c @@ -19,16 +19,17 @@ #include "appmain.h" #include "BigBuf.h" #include "dbprint.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "iso14443a.h" #include "protocols.h" #include "proxmark3_arm.h" #include "standalone.h" -#include "ticks.h" +#include "ticks_apis.h" #include "util.h" #include "usart.h" #include "cmd.h" -#include "usb_cdc.h" +#include "usb_cdc_apis.h" #ifdef CARDHOPPER_USB #define cardhopper_write usb_write @@ -535,7 +536,7 @@ static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *received, uint16 Uart14aInit(received, received_max_len, par); - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + uint8_t b = (uint8_t)FPGA_SSC_RX_Value(); (void)b; uint8_t flip = 0; @@ -555,8 +556,8 @@ static bool GetIso14443aCommandFromReaderInterruptible(uint8_t *received, uint16 checker = 4000; } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + b = (uint8_t)FPGA_SSC_RX_Value(); if (MillerDecoding(b, 0)) { *len = GetUart14a()->len; return true; diff --git a/armsrc/Standalone/hf_colin.c b/armsrc/Standalone/hf_colin.c index 7a87347ba..aedad8f1b 100644 --- a/armsrc/Standalone/hf_colin.c +++ b/armsrc/Standalone/hf_colin.c @@ -22,9 +22,10 @@ #include "hf_colin.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "util.h" #include "commonutil.h" #include "BigBuf.h" diff --git a/armsrc/Standalone/hf_craftbyte.c b/armsrc/Standalone/hf_craftbyte.c index d12c5c5dd..a01f86767 100644 --- a/armsrc/Standalone/hf_craftbyte.c +++ b/armsrc/Standalone/hf_craftbyte.c @@ -21,10 +21,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "iso14443a.h" diff --git a/armsrc/Standalone/hf_doegox_auth0.c b/armsrc/Standalone/hf_doegox_auth0.c index c1796ff2a..2e1c9ff60 100644 --- a/armsrc/Standalone/hf_doegox_auth0.c +++ b/armsrc/Standalone/hf_doegox_auth0.c @@ -67,12 +67,13 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "iso14443a.h" #include "util.h" #include "appmain.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "protocols.h" #include "mifareutil.h" #include "string.h" @@ -208,8 +209,8 @@ static bool RAMFUNC sniff_wait_for_rnda_reply(tag_t type) { uint8_t *data = dma->buf; // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); + if (FpgaSetupSscRxDmaRepeat((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); goto out; } @@ -222,7 +223,7 @@ static bool RAMFUNC sniff_wait_for_rnda_reply(tag_t type) { uint32_t ledb_counter = 0; while (BUTTON_PRESS() == false) { register int readBufDataP = data - dma->buf; - register int dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + register int dmaBufDataP = DMA_BUFFER_SIZE - FPGA_SSC_DMA_RX_Remaining_Count(); if (readBufDataP <= dmaBufDataP) { dataLen = dmaBufDataP - readBufDataP; } else { @@ -246,17 +247,7 @@ static bool RAMFUNC sniff_wait_for_rnda_reply(tag_t type) { ledb_counter = 0; } - // primary buffer was stopped( <-- we lost data! - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - // Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + FPGA_SSC_DMA_RX_Refresh_Repeat(dma->buf, DMA_BUFFER_SIZE); // Need two samples to feed Miller and Manchester-Decoder if (rx_samples & 0x01) { @@ -328,7 +319,7 @@ out: FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } FpgaDisableTracing(); - FpgaDisableSscDma(); + FPGA_SSC_DMA_RX_Disable(); return found_rnda_reply; } diff --git a/armsrc/Standalone/hf_doegox_commit.c b/armsrc/Standalone/hf_doegox_commit.c index 89dc91b20..c46f79080 100644 --- a/armsrc/Standalone/hf_doegox_commit.c +++ b/armsrc/Standalone/hf_doegox_commit.c @@ -67,12 +67,13 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "iso14443a.h" #include "util.h" #include "appmain.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "protocols.h" #include "mifareutil.h" #include "string.h" @@ -184,8 +185,8 @@ static bool RAMFUNC sniff_wait_for_commit(tag_t type) { uint8_t *data = dma->buf; // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); + if (FpgaSetupSscRxDmaRepeat((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); goto out; } @@ -195,7 +196,7 @@ static bool RAMFUNC sniff_wait_for_commit(tag_t type) { uint32_t ledb_counter = 0; while (BUTTON_PRESS() == false) { register int readBufDataP = data - dma->buf; - register int dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + register int dmaBufDataP = DMA_BUFFER_SIZE - FPGA_SSC_DMA_RX_Remaining_Count(); if (readBufDataP <= dmaBufDataP) { dataLen = dmaBufDataP - readBufDataP; } else { @@ -219,17 +220,7 @@ static bool RAMFUNC sniff_wait_for_commit(tag_t type) { ledb_counter = 0; } - // primary buffer was stopped( <-- we lost data! - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - // Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + FPGA_SSC_DMA_RX_Refresh_Repeat(dma->buf, DMA_BUFFER_SIZE); // Need two samples to feed Miller and Manchester-Decoder if (rx_samples & 0x01) { @@ -294,7 +285,7 @@ out: FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } FpgaDisableTracing(); - FpgaDisableSscDma(); + FPGA_SSC_DMA_RX_Disable(); return found_commit; } diff --git a/armsrc/Standalone/hf_emvpng.c b/armsrc/Standalone/hf_emvpng.c index 5f9d5f2fa..1125eb9fa 100644 --- a/armsrc/Standalone/hf_emvpng.c +++ b/armsrc/Standalone/hf_emvpng.c @@ -31,10 +31,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "iso14443a.h" diff --git a/armsrc/Standalone/hf_iceclass.c b/armsrc/Standalone/hf_iceclass.c index 56b662024..8a6345d79 100644 --- a/armsrc/Standalone/hf_iceclass.c +++ b/armsrc/Standalone/hf_iceclass.c @@ -26,9 +26,10 @@ #include "proxmark3_arm.h" #include "appmain.h" #include "BigBuf.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" -#include "ticks.h" +#include "ticks_apis.h" #include "dbprint.h" #include "spiffs.h" #include "iclass.h" diff --git a/armsrc/Standalone/hf_legic.c b/armsrc/Standalone/hf_legic.c index a15bb2de3..46432a836 100644 --- a/armsrc/Standalone/hf_legic.c +++ b/armsrc/Standalone/hf_legic.c @@ -21,10 +21,11 @@ #include "proxmark3_arm.h" #include "BigBuf.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "legicrf.h" #include "legicrfsim.h" #include "legic.h" // legic_card_select_t struct diff --git a/armsrc/Standalone/hf_legicsim.c b/armsrc/Standalone/hf_legicsim.c index 849d2be3b..1b35f13da 100644 --- a/armsrc/Standalone/hf_legicsim.c +++ b/armsrc/Standalone/hf_legicsim.c @@ -18,11 +18,12 @@ // main code for legic prime simulator aka LEGICSIM //----------------------------------------------------------------------------- #include -#include "ticks.h" +#include "ticks_apis.h" #include "proxmark3_arm.h" #include "BigBuf.h" #include "commonutil.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" #include "spiffs.h" diff --git a/armsrc/Standalone/hf_mattyrun.c b/armsrc/Standalone/hf_mattyrun.c index 92ce5e5cf..d35345528 100644 --- a/armsrc/Standalone/hf_mattyrun.c +++ b/armsrc/Standalone/hf_mattyrun.c @@ -27,7 +27,8 @@ #include "commonutil.h" #include "crc16.h" #include "dbprint.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "iso14443a.h" #include "mifarecmd.h" #include "mifaresim.h" // mifare1ksim @@ -36,7 +37,7 @@ #include "spiffs.h" #include "standalone.h" // standalone definitions #include "string.h" -#include "ticks.h" +#include "ticks_apis.h" #include "util.h" /* diff --git a/armsrc/Standalone/hf_mfcsim.c b/armsrc/Standalone/hf_mfcsim.c index 667696f86..9dd6afd00 100644 --- a/armsrc/Standalone/hf_mfcsim.c +++ b/armsrc/Standalone/hf_mfcsim.c @@ -17,11 +17,12 @@ // main code for mifare classic simulator aka MFCSIM //----------------------------------------------------------------------------- #include -#include "ticks.h" +#include "ticks_apis.h" #include "proxmark3_arm.h" #include "BigBuf.h" #include "commonutil.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" #include "spiffs.h" diff --git a/armsrc/Standalone/hf_msdsal.c b/armsrc/Standalone/hf_msdsal.c index 6eb5b46b2..94d32c5a1 100644 --- a/armsrc/Standalone/hf_msdsal.c +++ b/armsrc/Standalone/hf_msdsal.c @@ -19,10 +19,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "iso14443a.h" diff --git a/armsrc/Standalone/hf_reblay.c b/armsrc/Standalone/hf_reblay.c index 30db64f41..484c2f596 100644 --- a/armsrc/Standalone/hf_reblay.c +++ b/armsrc/Standalone/hf_reblay.c @@ -19,10 +19,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "iso14443a.h" diff --git a/armsrc/Standalone/hf_st25_tearoff.c b/armsrc/Standalone/hf_st25_tearoff.c index aca569882..e32b86c40 100644 --- a/armsrc/Standalone/hf_st25_tearoff.c +++ b/armsrc/Standalone/hf_st25_tearoff.c @@ -59,12 +59,13 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "iso14443b.h" // ISO14443B operations #include "util.h" #include "spiffs.h" // Flash memory filesystem access #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "BigBuf.h" #include "protocols.h" #include "crc16.h" // compute_crc @@ -368,7 +369,7 @@ static void iso14443b_setup_light(void) { FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // Signal field is on with the appropriate LED -#ifdef RDV4 +#if defined RDV4 || defined PM5 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD_RDV4); #else FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); diff --git a/armsrc/Standalone/hf_tcprst.c b/armsrc/Standalone/hf_tcprst.c index 58fb00163..ea95780ab 100644 --- a/armsrc/Standalone/hf_tcprst.c +++ b/armsrc/Standalone/hf_tcprst.c @@ -19,10 +19,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "iso14443a.h" diff --git a/armsrc/Standalone/hf_tmudford.c b/armsrc/Standalone/hf_tmudford.c index aa986aba0..5f69c9bd3 100644 --- a/armsrc/Standalone/hf_tmudford.c +++ b/armsrc/Standalone/hf_tmudford.c @@ -21,10 +21,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "iso15693.h" #include "iso15.h" diff --git a/armsrc/Standalone/hf_unisniff.c b/armsrc/Standalone/hf_unisniff.c index fcf1bb48d..c26b53632 100644 --- a/armsrc/Standalone/hf_unisniff.c +++ b/armsrc/Standalone/hf_unisniff.c @@ -122,7 +122,7 @@ #include "spiffs.h" #include "appmain.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "BigBuf.h" #include "string.h" diff --git a/armsrc/Standalone/hf_young.c b/armsrc/Standalone/hf_young.c index 079ae7c3b..3d2935a9e 100644 --- a/armsrc/Standalone/hf_young.c +++ b/armsrc/Standalone/hf_young.c @@ -21,10 +21,11 @@ #include #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "commonutil.h" #include "mifarecmd.h" diff --git a/armsrc/Standalone/lf_em4100emul.c b/armsrc/Standalone/lf_em4100emul.c index b9244c59a..4e5a0b8b9 100644 --- a/armsrc/Standalone/lf_em4100emul.c +++ b/armsrc/Standalone/lf_em4100emul.c @@ -20,11 +20,12 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "lfops.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "commonutil.h" diff --git a/armsrc/Standalone/lf_em4100rswb.c b/armsrc/Standalone/lf_em4100rswb.c index c5fd61475..0138cd7ef 100644 --- a/armsrc/Standalone/lf_em4100rswb.c +++ b/armsrc/Standalone/lf_em4100rswb.c @@ -46,10 +46,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "spiffs.h" diff --git a/armsrc/Standalone/lf_em4100rsww.c b/armsrc/Standalone/lf_em4100rsww.c index 91b708599..959a064b6 100644 --- a/armsrc/Standalone/lf_em4100rsww.c +++ b/armsrc/Standalone/lf_em4100rsww.c @@ -47,10 +47,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "spiffs.h" diff --git a/armsrc/Standalone/lf_em4100rwc.c b/armsrc/Standalone/lf_em4100rwc.c index 95e34871f..dd1e15810 100644 --- a/armsrc/Standalone/lf_em4100rwc.c +++ b/armsrc/Standalone/lf_em4100rwc.c @@ -28,11 +28,12 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "lfops.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "string.h" #include "BigBuf.h" #include "spiffs.h" diff --git a/armsrc/Standalone/lf_hidbrute.c b/armsrc/Standalone/lf_hidbrute.c index da78d0975..57973d61a 100644 --- a/armsrc/Standalone/lf_hidbrute.c +++ b/armsrc/Standalone/lf_hidbrute.c @@ -33,10 +33,11 @@ #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "lfops.h" #define OPTS 3 diff --git a/armsrc/Standalone/lf_hidfcbrute.c b/armsrc/Standalone/lf_hidfcbrute.c index 284b098b7..b6d453544 100644 --- a/armsrc/Standalone/lf_hidfcbrute.c +++ b/armsrc/Standalone/lf_hidfcbrute.c @@ -40,15 +40,15 @@ #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "lfsampling.h" #include "util.h" #include "dbprint.h" #include "spiffs.h" -#include "ticks.h" +#include "ticks_apis.h" #include "lfops.h" #include "BigBuf.h" -#include "fpgaloader.h" #include "parity.h" // What card number should be used for the bruteforce? diff --git a/armsrc/Standalone/lf_icehid.c b/armsrc/Standalone/lf_icehid.c index c44069a12..70f00a6a0 100644 --- a/armsrc/Standalone/lf_icehid.c +++ b/armsrc/Standalone/lf_icehid.c @@ -23,12 +23,13 @@ #include "lfops.h" #include "lfsampling.h" #include "BigBuf.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" #include "printf.h" #include "spiffs.h" -#include "ticks.h" +#include "ticks_apis.h" #include "lfdemod.h" /* * `lf_hidcollect` sniffs after LF HID credentials, and stores them in internal diff --git a/armsrc/Standalone/lf_multihid.c b/armsrc/Standalone/lf_multihid.c index d2edd867c..cf471da33 100644 --- a/armsrc/Standalone/lf_multihid.c +++ b/armsrc/Standalone/lf_multihid.c @@ -25,10 +25,11 @@ #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "lfops.h" #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0])) diff --git a/armsrc/Standalone/lf_nedap_sim.c b/armsrc/Standalone/lf_nedap_sim.c index 726f13ca8..b2002b71d 100644 --- a/armsrc/Standalone/lf_nedap_sim.c +++ b/armsrc/Standalone/lf_nedap_sim.c @@ -19,7 +19,8 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "lfops.h" #include "util.h" #include "dbprint.h" diff --git a/armsrc/Standalone/lf_nexid.c b/armsrc/Standalone/lf_nexid.c index 5789226a1..b1697d81e 100644 --- a/armsrc/Standalone/lf_nexid.c +++ b/armsrc/Standalone/lf_nexid.c @@ -24,12 +24,13 @@ #include "lfops.h" #include "lfsampling.h" #include "BigBuf.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" #include "printf.h" #include "spiffs.h" -#include "ticks.h" +#include "ticks_apis.h" #include "lfdemod.h" #include "commonutil.h" diff --git a/armsrc/Standalone/lf_prox2brute.c b/armsrc/Standalone/lf_prox2brute.c index 86c06a91a..21d7fb59e 100644 --- a/armsrc/Standalone/lf_prox2brute.c +++ b/armsrc/Standalone/lf_prox2brute.c @@ -27,7 +27,8 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" #include "lfops.h" diff --git a/armsrc/Standalone/lf_proxbrute.c b/armsrc/Standalone/lf_proxbrute.c index 112693077..740297d53 100644 --- a/armsrc/Standalone/lf_proxbrute.c +++ b/armsrc/Standalone/lf_proxbrute.c @@ -19,10 +19,11 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "lfops.h" void ModInfo(void) { diff --git a/armsrc/Standalone/lf_samyrun.c b/armsrc/Standalone/lf_samyrun.c index 215ccfa44..4da554a20 100644 --- a/armsrc/Standalone/lf_samyrun.c +++ b/armsrc/Standalone/lf_samyrun.c @@ -19,11 +19,11 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_loader.h" #include "lfops.h" #include "util.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #define OPTS 2 diff --git a/armsrc/Standalone/lf_skeleton.c b/armsrc/Standalone/lf_skeleton.c index 4272cfc7e..2008cd0ae 100644 --- a/armsrc/Standalone/lf_skeleton.c +++ b/armsrc/Standalone/lf_skeleton.c @@ -18,7 +18,8 @@ #include "standalone.h" // standalone definitions #include "proxmark3_arm.h" #include "appmain.h" -#include "fpgaloader.h" +#include "fpga_apis.h" +#include "fpga_loader.h" #include "util.h" #include "dbprint.h" diff --git a/armsrc/Standalone/lf_tharexde.c b/armsrc/Standalone/lf_tharexde.c index 735270328..76b143a4b 100644 --- a/armsrc/Standalone/lf_tharexde.c +++ b/armsrc/Standalone/lf_tharexde.c @@ -17,13 +17,13 @@ // main code for EM4x50 simulator and collector aka THAREXDE //----------------------------------------------------------------------------- #include -#include "ticks.h" +#include "ticks_apis.h" #include "standalone.h" #include "proxmark3_arm.h" #include "appmain.h" #include "BigBuf.h" #include "commonutil.h" -#include "fpgaloader.h" +#include "fpga_apis.h" #include "util.h" #include "dbprint.h" #include "spiffs.h" @@ -279,11 +279,7 @@ void RunMod(void) { } } - // reset timer - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // re-enable timer and wait for TC0 - AT91C_BASE_TC0->TC_RC = 0; // set TIOA (carry bit) on overflow, return to zero - AT91C_BASE_TC0->TC_RA = 1; // clear carry bit on next clock cycle - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; // reset and re-enable timer + ResetTicks(); } if (state == STATE_READ) { diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a37642b38..9b8946c27 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -20,13 +20,15 @@ //----------------------------------------------------------------------------- #include "appmain.h" -#include "clocks.h" -#include "usb_cdc.h" +#include "sys_apis.h" +#include "usb_cdc_apis.h" #include "proxmark3_arm.h" #include "dbprint.h" #include "pmflash.h" #include "fpga.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" +#include "rssi_apis.h" #include "string.h" #include "printf.h" #include "legicrf.h" @@ -62,7 +64,7 @@ #include "pcf7931.h" #include "Standalone/standalone.h" #include "util.h" -#include "ticks.h" +#include "ticks_apis.h" #include "commonutil.h" #include "crc16.h" #include "protocols.h" @@ -72,6 +74,7 @@ #include "sam_mfc.h" #include "sam_sc.h" #include "cmac_calc.h" +#include "i2c.h" #ifdef WITH_LCD #include "LCD_disabled.h" @@ -146,47 +149,6 @@ void send_wtx(uint16_t wtx) { } } -//----------------------------------------------------------------------------- -// Read an ADC channel and block till it completes, then return the result -// in ADC units (0 to 1023). Also a routine to sum up a number of samples and -// return that. -//----------------------------------------------------------------------------- -static uint16_t ReadAdc(uint8_t ch) { - - // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. - // AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant - // of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. - // - // The maths are: - // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be - // - // v_cap = v_in * (1 - exp(-SHTIM/RC)) = v_in * (1 - exp(-40us/10.9us)) = v_in * 0,97 (i.e. an error of 3%) - - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; - AT91C_BASE_ADC->ADC_MR = - ADC_MODE_PRESCALE(63) // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz - | ADC_MODE_STARTUP_TIME(1) // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us - | ADC_MODE_SAMPLE_HOLD_TIME(15); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us - - AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch); - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; - - while (!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {}; - - return (AT91C_BASE_ADC->ADC_CDR[ch] & 0x3FF); -} - -// was static - merlok -uint16_t AvgAdc(uint8_t ch) { - return SumAdc(ch, 32) >> 5; -} - -uint16_t SumAdc(uint8_t ch, uint8_t NbSamples) { - uint16_t a = 0; - for (uint8_t i = 0; i < NbSamples; i++) - a += ReadAdc(ch); - return (a + (NbSamples >> 1) - 1); -} #ifdef WITH_LF static void MeasureAntennaTuning(void) { @@ -230,7 +192,7 @@ static void MeasureAntennaTuning(void) { WDT_HIT(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); - uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14); + uint32_t adcval = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_LF); if (i == LF_DIVISOR_125) payload.v_lf125 = adcval; // voltage at 125kHz @@ -255,24 +217,15 @@ static void MeasureAntennaTuning(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER); SpinDelay(50); - payload.v_hf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + payload.v_hf = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t *)&payload, sizeof(payload)); LEDsoff(); } #endif -// Measure HF in milliVolt -static uint16_t MeasureAntennaTuningHfData(void) { - return (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; - -} - -// Measure LF in milliVolt -static uint32_t MeasureAntennaTuningLfData(void) { - return (MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14; -} +#ifndef PM5 // TODO DXL: PM5 is temporarily incompatible. // Measure HF antenna decay after field-off. // Captures peak-detect capacitor discharge curve via burst ADC sampling. @@ -297,7 +250,7 @@ static void MeasureAntennaTuningHfDecay(const hf_decay_params_t *params) { SpinDelay(stabilize_ms); // Baseline measurement (averaged) - payload.baseline_mv = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + payload.baseline_mv = (MAX_ADC_HF_VOLTAGE * AdcRssiSum(ADC_RSSI_CH_HF, 32)) >> 15; // Configure ADC for fast burst mode. // Faster ADC clock + shorter S&H trades absolute accuracy for speed. @@ -354,6 +307,8 @@ static void MeasureAntennaTuningHfDecay(const hf_decay_params_t *params) { LEDsoff(); } +#endif + void print_stack_usage(void) { for (uint32_t *p = _stack_start; ; ++p) { if (*p != 0xdeadbeef) { @@ -429,7 +384,10 @@ static void SendVersion(void) { } PACKED; struct p payload; - payload.id = *(AT91C_DBGU_CIDR); + + // Set a CHIP ID(not unique id) + payload.id = GetChipId(); + #ifndef WITH_COMPRESSION payload.section_size = (uint32_t)_bootrom_end - (uint32_t)_bootrom_start + (uint32_t)__os_size__; #else @@ -441,6 +399,8 @@ static void SendVersion(void) { reply_ng(CMD_VERSION, PM3_SUCCESS, (uint8_t *)&payload, 12 + payload.versionstr_len); } +#ifdef CHIP_AT91SAM7S // Only AT91SAM7S chip series need calibration. + static void TimingIntervalAcquisition(void) { // trigger new acquisition by turning main oscillator off and on mck_from_pll_to_slck(); @@ -449,6 +409,8 @@ static void TimingIntervalAcquisition(void) { StartTickCount(); } +#endif + static void print_debug_level(void) { char dbglvlstr[20] = {0}; switch (g_dbglevel) { @@ -529,6 +491,9 @@ static void SendStatus(uint32_t wait) { tosend_t *ts = get_tosend(); Dbprintf(" ToSendMax........... %d", ts->max); Dbprintf(" ToSend BUFFERSIZE... %d", TOSEND_BUFFER_SIZE); + +#ifdef CHIP_AT91SAM7S + while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; // Get # main clocks within 16 slow clocks Dbprintf(" Slow clock.......... %d Hz", (16 * MAINCK) / mainf); @@ -543,6 +508,9 @@ static void SendStatus(uint32_t wait) { Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"), (16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS); } + +#endif + DbpString(_CYAN_("Installed StandAlone Mode")); ModInfo(); @@ -816,7 +784,7 @@ void ListenReaderField(uint8_t limit) { LEDsoff(); if (limit == LF_ONLY || limit == LF_HF_BOTH) { - lf_av = lf_max = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15; + lf_av = lf_max = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_LF); Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av); lf_baseline = lf_av; } @@ -824,7 +792,7 @@ void ListenReaderField(uint8_t limit) { if (limit == HF_ONLY || limit == LF_HF_BOTH) { // iceman, useless, since we are measuring readerfield, not our field. My tests shows a max of 20v from a reader. - hf_av = hf_max = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + hf_av = hf_max = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF);; Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av); hf_baseline = hf_av; } @@ -864,7 +832,7 @@ void ListenReaderField(uint8_t limit) { LED_D_OFF(); } - lf_av_new = (MAX_ADC_LF_VOLTAGE * SumAdc(ADC_CHAN_LF, 32)) >> 15; + lf_av_new = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_LF); // see if there's a significant change if (ABS(lf_av - lf_av_new) > REPORT_CHANGE) { Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new); @@ -882,7 +850,7 @@ void ListenReaderField(uint8_t limit) { LED_B_OFF(); } - hf_av_new = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + hf_av_new = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF); // see if there's a significant change if (ABS(hf_av - hf_av_new) > REPORT_CHANGE) { Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new); @@ -965,6 +933,188 @@ void ListenReaderField(uint8_t limit) { } } } + +#ifdef PM5 + +#include "at32f435_437_crm.h" +#include "at32f435_437_tmr.h" + +// TODO DXL: 一部分QC逻辑可以放在PM5设备端实现,这个函数后面记得复用代码,并且不要放在 appmain.c 中(考虑移动到平台专属的模块) +// failed_item == 0: BLUE LED in Antenna +// failed_item == 1: RGB in mainboard +// failed_item == 2: LEDs * 4 or Buzzer or Button in mainboard +static bool QCTestPM5(uint8_t *failed_item) { + // 天线蓝灯、主板RGB、主板四颗LED、蜂鸣器、按钮 + StartTicks(); + I2C_init(true); + + uint8_t addr_ant = 0x51; // TODO DXL define move to header? + uint8_t addr_rgb = 0x48; + uint8_t data_u8; + bool isok = false; + + // 读取天线当前MAP配置,如果读取不到,则认为天线的控制芯片可能有问题 + isok = I2C_BufferReadRaw(&data_u8, 1, 0x02, addr_ant << 1); + if (!isok) { + *failed_item = 0; + return false; + } + // 重新写入天线的MAP配置,去开灯 + data_u8 |= 0x06; // 0000 0110 // 125 134 250 375 500 HFLED LFLED Q + isok = I2C_BufferWrite(&data_u8, 1, 0x02, addr_ant << 1); + + // 开启RGB灯自动闪烁 + uint8_t buf_rgb[3] = {0, 0, 128}; + uint8_t buf_flash_time[] = {50, 50}; // 1s on, 500ms off. + isok = I2C_WriteByte(0, 0x02, addr_rgb << 1); // 写索引寄存器,设置后续操作的RGB索引 + if (!isok) { + *failed_item = 1; + return false; + } + isok = I2C_WriteByte(1, 0x01, addr_rgb << 1); // 写数量寄存器,设置硬件挂1个灯,很重要!!!,不然无法闪灯 + if (!isok) { + *failed_item = 1; + return false; + } + isok = I2C_BufferWrite(buf_rgb, sizeof(buf_rgb), 0x03, addr_rgb << 1); // 写数据寄存器,每三个字节就是对应的RGB888值 + if (!isok) { + *failed_item = 1; + return false; + } + isok = I2C_WriteByte(1, 0x06, addr_rgb << 1); // 写闪灯使能寄存器,使能 0 号灯珠的可控闪烁 + if (!isok) { + *failed_item = 1; + return false; + } + isok = I2C_BufferWrite(buf_flash_time, sizeof(buf_flash_time), 0x07, addr_rgb << 1); // 写闪灯使能寄存器,使能 0 号灯珠的可控闪烁 + if (!isok) { + *failed_item = 1; + return false; + } + + // 在循环中测试LED、蜂鸣器、按钮 + +#define BEEPER_EN_GPIO GPIOB +#define BEEPER_EN_GPIO_PIN GPIO_PINS_13 +#define BEEPER_MOD_GPIO GPIOC +#define BEEPER_MOD_GPIO_PIN GPIO_PINS_9 +#define BEEPER_MOD_GPIO_SRC GPIO_PINS_SOURCE9 +#define BEEPER_MOD_GPIO_MUX GPIO_MUX_3 +#define BEEPER_MOD_TMR TMR8 +#define BEEPER_MOD_TMR_CH TMR_SELECT_CHANNEL_4 + + // PB13 使能,PC9 调制,使用 TMR8_CH4 输出调制 + crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE); + crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, TRUE); + + gpio_init_type gpio_init_struct; + gpio_default_para_init(&gpio_init_struct); + // 蜂鸣器使能脚 + gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; + gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; + gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; + gpio_init_struct.gpio_pins = BEEPER_EN_GPIO_PIN; + gpio_init_struct.gpio_pull = GPIO_PULL_NONE; + gpio_init(BEEPER_EN_GPIO, &gpio_init_struct); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, FALSE); + // 蜂鸣器调制脚 + gpio_init_struct.gpio_mode = GPIO_MODE_MUX; + gpio_init_struct.gpio_pins = BEEPER_MOD_GPIO_PIN; + gpio_init(BEEPER_MOD_GPIO, &gpio_init_struct); + gpio_pin_mux_config(BEEPER_MOD_GPIO, BEEPER_MOD_GPIO_SRC, BEEPER_MOD_GPIO_MUX); + + tmr_internal_clock_set(BEEPER_MOD_TMR); + tmr_reset(BEEPER_MOD_TMR); + tmr_base_init(BEEPER_MOD_TMR, 999, 95); // 192M出2k + tmr_output_config_type tmr_output_struct; + tmr_output_default_para_init(&tmr_output_struct); + tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; + tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tmr_output_struct.oc_output_state = TRUE; + tmr_output_channel_config(BEEPER_MOD_TMR, BEEPER_MOD_TMR_CH, &tmr_output_struct); + tmr_channel_value_set(BEEPER_MOD_TMR, BEEPER_MOD_TMR_CH, 500); // 比较值=500 (50%占空比) + tmr_counter_enable(BEEPER_MOD_TMR, TRUE); + tmr_output_enable(BEEPER_MOD_TMR, TRUE); + + LEDsoff(); // 在开始测试之前线关闭所有LED + + *failed_item = 2; + // 在开始测试之前,如果按钮是按下的,则认为失败,有可能按钮不良卡住了 + if (BUTTON_PRESS()) { + return false; + } + + while (1) { + if (BUTTON_PRESS()) { + return true; + } + if (data_available()) { + return false; + } + + LED_A_ON(); + BEEPER_MOD_TMR->pr = 999; + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, TRUE); + SpinDelay(20); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, FALSE); + SpinDelay(200); + LED_A_OFF(); + + if (BUTTON_PRESS()) { + return true; + } + if (data_available()) { + return false; + } + + LED_B_ON(); + BEEPER_MOD_TMR->pr = 1100; + tmr_channel_value_set(BEEPER_MOD_TMR, BEEPER_MOD_TMR_CH, 550); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, TRUE); + SpinDelay(20); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, FALSE); + SpinDelay(200); + LED_B_OFF(); + + if (BUTTON_PRESS()) { + return true; + } + if (data_available()) { + return false; + } + + LED_C_ON(); + BEEPER_MOD_TMR->pr = 1200; + tmr_channel_value_set(BEEPER_MOD_TMR, BEEPER_MOD_TMR_CH, 600); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, TRUE); + SpinDelay(20); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, FALSE); + SpinDelay(200); + LED_C_OFF(); + + if (BUTTON_PRESS()) { + return true; + } + if (data_available()) { + return false; + } + + LED_D_ON(); + BEEPER_MOD_TMR->pr = 1300; + tmr_channel_value_set(BEEPER_MOD_TMR, BEEPER_MOD_TMR_CH, 650); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, TRUE); + SpinDelay(20); + gpio_bits_write(BEEPER_EN_GPIO,BEEPER_EN_GPIO_PIN, FALSE); + SpinDelay(200); + LED_D_OFF(); + } + + return true; +} + +#endif + static void PacketReceived(PacketCommandNG *packet) { /* if (packet->ng) { @@ -2684,7 +2834,7 @@ static void PacketReceived(PacketCommandNG *packet) { if (button_status == BUTTON_SINGLE_CLICK) { reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_EOPABORTED, NULL, 0); } - uint16_t volt = MeasureAntennaTuningHfData(); + uint32_t volt = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF); reply_ng(CMD_MEASURE_ANTENNA_TUNING_HF, PM3_SUCCESS, (uint8_t *)&volt, sizeof(volt)); break; case 3: @@ -2697,10 +2847,12 @@ static void PacketReceived(PacketCommandNG *packet) { } break; } +#ifndef PM5 case CMD_HF_DECAY: { MeasureAntennaTuningHfDecay((const hf_decay_params_t *)packet->data.asBytes); break; } +#endif case CMD_MEASURE_ANTENNA_TUNING_LF: { if (packet->length != 2) reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EINVARG, NULL, 0); @@ -2718,7 +2870,7 @@ static void PacketReceived(PacketCommandNG *packet) { reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_EOPABORTED, NULL, 0); } - uint32_t volt = MeasureAntennaTuningLfData(); + uint32_t volt = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_LF); reply_ng(CMD_MEASURE_ANTENNA_TUNING_LF, PM3_SUCCESS, (uint8_t *)&volt, sizeof(volt)); break; case 3: @@ -2848,7 +3000,7 @@ static void PacketReceived(PacketCommandNG *packet) { base = (uint8_t *) _flash_start; - size_t flash_size = get_flash_size(); + size_t flash_size = GetChipFlashSize(); // Boundary check the offset. if (offset > flash_size) { @@ -3072,7 +3224,7 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_FLASHMEM_SET_SPIBAUDRATE: { if (packet->length != sizeof(uint32_t)) break; - FlashmemSetSpiBaudrate(packet->data.asDwords[0]); + Flash_SetSpiBaudrate(packet->data.asDwords[0]); break; } case CMD_FLASHMEM_WRITE: { @@ -3199,6 +3351,16 @@ static void PacketReceived(PacketCommandNG *packet) { LED_B_OFF(); break; } + case CMD_FLASHMEM_INFO: { + uint64_t flash_uniqueID = 0; + bool isok = FlashInit(); + if (isok) { + isok = Flash_UniqueID((uint8_t *)(&flash_uniqueID)); + FlashStop(); + } + reply_ng(CMD_FLASHMEM_INFO, (isok) ? PM3_SUCCESS : PM3_EFLASH, (uint8_t *)&flash_uniqueID, sizeof(flash_uniqueID)); + break; + } #endif #ifdef WITH_LF case CMD_LF_SET_DIVISOR: { @@ -3210,17 +3372,17 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_SET_ADC_MUX: { switch (packet->data.asBytes[0]) { case 0: - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); break; case 2: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); break; #ifndef WITH_FPC_USART case 1: - SetAdcMuxFor(GPIO_MUXSEL_LORAW); + SetAdcMuxFor(ADC_MUXSEL_LORAW); break; case 3: - SetAdcMuxFor(GPIO_MUXSEL_HIRAW); + SetAdcMuxFor(ADC_MUXSEL_HIRAW); break; #endif } @@ -3238,7 +3400,7 @@ static void PacketReceived(PacketCommandNG *packet) { break; } case CMD_TIA: { - +#ifdef CHIP_AT91SAM7S while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available... uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF; Dbprintf(" Slow clock old measured value:.........%d Hz", (16 * MAINCK) / mainf); @@ -3249,6 +3411,10 @@ static void PacketReceived(PacketCommandNG *packet) { Dbprintf(""); // first message gets lost Dbprintf(" Slow clock new measured value:.........%d Hz", (16 * MAINCK) / mainf); reply_ng(CMD_TIA, PM3_SUCCESS, NULL, 0); +#else + Dbprintf("Chip is not AT91SAM7S, TIA is " _RED_("unsupported")); + reply_ng(CMD_TIA, PM3_EDEVNOTSUPP, NULL, 0); +#endif break; } case CMD_STANDALONE: { @@ -3294,8 +3460,8 @@ static void PacketReceived(PacketCommandNG *packet) { usb_disable(); // (iceman) why this wait? - SpinDelay(1000); - AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; + SpinDelay(1000); // Go wait for the USB to completely go offline on the host side. + ResetChip(); // We're going to reset, and the bootrom will take control. for (;;) {} break; @@ -3305,7 +3471,7 @@ static void PacketReceived(PacketCommandNG *packet) { g_common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE; } usb_disable(); - AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; + ResetChip(); // We're going to flash, and the bootrom will take control. for (;;) {} break; @@ -3318,13 +3484,126 @@ static void PacketReceived(PacketCommandNG *packet) { reply_old(CMD_DEVICE_INFO, dev_info, 0, 0, 0, 0); break; } + case CMD_FPGA_BITSTREAM_CONFIG_START: // Merge 3 cmds to reuse some code. + case CMD_FPGA_BITSTREAM_CONFIG_WRITE: + case CMD_FPGA_BITSTREAM_CONFIG_FINISH: { + // Dbprintf("Received FPGA config command 0x%04x", packet->cmd); + int res; + // Process + if (packet->cmd == CMD_FPGA_BITSTREAM_CONFIG_START) { + struct p { + uint8_t sram_mode; + uint32_t file_length; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + res = FpgaStartConfig(payload->sram_mode, payload->file_length); + } else if (packet->cmd == CMD_FPGA_BITSTREAM_CONFIG_WRITE) { + res = FpgaConfigWrite(packet->data.asBytes, packet->length); + } else { + res = FpgaStopConfig(); + } + // Response + if (res == PM3_EFAILED) { + uint32_t plat_status = FpgaConfigPlatformStatus(); // Return status code of platform when res is PM3_EFAILED + reply_ng(packet->cmd, res, (uint8_t*)&plat_status, sizeof(plat_status)); + } else { + reply_ng(packet->cmd, res, NULL, 0); + } + break; + } +#ifdef PM5 + case CMD_ANT_CONTROL_WRITE: { + struct p { + uint8_t data; + uint8_t reg_type; // 0 is io reg, 1 is map reg. + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + + StartTicks(); + I2C_init(true); + + uint8_t addr = 0x51; // TODO DXL define move to header? + uint8_t cmd = payload->reg_type == 0 ? 0x01 : 0x02; + + bool isok = I2C_BufferWrite(&payload->data, 1, cmd, addr << 1); + reply_ng(CMD_ANT_CONTROL_WRITE, isok ? PM3_SUCCESS : PM3_EFAILED, NULL, 0); + break; + } + case CMD_ANT_CONTROL_READ: { + struct p { + uint8_t reg_type; // 0 is io reg, 1 is map reg. + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + + StartTicks(); + I2C_init(true); + + uint8_t addr = 0x51; // TODO DXL define move to header? + uint8_t cmd = payload->reg_type == 0 ? 0x01 : 0x02; + uint8_t data; + + bool isok = I2C_BufferReadRaw(&data, 1, cmd, addr << 1); + reply_ng(CMD_ANT_CONTROL_READ, isok ? PM3_SUCCESS : PM3_EFAILED, &data, sizeof(data)); + break; + } + case CMD_EEPROM_FACTORY_INFO_READ: { + StartTicks(); + I2C_init(true); + + uint8_t addr = 0x50; // TODO DXL define move to header? + uint8_t data[256]; // 24c02: 256byte + bool isok = I2C_BufferReadRaw(data, sizeof(data), 0x00, addr << 1); + reply_ng(CMD_EEPROM_FACTORY_INFO_READ, isok ? PM3_SUCCESS : PM3_EFAILED, data, sizeof(data)); + break; + } + case CMD_EEPROM_FACTORY_INFO_WRITE: { + StartTicks(); + I2C_init(true); + + uint8_t addr = 0x50; // TODO DXL define move to header? + uint16_t len = packet->length; + while (len) { + uint16_t write_len = MIN(len, 16); + uint16_t write_pos = packet->length - len; + bool isok = I2C_BufferWrite(packet->data.asBytes + write_pos, write_len, write_pos, addr << 1); + if (!isok) { + reply_ng(CMD_EEPROM_FACTORY_INFO_WRITE, PM3_EFAILED, NULL, 0); + return; + } + len -= write_len; + // 24C02 writes to a page write buffer of only 16 bytes. + // If the write speed is too fast, it may cause data write failure. + // Therefore, a delay or ACK judgment is required between page writes + SpinDelay(5); // 24C02 write cycle time is about 5ms + } + reply_ng(CMD_EEPROM_FACTORY_INFO_WRITE, PM3_SUCCESS, NULL, 0); + break; + } +#endif + case CMD_FPGA_CMD_SET_PWR_PWM_LOW_COUNT: { + struct p { + uint8_t is_lf; + uint16_t count; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + FpgaDownloadAndGo(payload->is_lf ? FPGA_BITSTREAM_LF : FPGA_BITSTREAM_HF); + FpgaSendCommand(FPGA_CMD_SET_PWR_PWM_LOW_COUNT, payload->count & 0xFFF); + reply_ng(CMD_FPGA_CMD_SET_PWR_PWM_LOW_COUNT, PM3_SUCCESS, NULL, 0); + break; + } case CMD_MAIN_CHIP_UNIQUEID: { - // PM3 placeholder, to be replaced when correct commit gets merged uint8_t size = 0; - uint8_t* uid = NULL; + uint8_t* uid = GetChipUniqueId(&size); reply_ng(CMD_MAIN_CHIP_UNIQUEID, PM3_SUCCESS, uid, size); break; } +#ifdef PM5 + case CMD_PM5_QC_TEST: { + uint8_t failed_item = 0; + reply_ng(CMD_PM5_QC_TEST, QCTestPM5(&failed_item) ? PM3_SUCCESS : PM3_EFAILED, &failed_item, 1); + break; + } +#endif default: { Dbprintf("%s: 0x%04x", "unknown command:", packet->cmd); break; @@ -3332,7 +3611,7 @@ static void PacketReceived(PacketCommandNG *packet) { } } -void __attribute__((noreturn)) AppMain(void) { +void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); BigBuf_initialize(); @@ -3344,23 +3623,12 @@ void __attribute__((noreturn)) AppMain(void) { LEDsoff(); - // The FPGA gets its clock from us from PCK0 output, so set that up. - AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; - AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0; - AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_PCK0; - // PCK0 is PLL clock / 4 = 96MHz / 4 = 24MHz - AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_4; // 4 for 24MHz pck0, 2 for 48 MHZ pck0 - AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0; - - // Reset SPI - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; - AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; // errata says it needs twice to be correctly set. - - // Reset SSC - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; + // Setup FPGA clock & Reset COM + FpgaSetup24MHzClk(); + FpgaResetComInterface(); // Configure MUX - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // Load the FPGA image, which we have stored in our flash. // (the HF version by default) @@ -3389,12 +3657,10 @@ void __attribute__((noreturn)) AppMain(void) { } #endif - #ifdef WITH_FLASH // If flash is not present, BUSY_TIMEOUT kicks in, let's do it after USB loadT55xxConfig(); - // // Enforce a spiffs check/garbage collection at boot so we are likely to never // fall under the 2 contigous free blocks availables // This is a time-consuming process on large flash. @@ -3457,9 +3723,68 @@ void __attribute__((noreturn)) AppMain(void) { * So this is the trigger to execute a standalone mod. Generic entrypoint by following the standalone/standalone.h headerfile * All standalone mod "main loop" should be the RunMod() function. */ - allow_send_wtx = false; - RunMod(); - allow_send_wtx = true; + // allow_send_wtx = false; + // RunMod(); + // allow_send_wtx = true; + +#ifdef PM5 // TODO DXL Test long press to device shutdown, temporarily blocking standalone mod + + /* + StartTicks(); + I2C_init(true); + uint8_t addr = 0x51; + // 125 134 250 375 500 HFLED LFLED Q + // 1 0 0 0 0 1 1 1 + uint8_t data = 0x87; + I2C_BufferWrite(&data, 1, 0x02, addr << 1); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_PWR_PWM_LOW_COUNT, 4095); + + static bool b = 0; + if (b) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + b = 0; + } else { + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); + b = 1; + } + */ + + LEDsoff(); + while (BUTTON_PRESS()) { + SpinDelay(50); + LED_A_INV(); + SpinDelay(50); + LED_B_INV(); + SpinDelay(50); + LED_C_INV(); + SpinDelay(50); + LED_D_INV(); + } + // Release for more than 100ms before truly shutting down, anti shake + uint8_t idx = 0; + while (!BUTTON_PRESS()) { + SpinDelay(10); + idx += 1; + if (idx == 10) { + break; + } + } + LEDsoff(); + if (idx == 10) { + SpinDelay(100); + LED_A_INV(); + SpinDelay(100); + LED_A_INV(); + SpinDelay(100); + LED_A_INV(); + Gpio_ARM_Power_ON_Low(); + while (1); // Wait for system power off. + } + +#endif } } } diff --git a/armsrc/appmain.h b/armsrc/appmain.h index 40cbdb52d..b2fafc107 100644 --- a/armsrc/appmain.h +++ b/armsrc/appmain.h @@ -28,16 +28,6 @@ extern bool g_hf_field_timeout_active; void hf_field_off(void); int tearoff_hook(void); -#if defined RDV4 || defined ICOPYX -// ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV -#define MAX_ADC_HF_VOLTAGE 140800 -#else -// ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV -#define MAX_ADC_HF_VOLTAGE 36300 -#endif -// ADC Vref = 3300mV, (240k-10M):240k voltage divider, 140800 mV -#define MAX_ADC_LF_VOLTAGE 140800 - // Default connection speed test timeout, used in hw status #define CONN_SPEED_TEST_MIN_TIME_DEFAULT 500 // in milliseconds @@ -48,9 +38,6 @@ void send_wtx(uint16_t wtx); void ReadMem(int addr); void __attribute__((noreturn)) AppMain(void); -uint16_t AvgAdc(uint8_t ch); -uint16_t SumAdc(uint8_t ch, uint8_t NbSamples); - //void PrintToSendBuffer(void); void ToSendStuffBit(int b); void ToSendReset(void); diff --git a/armsrc/cmd.c b/armsrc/cmd.c index 2c708c826..492b4aa26 100644 --- a/armsrc/cmd.c +++ b/armsrc/cmd.c @@ -14,7 +14,8 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- #include "cmd.h" -#include "usb_cdc.h" +#include "usb_cdc_apis.h" +#include "usb_read_ng.h" #include "usart.h" #include "crc16.h" #include "string.h" @@ -73,6 +74,9 @@ int reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, const v return PM3_SUCCESS; } +// TODO DXL 测试阶段,暂时通过SPI应答 +extern int cep_spi_write_sync(uint8_t *data, size_t len); + static int reply_ng_internal(uint16_t cmd, int8_t status, uint8_t reason, const uint8_t *data, size_t len, bool ng) { PacketResponseNGRaw txBufferNG; size_t txBufferNGLen; @@ -119,6 +123,10 @@ static int reply_ng_internal(uint16_t cmd, int8_t status, uint8_t reason, const resultusb = usb_write((uint8_t *)&txBufferNG, txBufferNGLen); } if (g_reply_via_fpc) { + + // TODO DXL 测试阶段,暂时通过SPI应答 + // resultusb = cep_spi_write_sync((uint8_t *)&txBufferNG, txBufferNGLen); + #ifdef WITH_FPC_USART_HOST resultfpc = usart_writebuffer_sync((uint8_t *)&txBufferNG, txBufferNGLen); #else @@ -251,6 +259,10 @@ static int receive_ng_internal(PacketCommandNG *rx, uint32_t read_ng(uint8_t *da return PM3_SUCCESS; } +// TODO DXL 临时在此处定义外部实现的CEP端口的SPI通信实现,做视频通信测试用的,后期需要重构设计 +// extern uint32_t cep_spi_read_ng(uint8_t *data, size_t len); +// extern bool cep_spi_data_available(void); + int receive_ng(PacketCommandNG *rx) { // Check if there is a packet available @@ -258,6 +270,10 @@ int receive_ng(PacketCommandNG *rx) { return receive_ng_internal(rx, usb_read_ng, true, false); } + // if (cep_spi_data_available()) { + // return receive_ng_internal(rx, cep_spi_read_ng, false, true); // TODO DXL 临时用fpc这种标志 + // } + #ifdef WITH_FPC_USART_HOST // Check if there is a FPC packet available if (usart_rxdata_available() > 0) diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index 8de00ccae..0aa9fb78d 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -16,10 +16,10 @@ // Low frequency EM4x50 commands //----------------------------------------------------------------------------- -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "dbprint.h" -#include "lfsampling.h" #include "lfadc.h" #include "lfdemod.h" #include "commonutil.h" @@ -29,15 +29,8 @@ #include "appmain.h" // tear #include "bruteforce.h" -// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) -// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz -// EM4x50 units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) -// T0 = TIMER_CLOCK1 / 125000 = 192 - -#define T0 192 - // conversions (carrier frequency 125 kHz): -// 1 us = 1.5 ticks +// 1 us = 1.5 ticks for GetTicks() // 1 cycle = 1 period = 8 us = 12 ticks // 1 bit = 64 cycles = 768 ticks = 512 us (for Opt64) #define CYCLES2TICKS 12 @@ -59,8 +52,8 @@ #define EM4X50_T_ZERO_DETECTION 3 // timeout values (empirical) for simulation mode (may vary with regard to reader) -#define EM4X50_T_SIMULATION_TIMEOUT_READ 600 -#define EM4X50_T_SIMULATION_TIMEOUT_WAIT 50 +#define EM4X50_T_SIMULATION_TIMEOUT_READ 318 // only for em4x50_sim_read_bit() +#define EM4X50_T_SIMULATION_TIMEOUT_EDGE 24 // the following value (pulses) seems to be critical; if it's too low //(e.g. < 120) some cards are no longer readable although they're ok @@ -69,7 +62,7 @@ // div #define EM4X50_TAG_WORD 45 #define EM4X50_TAG_MAX_NO_BYTES 136 -#define EM4X50_TIMEOUT_PULSE_EVAL 2500 +#define EM4X50_TIMEOUT_PULSE_EVAL (4 * EM4X50_T_TAG_FULL_PERIOD * CYCLES2TICKS) // 4bit data periods uint8_t g_High = 190; uint8_t g_Low = 60; @@ -136,7 +129,6 @@ static bool extract_parities(uint64_t word, uint32_t *data) { } void em4x50_setup_read(void) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); @@ -151,15 +143,14 @@ void em4x50_setup_read(void) { FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); // Steal this pin from the SSP (SPI communication channel with fpga) and // use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + gpio_fpga_mod_only_setup(); // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); // Watchdog hit WDT_HIT(); @@ -170,9 +161,7 @@ void em4x50_setup_sim(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + gpio_fpga_mod_feedback_setup(); StartTicks(); @@ -200,8 +189,10 @@ static bool get_signalproperties(void) { // about 2 samples per bit period WaitUS(EM4X50_T_TAG_HALF_PERIOD * CYCLES2MUSEC); + FPGA_SSC_RX_READY_WAIT(); + // ignore first samples - if ((i > SIGNAL_IGNORE_FIRST_SAMPLES) && (AT91C_BASE_SSC->SSC_RHR > noise)) { + if ((i > SIGNAL_IGNORE_FIRST_SAMPLES) && (FPGA_SSC_RX_Value() > noise)) { signal_found = true; break; } @@ -220,7 +211,9 @@ static bool get_signalproperties(void) { if (BUTTON_PRESS()) return false; - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + FPGA_SSC_RX_READY_WAIT(); + + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); if (sample > sample_max[i]) sample_max[i] = sample; @@ -247,7 +240,9 @@ static bool invalid_bit(void) { // get sample at 3/4 of bit period WaitUS(EM4X50_T_TAG_THREE_QUARTER_PERIOD * CYCLES2MUSEC); - uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + FPGA_SSC_RX_READY_WAIT(); + + uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); // wait until end of bit period WaitUS(EM4X50_T_TAG_QUARTER_PERIOD * CYCLES2MUSEC); @@ -261,36 +256,46 @@ static bool invalid_bit(void) { static uint32_t get_pulse_length(void) { - int32_t timeout = EM4X50_TIMEOUT_PULSE_EVAL, tval = 0; + uint64_t timeout = GetTicks() + EM4X50_TIMEOUT_PULSE_EVAL; // iterates pulse lengths (low -> high -> low) - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + FPGA_SSC_RX_READY_WAIT(); // Wait for valid data received. + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); - while (sample > g_Low && (timeout--)) - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + while (sample > g_Low && (GetTicks() < timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = (uint8_t)FPGA_SSC_RX_Value(); + } + } - if (timeout <= 0) + if (GetTicks() >= timeout) { return 0; + } - tval = GetTicks(); - timeout = EM4X50_TIMEOUT_PULSE_EVAL; + uint32_t start_ticks = GetTicks(); - while (sample < g_High && (timeout--)) - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + while (sample < g_High && (GetTicks() < timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = (uint8_t)FPGA_SSC_RX_Value(); + } + } - if (timeout <= 0) + if (GetTicks() >= timeout) { return 0; + } - timeout = EM4X50_TIMEOUT_PULSE_EVAL; - while (sample > g_Low && (timeout--)) - sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + while (sample > g_Low && (GetTicks() < timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = (uint8_t)FPGA_SSC_RX_Value(); + } + } - if (timeout <= 0) + if (GetTicks() >= timeout) { return 0; + } - return GetTicks() - tval; - + return GetTicks() - start_ticks; } // check if pulse length corresponds to given length @@ -309,22 +314,22 @@ static void em4x50_reader_send_bit(int bit) { // disable modulation (activate the field) for 7 cycles of carrier // period (Opt64) - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (GetTicks() - tval < 7 * CYCLES2TICKS); // enable modulation (drop the field) for remaining first // half of bit period - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); while (GetTicks() - tval < EM4X50_T_TAG_HALF_PERIOD * CYCLES2TICKS); // disable modulation for second half of bit period - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (GetTicks() - tval < EM4X50_T_TAG_FULL_PERIOD * CYCLES2TICKS); } else { // bit = "1" means disable modulation for full bit period - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (GetTicks() - tval < EM4X50_T_TAG_FULL_PERIOD * CYCLES2TICKS); } } @@ -903,7 +908,7 @@ void em4x50_read(const em4x50_data_t *etd, bool ledcontrol) { } if (ledcontrol) LEDsoff(); - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); lf_finalize(ledcontrol); reply_ng(CMD_LF_EM4X50_READ, status, (uint8_t *)words, EM4X50_TAG_MAX_NO_BYTES); } @@ -956,7 +961,7 @@ void em4x50_reader(bool ledcontrol) { } if (ledcontrol) LEDsoff(); - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); lf_finalize(ledcontrol); reply_ng(CMD_LF_EM4X50_READER, now, (uint8_t *)words, 4 * now); } @@ -1145,37 +1150,50 @@ void em4x50_writepwd(const em4x50_data_t *etd, bool ledcontrol) { reply_ng(CMD_LF_EM4X50_WRITEPWD, status, NULL, 0); } +// wait for ssc clk edge change to high, clk is from cross_lo +// mode: +// 1: wait to high +// 2: wait to low +// 3: wait to high & low +static void em4x50_sim_wait_edge(const int mode) { + uint32_t ticks_start; + if (mode & 0x01) { + ticks_start = GET_TICKS; // reset start time value + do { + if (GetTicksDelta(ticks_start) > EM4X50_T_SIMULATION_TIMEOUT_EDGE) { + // Dbprintf("timeout wait clk(1)"); + return; + } + } + while (!Gpio_SSC_CLK_Read()); // wait to high + } + if (mode & 0x02) { + ticks_start = GET_TICKS; // reset start time value + do { + if (GetTicksDelta(ticks_start) > EM4X50_T_SIMULATION_TIMEOUT_EDGE) { + // Dbprintf("timeout wait clk(2)"); + return; + } + } while (Gpio_SSC_CLK_Read()); // wait to low + } +} + // send bit in receive mode by counting carrier cycles static void em4x50_sim_send_bit(uint8_t bit) { - uint16_t timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; - for (int t = 0; t < EM4X50_T_TAG_FULL_PERIOD; t++) { - // wait until SSC_CLK goes HIGH - // used as a simple detection of a reader field? - while ((timeout--) && !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); - - if (timeout == 0) { - return; - } - timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; + em4x50_sim_wait_edge(1); if (bit) OPEN_COIL(); else SHORT_COIL(); - //wait until SSC_CLK goes LOW - while ((timeout--) && (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); - if (timeout == 0) { - return; - } - timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; + em4x50_sim_wait_edge(2); if (t == EM4X50_T_TAG_HALF_PERIOD) bit ^= 1; - } } @@ -1227,23 +1245,9 @@ static void em4x50_sim_send_word(uint32_t word) { // wait for pulses of carrier frequency static void wait_cycles(int maxperiods) { - - int period = 0, timeout = EM4X50_T_SIMULATION_TIMEOUT_WAIT; - + int period = 0; while (period < maxperiods) { - - while ((timeout--) && !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); - if (timeout <= 0) { - return; - } - timeout = EM4X50_T_SIMULATION_TIMEOUT_WAIT; - - while ((timeout--) && (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); - if (timeout <= 0) { - return; - } - timeout = EM4X50_T_SIMULATION_TIMEOUT_WAIT; - + em4x50_sim_wait_edge(3); period++; } } @@ -1252,7 +1256,6 @@ static void wait_cycles(int maxperiods) { static int em4x50_sim_read_bit(void) { int cycles = 0; - int timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; // wait 16 cycles to make sure there is no field when reading a "0" bit uint32_t waitval = GetTicks(); @@ -1260,18 +1263,24 @@ static int em4x50_sim_read_bit(void) { while (cycles < EM4X50_T_TAG_THREE_QUARTER_PERIOD) { + uint32_t timeout_start = GET_TICKS; + // wait until reader field disappears - while ((timeout--) && !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); - if (timeout <= 0) { - return PM3_ETIMEOUT; - } - timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; + do { + if (GetTicksDelta(timeout_start) >= EM4X50_T_SIMULATION_TIMEOUT_READ) { + DBG Dbprintf("read bit timeout(1): %d", GetTicksDelta(timeout_start)); + return PM3_ETIMEOUT; + } + } while (!Gpio_SSC_CLK_Read()); + + timeout_start = GET_TICKS; // now check until reader switches on carrier field uint32_t tval = GetTicks(); - while ((timeout--) && (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + while (Gpio_SSC_CLK_Read()) { - if (timeout <= 0) { + if (GetTicksDelta(timeout_start) >= EM4X50_T_SIMULATION_TIMEOUT_READ) { + DBG Dbprintf("read bit timeout(2): %d", GetTicksDelta(timeout_start)); return PM3_ETIMEOUT; } @@ -1279,11 +1288,12 @@ static int em4x50_sim_read_bit(void) { if (GetTicks() - tval > EM4X50_T_ZERO_DETECTION * CYCLES2TICKS) { // gap detected; wait until reader field is switched on again - while ((timeout--) && (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); - - if (timeout <= 0) { - return PM3_ETIMEOUT; - } + do { + if (GetTicksDelta(timeout_start) >= EM4X50_T_SIMULATION_TIMEOUT_READ) { + DBG Dbprintf("read bit timeout(3): %d", GetTicksDelta(timeout_start)); + return PM3_ETIMEOUT; + } + } while (Gpio_SSC_CLK_Read()); // now we have a reference "position", from here it will take // slightly less than 32 cycles until the end of the bit period @@ -1294,7 +1304,6 @@ static int em4x50_sim_read_bit(void) { return 0; } } - timeout = EM4X50_T_SIMULATION_TIMEOUT_READ; // no gap detected, i.e. reader field is still up; // continue with counting cycles diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 14a114e5b..bb20a9950 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -16,8 +16,9 @@ // Low frequency EM4x70 commands //----------------------------------------------------------------------------- -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "dbprint.h" #include "lfadc.h" #include "commonutil.h" @@ -222,7 +223,6 @@ static void init_tag(void) { } static void em4x70_setup_read(void) { - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); @@ -235,15 +235,14 @@ static void em4x70_setup_read(void) { FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); // Steal this pin from the SSP (SPI communication channel with fpga) and // use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + gpio_fpga_mod_only_setup(); // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); // Start the timer StartTicks(); @@ -263,7 +262,9 @@ static bool get_signalproperties(void) { // about 2 samples per bit period WaitTicks(EM4X70_T_TAG_HALF_PERIOD); - if (AT91C_BASE_SSC->SSC_RHR > HIGH_SIGNAL_THRESHOLD) { + FPGA_SSC_RX_READY_WAIT(); + + if (FPGA_SSC_RX_Value() > HIGH_SIGNAL_THRESHOLD) { return true; } } @@ -279,19 +280,35 @@ static uint32_t get_falling_pulse_length(void) { uint32_t timeout = GetTicks() + EM4X70_T_TAG_TIMEOUT; - while (IS_HIGH(AT91C_BASE_SSC->SSC_RHR) && !IS_TIMEOUT(timeout)); + FPGA_SSC_RX_READY_WAIT(); + + uint32_t sample = FPGA_SSC_RX_Value(); + + while (IS_HIGH(sample) && !IS_TIMEOUT(timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = FPGA_SSC_RX_Value(); + } + } if (IS_TIMEOUT(timeout)) return 0; uint32_t start_ticks = GetTicks(); - while (IS_LOW(AT91C_BASE_SSC->SSC_RHR) && !IS_TIMEOUT(timeout)); + while (IS_LOW(sample) && !IS_TIMEOUT(timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = FPGA_SSC_RX_Value(); + } + } if (IS_TIMEOUT(timeout)) return 0; - while (IS_HIGH(AT91C_BASE_SSC->SSC_RHR) && !IS_TIMEOUT(timeout)); + while (IS_HIGH(sample) && !IS_TIMEOUT(timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = FPGA_SSC_RX_Value(); + } + } if (IS_TIMEOUT(timeout)) return 0; @@ -308,19 +325,35 @@ static uint32_t get_rising_pulse_length(void) { uint32_t timeout = GetTicks() + EM4X70_T_TAG_TIMEOUT; - while (IS_LOW(AT91C_BASE_SSC->SSC_RHR) && !IS_TIMEOUT(timeout)); + FPGA_SSC_RX_READY_WAIT(); + + uint32_t sample = FPGA_SSC_RX_Value(); + + while (IS_LOW(sample) && !IS_TIMEOUT(timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = FPGA_SSC_RX_Value(); + } + } if (IS_TIMEOUT(timeout)) return 0; uint32_t start_ticks = GetTicks(); - while (IS_HIGH(AT91C_BASE_SSC->SSC_RHR) && !IS_TIMEOUT(timeout)); + while (IS_HIGH(sample) && !IS_TIMEOUT(timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = FPGA_SSC_RX_Value(); + } + } if (IS_TIMEOUT(timeout)) return 0; - while (IS_LOW(AT91C_BASE_SSC->SSC_RHR) && !IS_TIMEOUT(timeout)); + while (IS_LOW(sample) && !IS_TIMEOUT(timeout)) { + if (FPGA_SSC_RX_Ready()) { + sample = FPGA_SSC_RX_Value(); + } + } if (IS_TIMEOUT(timeout)) return 0; @@ -448,22 +481,22 @@ static void em4x70_send_bit(bool bit) { if (bit == 0) { // disable modulation (drop the field) n cycles of carrier - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (TICKS_ELAPSED(start_ticks) <= EM4X70_T_TAG_BITMOD); // enable modulation (activates the field) for remaining first // half of bit period - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); while (TICKS_ELAPSED(start_ticks) <= EM4X70_T_TAG_HALF_PERIOD); // disable modulation for second half of bit period - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (TICKS_ELAPSED(start_ticks) <= EM4X70_T_TAG_FULL_PERIOD); } else { // bit = "1" means disable modulation for full bit period - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (TICKS_ELAPSED(start_ticks) <= EM4X70_T_TAG_FULL_PERIOD); } log_sent_bit_end(GetTicks()); diff --git a/armsrc/emvsim.c b/armsrc/emvsim.c index 5b2c2b58e..605ec5244 100644 --- a/armsrc/emvsim.c +++ b/armsrc/emvsim.c @@ -43,13 +43,14 @@ #include "string.h" #include "mifareutil.h" #include "mifaresim.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "proxmark3_arm.h" #include "protocols.h" #include "util.h" #include "commonutil.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "i2c_direct.h" // Hardcoded response to the reader for file not found, plus the checksum diff --git a/armsrc/epa.c b/armsrc/epa.c index 583b59d8f..d2bdeb8dd 100644 --- a/armsrc/epa.c +++ b/armsrc/epa.c @@ -21,14 +21,15 @@ #include "epa.h" #include "cmd.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "iso14443a.h" #include "iso14443b.h" #include "string.h" #include "util.h" #include "dbprint.h" #include "commonutil.h" -#include "ticks.h" +#include "ticks_apis.h" #ifdef WITH_ISO14443a // Protocol and Parameter Selection Request for ISO 14443 type A cards diff --git a/armsrc/felica.c b/armsrc/felica.c index d6425b32c..95bab9990 100644 --- a/armsrc/felica.c +++ b/armsrc/felica.c @@ -19,11 +19,12 @@ #include "util.h" #include "protocols.h" #include "crc16.h" -#include "fpgaloader.h" +#include "fpga_loader.h" #include "string.h" #include "commonutil.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "iso18.h" #define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len)) @@ -416,8 +417,8 @@ void TransmitFor18092_AsReaderEx(const uint8_t *frame, uint16_t len, const uint3 uint16_t c = 0; while (c < 6) { // keep tx buffer in a defined state anyway. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(0x00); c++; } } @@ -426,17 +427,17 @@ void TransmitFor18092_AsReaderEx(const uint8_t *frame, uint16_t len, const uint3 while (c < len) { // Put byte into tx holding register as soon as it is ready - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = frame[c++]; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(frame[c++]); } } /**/ - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) {}; - AT91C_BASE_SSC->SSC_THR = 0x00; //minimum delay + while (!FPGA_SSC_TX_Ready()) {}; + FPGA_SSC_TX_Value(0x00); //minimum delay - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) {}; - AT91C_BASE_SSC->SSC_THR = 0x00; //spin + while (!FPGA_SSC_TX_Ready()) {}; + FPGA_SSC_TX_Value(0x00); //spin /**/ const uint32_t frame_start = felica_lasttime_prox2air_start + (FELICA_PREAMBLE_BYTES * FELICA_BITS_PER_BYTE); @@ -475,7 +476,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { FelicaFrameReset(&FelicaFrame); // clear RXRDY: - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + uint8_t b = (uint8_t)FPGA_SSC_RX_Value(); (void)b; uint32_t timeout = iso18092_get_timeout(); @@ -484,9 +485,9 @@ bool WaitForFelicaReply(uint16_t maxbytes) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + if (FPGA_SSC_RX_Ready()) { - b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); + b = (uint8_t)(FPGA_SSC_RX_Value()); Process18092Byte(&FelicaFrame, b, felica_get_rx_byte_start_time()); felica_frame_t *received = NULL; @@ -552,7 +553,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) { bool iso18092_setup_ex(uint8_t fpga_minor_mode, uint32_t preserve_low_bytes) { LEDsoff(); -#if defined XC3 +#if defined XC3 || defined PM5 FpgaDownloadAndGo(FPGA_BITSTREAM_HF); #else FpgaDownloadAndGo(FPGA_BITSTREAM_HF_FELICA); @@ -576,13 +577,13 @@ bool iso18092_setup_ex(uint8_t fpga_minor_mode, uint32_t preserve_low_bytes) { init_table(CRC_FELICA); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // Set up the synchronous serial port FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO18092); - // LSB transfer. Remember to set it back to MSB with - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + // RX LSB transfer. TX MSB transfer, Remember to set it(RX) back to MSB with + FpgaUpdateFrameMode(8, false, true); // Signal field is on with the appropriate LED FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | fpga_minor_mode); @@ -605,8 +606,8 @@ void iso18092_setup(uint8_t fpga_minor_mode) { void felica_reset_frame_mode(void) { switch_off(); felica_field_active = false; - //Resetting Frame mode (First set in fpgaloader.c) - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + // Resetting Frame mode (First set in FpgaSetupSsc() function) + FpgaUpdateFrameMode(8, true, true); } //----------------------------------------------------------------------------- @@ -780,9 +781,9 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { } ++checker; - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + if (FPGA_SSC_RX_Ready()) { - uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); + uint8_t dist = (uint8_t)FPGA_SSC_RX_Value(); Process18092Byte(&FelicaFrame, dist, felica_get_rx_byte_start_time()); if ((dist >= 178) && (++trigger_cnt > triggersToSkip)) { @@ -888,9 +889,9 @@ void felica_sim_lite(const uint8_t *uid) { if (listenmode) { // waiting for request... - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + if (FPGA_SSC_RX_Ready()) { - uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); + uint8_t dist = (uint8_t)(FPGA_SSC_RX_Value()); // frtm = GetCountSspClk(); Process18092Byte(&FelicaFrame, dist, felica_get_rx_byte_start_time()); diff --git a/armsrc/felicasim.c b/armsrc/felicasim.c index cb0f3ade2..4ad9216fc 100644 --- a/armsrc/felicasim.c +++ b/armsrc/felicasim.c @@ -21,11 +21,12 @@ #include "util.h" #include "protocols.h" #include "crc16.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "string.h" #include "commonutil.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "iso18.h" #define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len)) @@ -879,8 +880,8 @@ static int felica_sim_standard_loop(const felica_sim_model_header_t *hdr, const } ++checker; - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); + if (FPGA_SSC_RX_Ready()) { + uint8_t dist = (uint8_t)FPGA_SSC_RX_Value(); Process18092Byte(&FelicaFrame, dist, felica_get_rx_byte_start_time()); if (FelicaFrame.state == STATE_FULL) { diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h deleted file mode 100644 index 191120155..000000000 --- a/armsrc/fpgaloader.h +++ /dev/null @@ -1,182 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// See LICENSE.txt for the text of the license. -//----------------------------------------------------------------------------- -// Routines to load the FPGA image, and then to configure the FPGA's major -// mode once it is configured. -//----------------------------------------------------------------------------- -#ifndef __FPGALOADER_H -#define __FPGALOADER_H - -#include "common.h" -#include "fpga.h" - -#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; -#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; - -/* - Communication between ARM / FPGA is done inside armsrc/fpgaloader.c see: function FpgaSendCommand() - Send 16 bit command / data pair to FPGA with the bit format: - -+------ frame layout circa 2020 ------------------+ -| 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | -+-------------------------------------------------+ -| C C C C M M M M P P P P P P P P | C = FPGA_CMD_SET_CONFREG, M = FPGA_MAJOR_MODE_*, P = FPGA_LF_* or FPGA_HF_* parameter -| C C C C D D D D D D D D | C = FPGA_CMD_SET_DIVISOR, D = divisor -| C C C C T T T T T T T T | C = FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, T = threshold -| C C C C E | C = FPGA_CMD_TRACE_ENABLE, E=0 off, E=1 on -+-------------------------------------------------+ - -+------ frame layout current ---------------------+ -| 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | -+-------------------------------------------------+ -| C C C C M M M P P P P P P | C = FPGA_CMD_SET_CONFREG, M = FPGA_MAJOR_MODE_*, P = FPGA_LF_* or FPGA_HF_* parameter -| C C C C D D D D D D D D | C = FPGA_CMD_SET_DIVISOR, D = divisor -| C C C C T T T T T T T T | C = FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, T = threshold -| C C C C E | C = FPGA_CMD_TRACE_ENABLE, E=0 off, E=1 on -+-------------------------------------------------+ - - shift_reg receive this 16bit frame - - LF command - ---------- - shift_reg[15:12] == 4bit command - LF has three commands (FPGA_CMD_SET_CONFREG, FPGA_CMD_SET_DIVISOR, FPGA_CMD_SET_EDGE_DETECT_THRESHOLD) - Current commands uses only 2bits. We have room for up to 4bits of commands total (7). - - LF data - ------- - shift_reg[11:0] == 12bit data - lf data is divided into MAJOR MODES and configuration values. - - The major modes uses 3bits (0,1,2,3,7 | 000, 001, 010, 011, 111) - 000 FPGA_MAJOR_MODE_LF_READER = Act as LF reader (modulate) - 001 FPGA_MAJOR_MODE_LF_EDGE_DETECT = Simulate LF - 010 FPGA_MAJOR_MODE_LF_PASSTHRU = Passthrough mode, CROSS_LO line connected to SSP_DIN. SSP_DOUT logic level controls if we modulate / listening - 011 FPGA_MAJOR_MODE_LF_ADC = refactor hitag 2, clear ADC sampling - 111 FPGA_MAJOR_MODE_OFF = turn off sampling. - - Each one of this major modes can have options. Currently these two major modes uses options. - - FPGA_MAJOR_MODE_LF_READER - - FPGA_MAJOR_MODE_LF_EDGE_DETECT - - FPGA_MAJOR_MODE_LF_READER - ------------------------------------- - lf_field = 1bit (FPGA_LF_ADC_READER_FIELD) - - You can send FPGA_CMD_SET_DIVISOR to set with FREQUENCY the fpga should sample at - divisor = 8bits shift_reg[7:0] - - FPGA_MAJOR_MODE_LF_EDGE_DETECT - ------------------------------------------ - lf_ed_toggle_mode = 1bits - lf_ed_threshold = 8bits threshold defaults to 127 - - You can send FPGA_CMD_SET_EDGE_DETECT_THRESHOLD to set a custom threshold - lf_ed_threshold = 8bits threshold value. - - conf_word 12bits - conf_word[7:5] = 3bit major mode. - conf_word[0] = 1bit lf_field - conf_word[1] = 1bit lf_ed_toggle_mode - conf_word[7:0] = 8bit divisor - conf_word[7:0] = 8bit threshold - -*/ -// Defining commands, modes and options. This must be aligned to the definitions in fpga/define.v -#define FPGA_MAJOR_MODE_MASK 0x01C0 -#define FPGA_MINOR_MODE_MASK 0x003F - -// Definitions for the FPGA commands. -#define FPGA_CMD_SET_CONFREG (1<<12) -#define FPGA_CMD_SET_DIVISOR (2<<12) -#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD (3<<12) -#define FPGA_CMD_TRACE_ENABLE (2<<12) - -// Major modes -#define FPGA_MAJOR_MODE_LF_READER (0<<6) -#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<6) -#define FPGA_MAJOR_MODE_LF_PASSTHRU (2<<6) -#define FPGA_MAJOR_MODE_LF_ADC (3<<6) - -#define FPGA_MAJOR_MODE_HF_READER (0<<6) -#define FPGA_MAJOR_MODE_HF_SIMULATOR (1<<6) -#define FPGA_MAJOR_MODE_HF_ISO14443A (2<<6) -#define FPGA_MAJOR_MODE_HF_SNIFF (3<<6) -#define FPGA_MAJOR_MODE_HF_ISO18092 (4<<6) -#define FPGA_MAJOR_MODE_HF_GET_TRACE (5<<6) -#define FPGA_MAJOR_MODE_OFF (7<<6) - -// Options for LF_READER -#define FPGA_LF_ADC_READER_FIELD ( 1 ) - -// Options for LF_EDGE_DETECT -#define FPGA_LF_EDGE_DETECT_READER_FIELD ( 1 ) -#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE ( 2 ) - -// Options for the generic HF reader -#define FPGA_HF_READER_MODE_RECEIVE_IQ ( 0 ) -#define FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE ( 1 ) -#define FPGA_HF_READER_MODE_RECEIVE_PHASE ( 2 ) -#define FPGA_HF_READER_MODE_SEND_FULL_MOD ( 3 ) -#define FPGA_HF_READER_MODE_SEND_SHALLOW_MOD ( 4 ) -#define FPGA_HF_READER_MODE_SNIFF_IQ ( 5 ) -#define FPGA_HF_READER_MODE_SNIFF_AMPLITUDE ( 6 ) -#define FPGA_HF_READER_MODE_SNIFF_PHASE ( 7 ) -#define FPGA_HF_READER_MODE_SEND_JAM ( 8 ) -#define FPGA_HF_READER_MODE_SEND_SHALLOW_MOD_RDV4 ( 9 ) - -#define FPGA_HF_READER_SUBCARRIER_848_KHZ (0<<4) -#define FPGA_HF_READER_SUBCARRIER_424_KHZ (1<<4) -#define FPGA_HF_READER_SUBCARRIER_212_KHZ (2<<4) -#define FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ (3<<4) - -// Options for the HF simulated tag, how to modulate -#define FPGA_HF_SIMULATOR_NO_MODULATION ( 0 ) -#define FPGA_HF_SIMULATOR_MODULATE_BPSK ( 1 ) -#define FPGA_HF_SIMULATOR_MODULATE_212K ( 2 ) -#define FPGA_HF_SIMULATOR_MODULATE_424K ( 4 ) -#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT ( 5 ) - -// Options for ISO14443A -#define FPGA_HF_ISO14443A_SNIFFER ( 0 ) -#define FPGA_HF_ISO14443A_TAGSIM_LISTEN ( 1 ) -#define FPGA_HF_ISO14443A_TAGSIM_MOD ( 2 ) -#define FPGA_HF_ISO14443A_READER_LISTEN ( 3 ) -#define FPGA_HF_ISO14443A_READER_MOD ( 4 ) - -// Options for ISO18092 / Felica -#define FPGA_HF_ISO18092_FLAG_NOMOD ( 1 ) // 0001 disable modulation module -#define FPGA_HF_ISO18092_FLAG_424K ( 2 ) // 0010 should enable 414k mode (untested). No autodetect -#define FPGA_HF_ISO18092_FLAG_READER ( 4 ) // 0100 enables antenna power, to act as a reader instead of tag - -void FpgaSendCommand(uint16_t cmd, uint16_t v); -void FpgaWriteConfWord(uint16_t v); -void FpgaEnableTracing(void); -void FpgaDisableTracing(void); -void FpgaDownloadAndGo(int bitstream_target); -void FpgaDownloadAndGo_keep_EM(int bitstream_target); -// void FpgaGatherVersion(int bitstream_target, char *dst, int len); -void FpgaSetupSsc(uint16_t fpga_mode); -void SetupSpi(int mode); -bool FpgaSetupSscDma(uint8_t *buf, uint16_t len); -void Fpga_print_status(void); -int FpgaGetCurrent(void); -void FpgaResetBitstream(void); -void SetAdcMuxFor(uint32_t whichGpio); - -// extern and generel turn off the antenna method -void switch_off(void); - -#endif diff --git a/armsrc/hfops.c b/armsrc/hfops.c index df42c8685..1c38ae73a 100644 --- a/armsrc/hfops.c +++ b/armsrc/hfops.c @@ -23,8 +23,10 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" +#include "rssi_apis.h" #include "dbprint.h" #include "util.h" #include "commonutil.h" @@ -35,7 +37,7 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { BigBuf_Clear_ext(false); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // And put the FPGA in the appropriate mode @@ -55,8 +57,8 @@ int HfReadADC(uint32_t samplesCount, bool ledcontrol) { break; } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - volatile uint16_t sample = AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + volatile uint16_t sample = FPGA_SSC_RX_Value(); // FPGA side: // corr_i_out <= {2'b00, corr_amplitude[13:8]}; @@ -216,7 +218,7 @@ int HfSimulateTkm(const uint8_t *uid, uint8_t modulation, uint32_t timeout) { LED_C_ON(); FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K); FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); @@ -238,7 +240,7 @@ int HfSimulateTkm(const uint8_t *uid, uint8_t modulation, uint32_t timeout) { break; // in mV - int vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + uint32_t vHf = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF); if (vHf > MF_MINFIELDV) { if (field_on == false) { LED_A_ON(); @@ -256,8 +258,8 @@ int HfSimulateTkm(const uint8_t *uid, uint8_t modulation, uint32_t timeout) { SpinDelay(3); for (int i = 0; i < elen;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = data[i++]; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(data[i++]); } } } diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index 939ee4319..8a941811f 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -18,8 +18,9 @@ #include "hfsnoop.h" #include "proxmark3_arm.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "dbprint.h" #include "util.h" #include "fpga.h" @@ -28,8 +29,8 @@ static void RAMFUNC optimizedSniff(uint16_t *dest, uint16_t dsize) { while (dsize > 0) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - *dest = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); + if (FPGA_SSC_RX_Ready()) { + *dest = (uint16_t)(FPGA_SSC_RX_Value()); dest++; dsize -= sizeof(dsize); } @@ -40,8 +41,8 @@ static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, u uint32_t accum = (skipMode == HF_SNOOP_SKIP_MIN) ? 0xffffffff : 0; uint8_t ratioindx = 0; while (dsize > 0) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - volatile uint16_t val = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); + if (FPGA_SSC_RX_Ready()) { + volatile uint16_t val = (uint16_t)(FPGA_SSC_RX_Value()); switch (skipMode) { case HF_SNOOP_SKIP_MAX: if (accum < (val & 0xff)) @@ -95,13 +96,13 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // Set up the synchronous serial port FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SNIFF); // Setting Frame Mode For better performance on high speed data transfer. - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16); + FpgaUpdateFrameMode(16, false, false); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNIFF); SpinDelay(100); @@ -127,8 +128,8 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint } // check if trigger is reached - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - r = (uint16_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + r = (uint16_t)FPGA_SSC_RX_Value(); r = MAX(r & 0xFF, r >> 8); @@ -149,7 +150,7 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint // skip samples loop while (samplesToSkip != 0) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (FPGA_SSC_RX_Ready()) { samplesToSkip--; } } @@ -165,8 +166,8 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint } } - //Resetting Frame mode (First set in fpgaloader.c) - AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0); + // Resetting Frame mode (First set in FpgaSetupSsc() function) + FpgaUpdateFrameMode(8, true, true); LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); BigBuf_free(); @@ -182,25 +183,20 @@ void HfPlotDownload(void) { FpgaSetupSsc(FPGA_MAJOR_MODE_HF_GET_TRACE); - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) this_buf; // start transfer to this memory address - AT91C_BASE_PDC_SSC->PDC_RCR = PM3_CMD_DATA_SIZE; // transfer this many samples - ts->buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // Start DMA transfer + FpgaSetupSscRxDmaSingle(this_buf, PM3_CMD_DATA_SIZE); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_GET_TRACE); // let FPGA transfer its internal Block-RAM LED_B_ON(); for (size_t i = 0; i < FPGA_TRACE_SIZE; i += PM3_CMD_DATA_SIZE) { + size_t len = MIN(FPGA_TRACE_SIZE - i, PM3_CMD_DATA_SIZE); // prepare next DMA transfer: uint8_t *next_buf = ts->buf + ((i + PM3_CMD_DATA_SIZE) % (2 * PM3_CMD_DATA_SIZE)); - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = PM3_CMD_DATA_SIZE; + while (!FPGA_SSC_DMA_RX_Done()) {}; // wait for DMA transfer to complete - size_t len = MIN(FPGA_TRACE_SIZE - i, PM3_CMD_DATA_SIZE); - - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX))) {}; // wait for DMA transfer to complete + // The main buf has stopped receiving, so it needs to be refreshed. + FPGA_SSC_DMA_RX_Refresh_Single(next_buf, PM3_CMD_DATA_SIZE); reply_old(CMD_FPGAMEM_DOWNLOADED, i, len, FPGA_TRACE_SIZE, this_buf, len); this_buf = next_buf; diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index db71f9dce..e1483a20d 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -20,8 +20,9 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "fpga_apis.h" +#include "ticks_apis.h" #include "dbprint.h" #include "util.h" #include "lfadc.h" @@ -159,15 +160,15 @@ static void hitag_send_bit(int bit, bool ledcontrol) { // check datasheet if reader uses BiPhase? if (bit == 0) { // Manchester: Unloaded, then loaded |__--| - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_HALF_PERIOD); - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_FULL_PERIOD); } else { // Manchester: Loaded, then unloaded |--__| - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_HALF_PERIOD); - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while (AT91C_BASE_TC0->TC_CV < HITAG_T0 * HITAG_T_TAG_FULL_PERIOD); } if (ledcontrol) LED_A_OFF(); @@ -188,7 +189,7 @@ static void hitag_send_frame(const uint8_t *frame, size_t frame_len) { } // Drop the modulation - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); } */ @@ -1053,7 +1054,7 @@ void hitag_sniff(void) { // and analog mux selection. FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); // 125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); RELAY_OFF(); } @@ -1074,7 +1075,7 @@ void SniffHitag2(bool ledcontrol) { set_tracing(true); /* - lf_init(false, false, ledcontrol); + lf_init(LF_ADC_SNIFF, LF_ADC_WAV_REVERSED, ledcontrol); // no logging of the raw signal g_logging = true; @@ -1216,7 +1217,7 @@ void SniffHitag2(bool ledcontrol) { // and analog mux selection. FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); // 125Khz - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); RELAY_OFF(); // Configure output pin that is connected to the FPGA (for modulating) @@ -1224,7 +1225,7 @@ void SniffHitag2(bool ledcontrol) { // AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; // Disable modulation, we are going to eavesdrop, not modulate ;) -// LOW(GPIO_SSC_DOUT); +// Gpio_SSC_DOUT_Low(); // Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); @@ -1274,7 +1275,7 @@ void SniffHitag2(bool ledcontrol) { overflow = 0; // Find out if we are dealing with a rising or falling edge - rising_edge = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_FRAME) > 0; + rising_edge = (Gpio_SSC_FRAME_Read()) > 0; // Shorter periods will only happen with reader frames if (reader_frame == false && rising_edge && ra < HITAG_T_TAG_CAPTURE_ONE_HALF) { @@ -1430,7 +1431,7 @@ void SimulateHitag2(bool ledcontrol) { set_tracing(true); // empties bigbuff etc - lf_init(false, true, ledcontrol); + lf_init(LF_ADC_TAG_SIM, LF_ADC_WAV_REVERSED, ledcontrol); int response = 0; uint8_t rx[HITAG_FRAME_LEN] = {0}; @@ -1788,7 +1789,7 @@ void ReaderHitag(const lf_hitag_data_t *payload, bool ledcontrol) { } // init as reader - lf_init(true, false, ledcontrol); + lf_init(LF_ADC_READER, LF_ADC_WAV_REVERSED, ledcontrol); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); uint8_t tag_modulation; @@ -2127,7 +2128,7 @@ void WriterHitag(const lf_hitag_data_t *payload, bool ledcontrol) { hitag2_init(); // init as reader - lf_init(true, false, ledcontrol); + lf_init(LF_ADC_READER, LF_ADC_WAV_REVERSED, ledcontrol); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // Tag specific configuration settings (sof, timings, etc.) @@ -2591,6 +2592,7 @@ bool ht2_packbits(uint8_t *nrz_samples, size_t nrzs, uint8_t *rx, size_t *rxlen) } return true; } + int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_field_up) { g_logging = false; @@ -2600,12 +2602,11 @@ int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_fiel clear_trace(); } - // hitag 2 state machine? hitag2_init(); // init as reader - lf_init(true, false, true); + lf_init(LF_ADC_READER, LF_ADC_WAV_REVERSED, true); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -2642,7 +2643,7 @@ int ht2_read_uid(uint8_t *uid, bool ledcontrol, bool send_answer, bool keep_fiel // receive raw samples if (ht2_receive(&response_start, &response_duration, nrz_samples, &nrzs) == false) { - continue;; + continue; } // Store the transmit frame ( TX ), we do this now at this point, to avoid delay in processing diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index b1afc9f49..47bc32a35 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -24,8 +24,9 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "fpga_apis.h" +#include "ticks_apis.h" #include "dbprint.h" #include "util.h" #include "string.h" @@ -56,7 +57,7 @@ static int block_data_left = 0; static bool enable_page_tearoff = false; static uint8_t protocol_mode = HITAGS_UID_REQ_ADV1; -static MOD m = AC2K; // used modulation +static hitag_mod_t m = AC2K; // used modulation static uint32_t reader_selected_uid; static int rotate_uid = 0; static int sof_bits; // number of start-of-frame bits @@ -423,7 +424,7 @@ void hts_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, LogTraceBits(rx, rxlen, start_time, TIMESTAMP, true); // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + StopInputCapture(); // Process the incoming frame (rx) and prepare the outgoing frame (tx) hts_handle_reader_command(rx, rxlen, tx, &txlen); @@ -433,7 +434,7 @@ void hts_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) // periods. The gap time T_Low varies (4..10). All timer values are in // terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_RESP - HITAG_T_LOW)) {}; + while (GetPrecisionCounter() < T0 * (HITAG_T_WAIT_RESP - HITAG_T_LOW)) {}; // Send and store the tag answer (if there is any) if (txlen > 0) { @@ -444,7 +445,7 @@ void hts_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, } // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + EnableInputCapture(); // Reset the received frame and response timing info memset(rx, 0x00, sizeof(rx)); @@ -454,9 +455,9 @@ void hts_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, // Reset the frame length rxlen = 0; // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV / T0); + overflow += (GetInputCaptureCount() / T0); // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + ResetInputCapture(); } @@ -472,7 +473,7 @@ static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t // Send and store the reader command // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + StopInputCapture(); DBG Dbprintf("tx %d bits:", txlen); DBG Dbhexdump((txlen + 7) / 8, tx, false); @@ -482,7 +483,7 @@ static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t // falling edge occurred halfway the period. with respect to this falling edge, // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. // All timer values are in terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * t_wait) {}; + while (GetPrecisionCounter() < T0 * t_wait) {}; start_time = TIMESTAMP; @@ -496,7 +497,7 @@ static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t LogTraceBits(tx, txlen, start_time, TIMESTAMP, true); // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + EnableInputCapture(); hts_set_frame_modulation(protocol_mode, ac_seq); diff --git a/armsrc/hitag_common.c b/armsrc/hitag_common.c index e5af48f27..6fa3d2382 100644 --- a/armsrc/hitag_common.c +++ b/armsrc/hitag_common.c @@ -21,8 +21,9 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "fpga_apis.h" +#include "ticks_apis.h" #include "dbprint.h" #include "util.h" #include "string.h" @@ -33,7 +34,7 @@ #include "protocols.h" #include "appmain.h" // tearoff_hook() -uint16_t timestamp_high = 0; // Timer Counter 2 overflow count, combined with TC2 counter for ~47min timing +uint16_t timestamp_high = 0; // Timer Counter 2 overflow count, combined with TC2 counter for ~47min timing static void hitag_stop_clock(void) { AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; @@ -77,7 +78,7 @@ static void hitag_init_clock(void) { // synchronized startup procedure // In theory, with MCK/32, we shouldn't be waiting longer than 32 instruction statements, right? while (AT91C_BASE_TC0->TC_CV != 0) { - }; // wait until TC0 returned to zero + }; // wait until TC0 returned to zero // reset timestamp timestamp_high = 0; @@ -93,22 +94,23 @@ void hitag_setup_fpga(uint16_t conf, uint8_t threshold, bool ledcontrol) { set_tracing(true); clear_trace(); - if (ledcontrol) LED_D_ON(); + if (ledcontrol) { + LED_D_ON(); + } hitag_init_clock(); // Set fpga in edge detect with/without reader field, we can modulate as reader/tag now FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | conf); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz if (threshold != 127) FpgaSendCommand(FPGA_CMD_SET_EDGE_DETECT_THRESHOLD, threshold); - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); // Configure output and enable pin that is connected to the FPGA (for modulating) - AT91C_BASE_PIOA->PIO_OER |= GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER |= GPIO_SSC_DOUT; + gpio_fpga_mod_only_setup(); // Disable modulation at default, which means enable the field - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); } // Clean up and finalize Hitag operations @@ -118,348 +120,422 @@ void hitag_cleanup(bool ledcontrol) { lf_finalize(ledcontrol); } -// Reader functions -static void hitag_reader_send_bit(int bit, bool ledcontrol) { - // Reset clock for the next bit - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV != 0) {}; - - if (ledcontrol) LED_A_ON(); +/** + * Send data or condition to TAG + * + * This function will modulate a fixed length gap before modulating the data/condition of the specified period, + * and the number of periods of the data/condition modulated later will subtract the number of gaps. + * + * @param periods The numbers of periods for data/condition modulation + * @param ledcontrol Show the LED flash + */ +static RAMFUNC void hitag_reader_send_with_gap(int periods, bool ledcontrol) { + if (ledcontrol) + LED_A_ON(); // Binary puls length modulation (BPLM) is used to encode the data stream // This means that a transmission of a one takes longer than that of a zero - HIGH(GPIO_SSC_DOUT); - // Wait for 4-10 times the carrier period - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_LOW) {}; + // GPIOB->clr = GPIO_PINS_11; // TODO DXL 测试添加 - LOW(GPIO_SSC_DOUT); + // Send GAP + Gpio_SSC_DOUT_High(); + lf_wait_periods(HITAG_T_LOW); // Wait for 4-10 times the carrier period - if (bit == 0) { - // Zero bit: |_-| - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_0) {}; - } else { - // One bit: |_--| - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_1) {}; - } + // GPIOB->scr = GPIO_PINS_11; // TODO DXL 测试添加 - if (ledcontrol) LED_A_OFF(); + Gpio_SSC_DOUT_Low(); + lf_wait_periods(periods - HITAG_T_LOW); + + if (ledcontrol) + LED_A_OFF(); } void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool ledcontrol, bool send_sof) { // Send SOF (Start of Frame) for Hitag µ if requested if (send_sof) { - hitag_reader_send_bit(0, ledcontrol); - - // Reset clock for the code violation - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV != 0) {}; - - if (ledcontrol) LED_A_ON(); - - // SOF is HIGH for HITAG_T_LOW - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_LOW) {}; - - // Then LOW for HITAG_T_CODE_VIOLATION - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_CODE_VIOLATION) {}; - - if (ledcontrol) LED_A_OFF(); + // The RWD requests in the data exchange mode always a start with a SOF pattern for ease + // of synchronization. The SOF pattern consists of an encoded data bit ’0’ and a ’code violation’. + hitag_reader_send_with_gap(HITAG_T_0, ledcontrol); + // According to the manual description, the TFcv timing includes the TF1 timing, + // so it is necessary to subtract the TF1 timing(subtract inside the 'hitag_reader_send_with_gap'). + hitag_reader_send_with_gap(HITAG_T_CODE_VIOLATION, ledcontrol); } // Send the content of the frame for (size_t i = 0; i < frame_len; i++) { - hitag_reader_send_bit(TEST_BIT_MSB(frame, i), ledcontrol); + hitag_reader_send_with_gap(TEST_BIT_MSB(frame, i) ? HITAG_T_1 : HITAG_T_0, ledcontrol); } - // Send EOF - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV != 0) {}; - - HIGH(GPIO_SSC_DOUT); - - // Wait for 4-10 times the carrier period - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_LOW) {}; - - LOW(GPIO_SSC_DOUT); + // 36 + 8 = 44(t0), if you have the wait for 'twresp', the 'twresp' need to subtract HITAG_T_LOW + HITAG_T_STOP + // twresp include the gap + eof, max = 212(t0). + // The best way is not to block waiting for a response, + // Otherwise, there is a possibility of missing the card's response. + hitag_reader_send_with_gap(HITAG_T_STOP + HITAG_T_LOW, ledcontrol); } void hitag_reader_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol, - MOD modulation, int sof_bits) { + hitag_mod_t modulation, int sof_bits) { + bool sof_received = false; // Skip SOF bits in header + bool is_first_edge = true; + uint8_t lastbit = 1; + bool skip_next_failing_edge = true; + uint8_t error_count = 0; // Cannot exceed 255 times. + uint8_t t_4half, t_3half, t_2half; + size_t periods_rising_edge = 0; // for save the edge periods if is a rising edge + // Reset values for receiving frames memset(rx, 0x00, sizeofrx); *rxlen = 0; - int lastbit = 1; - bool bSkip = true; - uint32_t errorCount = 0; - bool bStarted = false; - uint16_t next_edge_event = AT91C_TC_LDRBS; - int double_speed = (modulation == AC4K || modulation == MC8K) ? 2 : 1; - - uint32_t rb_i = 0; + // For debug, if the development has been completed, + // please comment out the relevant definitions and calls to reduce resource usage. + int rb_i = 0; uint8_t edges[160] = {0}; - // Skip SOF bits - bool sof_received = false; + // Precalculate the number of periods at different modulation speeds. + if (modulation == AC4K || modulation == MC8K) { + t_4half = HITAG_T_TAG_CAPTURE_FOUR_HALF / 2; + t_3half = HITAG_T_TAG_CAPTURE_THREE_HALF / 2; + t_2half = HITAG_T_TAG_CAPTURE_TWO_HALF / 2; + } else { + t_4half = HITAG_T_TAG_CAPTURE_FOUR_HALF; + t_3half = HITAG_T_TAG_CAPTURE_THREE_HALF; + t_2half = HITAG_T_TAG_CAPTURE_TWO_HALF; + } - // Receive tag frame, watch for at most T0*HITAG_T_PROG_MAX periods - while (AT91C_BASE_TC0->TC_CV < (T0 * HITAG_T_PROG_MAX)) { - // Check if edge in tag modulation is detected - if (AT91C_BASE_TC1->TC_SR & next_edge_event) { - next_edge_event = next_edge_event ^ (AT91C_TC_LDRAS | AT91C_TC_LDRBS); - - // only use AT91C_TC_LDRBS falling edge for now - if (next_edge_event == AT91C_TC_LDRBS) { - continue; - } - - // Retrieve the new timing values - uint32_t rb = AT91C_BASE_TC1->TC_RB / T0; - edges[rb_i++] = rb; - - // Reset timer every frame, we have to capture the last edge for timing - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - - if (ledcontrol) LED_B_INV(); - - // Capture tag frame (manchester decoding using only falling edges) - if (bStarted == false) { - if (rb >= HITAG_T_WAIT_RESP) { - bStarted = true; - - // Capture tag response timestamp - *resptime = TIMESTAMP; - - // We always receive a 'one' first, which has the falling edge after a half period |-_| - rx[0] = 0x80; - *rxlen = 1; - } else { - errorCount++; - } - } else { - // Handle different modulation types - if (modulation == AC2K || modulation == AC4K) { - // Anticollision Coding - if (rb >= HITAG_T_TAG_CAPTURE_FOUR_HALF / double_speed) { - // Anticollision Coding example |--__|--__| (00) - lastbit = 0; - // CLEAR_BIT_MSB(rx, *rxlen); - (*rxlen)++; - } else if (rb >= HITAG_T_TAG_CAPTURE_THREE_HALF / double_speed) { - // Anticollision Coding example |-_-_|--__| (10) or |--__|-_-_| (01) - lastbit = !lastbit; - if (lastbit) { - SET_BIT_MSB(rx, *rxlen); - } - (*rxlen)++; - - bSkip = !!lastbit; - } else if (rb >= HITAG_T_TAG_CAPTURE_TWO_HALF / double_speed) { - // Anticollision Coding example |-_-_| (1) - if (bSkip == false) { - lastbit = 1; - SET_BIT_MSB(rx, *rxlen); - (*rxlen)++; - } - - bSkip = !bSkip; - } else { - // Ignore weird value, is to small to mean anything - errorCount++; - } - } else { - // Manchester coding (MC4K, MC8K) - if (rb >= HITAG_T_TAG_CAPTURE_FOUR_HALF / double_speed) { - // Manchester coding example |-_|_-|-_| (101) - // CLEAR_BIT_MSB(rx, *rxlen); - (*rxlen)++; - - SET_BIT_MSB(rx, *rxlen); - (*rxlen)++; - } else if (rb >= HITAG_T_TAG_CAPTURE_THREE_HALF / double_speed) { - // Manchester coding example |_-|...|_-|-_| (0...01) - // CLEAR_BIT_MSB(rx, *rxlen); - (*rxlen)++; - - // We have to skip this half period at start and add the 'one' the second time - if (bSkip == false) { - SET_BIT_MSB(rx, *rxlen); - (*rxlen)++; - } - - lastbit = !lastbit; - bSkip = !bSkip; - } else if (rb >= HITAG_T_TAG_CAPTURE_TWO_HALF / double_speed) { - // Manchester coding example |_-|_-| (00) or |-_|-_| (11) - // bit is same as last bit - if (lastbit) { - SET_BIT_MSB(rx, *rxlen); - } - (*rxlen)++; - } else { - // Ignore weird value, is to small to mean anything - errorCount++; - } - } - - // Handle SOF bits - if (sof_received == false && *rxlen >= sof_bits) { - // Check if SOF is valid (all bits should be 1) - if ((rx[0] >> (8 - sof_bits)) != ((1 << sof_bits) - 1)) { - if (sof_bits == 4) { - sof_bits = 3; - // Hitag µ is LSB first 0b110 - if ((rx[0] & 0xE0) != 0xC0) { - DBG Dbprintf("Warning, SOF is invalid rx[0]: 0x%02X", rx[0]); - } - } else { - DBG DbpString("Warning, not all bits of SOF are 1"); - } - } - - *rxlen -= sof_bits; - uint8_t tmp = rx[0]; - rx[0] = 0x00; - for (size_t i = 0; i < *rxlen; i++) { - if (TEST_BIT_MSB(&tmp, sof_bits + i)) { - SET_BIT_MSB(rx, i); - } - } - // DBG Dbprintf("after sof_bits rxlen: %d rx[0]: 0x%02X", *rxlen, rx[0]); - sof_received = true; - } - } - } - - // if we saw over 100 weird values break it probably isn't hitag... - if (errorCount > 100 || (*rxlen) / 8 >= sizeofrx) { + while (BUTTON_PRESS() == false) { + // Note: It is necessary to wait for at least N periods after the card is powered on and stabilized. + // Otherwise, an incorrect starting edge will be collected, resulting in a deviation in the periods calculation. + // So, it's best to wait for about 1000 periods. To wait for first response. + size_t periods = lf_count_edge_periods(1000); + if (periods == 0) { break; } - // We can break this loop if we received the last bit from a frame - // max periods between 2 falling edge - // RTF AC64 |--__|--__| (00) 64 * T0 - // RTF MC32 |_-|-_|_-| (010) 48 * T0 - if (AT91C_BASE_TC1->TC_CV > (T0 * 80)) { - if (bStarted) { - break; + // Capture tag frame (manchester decoding using only falling edges) + if (periods >= HITAG_T_WAIT_RESP - (HITAG_T_EOF + HITAG_T_LOW) && is_first_edge) { + *resptime = TIMESTAMP; // TODO DXL 待实现计算时间 + + // We always receive a 'one' first, which has the falling edge after a half period |-_| + rx[0] = 0x80; + *rxlen = 1; + + is_first_edge = false; + continue; + } + + // Only use falling edge for now + if (!lf_get_tag_modulation()) { + periods_rising_edge = periods; + continue; + } + + // We have obtained an effective falling edge, now we can calculate the number of periods. + periods += periods_rising_edge; + periods_rising_edge = 0; // reset periods of rising edge for next time detect + + if (rb_i < sizeof(edges)) { + // For debug, save the edges for decoding manual + edges[rb_i++] = periods; + } + + // if we saw over 100 weird values break it probably isn't hitag... + // Under some decoding conditions, two bits may be obtained, + // so it is necessary to ensure that the remaining buf space can store at least two bits. + if (error_count > 100 || (*rxlen + 2) >= sizeofrx * 8) { + DBG Dbprintf("hitag receive overflow or error!!"); + break; + } + + if (ledcontrol) + LED_B_INV(); + + if (modulation == AC2K || modulation == AC4K) { + // Handle different modulation types + // Anticollision Coding + if (periods >= t_4half) { + // Anticollision Coding example |--__|--__| (00) + lastbit = 0; + // CLEAR_BIT_MSB(rx, *rxlen); + (*rxlen)++; + } else if (periods >= t_3half) { + // Anticollision Coding example |-_-_|--__| (10) or |--__|-_-_| (01) + lastbit = !lastbit; + if (lastbit) { + SET_BIT_MSB(rx, *rxlen); + } + (*rxlen)++; + + skip_next_failing_edge = !!lastbit; + // Whether to skip the next falling edge depends on whether the current bit is 1 or not + } else if (periods >= t_2half) { + // Anticollision Coding example |-_-_| (1) + if (skip_next_failing_edge == false) { + lastbit = 1; + SET_BIT_MSB(rx, *rxlen); + (*rxlen)++; + } + + skip_next_failing_edge = !skip_next_failing_edge; + } else { + // Ignore weird value, is to small to mean anything + error_count++; } + } else { + // Manchester coding (MC4K, MC8K) + if (periods >= t_4half) { + // Manchester coding example |-_|_-|-_| (101) + + // CLEAR_BIT_MSB(rx, *rxlen); + (*rxlen)++; + // The function has already been reset to 0 when entering, so there is no need to operate clear + + SET_BIT_MSB(rx, *rxlen); + (*rxlen)++; + } else if (periods >= t_3half) { + // Manchester coding example |_-|...|_-|-_| (0...01) + + // CLEAR_BIT_MSB(rx, *rxlen); + (*rxlen)++; + // The function has already been reset to 0 when entering, so there is no need to operate clear + + // We have to skip this half period at start and add the 'one' the second time + if (skip_next_failing_edge == false) { + SET_BIT_MSB(rx, *rxlen); + (*rxlen)++; + } + + lastbit = !lastbit; + skip_next_failing_edge = !skip_next_failing_edge; + } else if (periods >= t_2half) { + // Manchester coding example |_-|_-| (00) or |-_|-_| (11) + // bit is same as last bit + if (lastbit) { + SET_BIT_MSB(rx, *rxlen); + } + (*rxlen)++; + } else { + // Ignore weird value, is to small to mean anything + error_count++; + } + } + + // Handle SOF bits + if (sof_received == false && *rxlen >= sof_bits) { + // Check if SOF is valid (all bits should be 1) + if ((rx[0] >> (8 - sof_bits)) != ((1 << sof_bits) - 1)) { + if (sof_bits == 4) { + sof_bits = 3; + // Hitag µ is LSB first 0b110 + if ((rx[0] & 0xE0) != 0xC0) { + DBG Dbprintf("Warning, SOF is invalid rx[0]: 0x%02X", rx[0]); + } + } else { + DBG Dbprintf("Warning, not all bits of SOF are 1: 0x%02X", rx[0]); + } + } + + *rxlen -= sof_bits; + uint8_t tmp = rx[0]; + rx[0] = 0x00; + for (size_t i = 0; i < *rxlen; i++) { + if (TEST_BIT_MSB(&tmp, sof_bits + i)) { + SET_BIT_MSB(rx, i); + } + } + // DBG Dbprintf("after sof_bits rxlen: %d rx[0]: 0x%02X", *rxlen, rx[0]); + sof_received = true; } } DBG { - Dbprintf("RX %i:%02X.. resptime:%i edges:", *rxlen, rx[0], *resptime); + Dbprintf("RX %i:%02X.. resptime:%i, sof_bits: %d", *rxlen, rx[0], *resptime, sof_bits); + Dbprintf("Edges count: %d, hex: ", rb_i); Dbhexdump(rb_i, edges, false); } } +int hitag_reader_transfer(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *rxlen, int t_wait, + bool ledcontrol, hitag_mod_t modulation, uint8_t sof_bits, uint8_t send_sof) { + uint32_t start_time = 0; + + DBG Dbprintf("tx %d bits:", txlen); + DBG Dbhexdump((txlen + 7) / 8, tx, false); + + // Wait for HITAG_T_WAIT_SC carrier periods after the last tag bit before transmitting, + // Since the clock counts since the last falling edge, a 'one' means that the + // falling edge occurred halfway the period. with respect to this falling edge, + // we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'. + // All timer values are in terms of T0 units + lf_wait_periods(t_wait); + + // TODO DXL 待实现计算时间 + // start_time = ? + + // Transmit the reader frame + hitag_reader_send_frame(tx, txlen, ledcontrol, send_sof); + + // tearoff + if (g_tearoff_enabled && tearoff_hook() == PM3_ETEAROFF) { + return PM3_ETEAROFF; + } + + LogTraceBits(tx, txlen, start_time, TIMESTAMP, true); + + hitag_reader_receive_frame(rx, sizeofrx, rxlen, &start_time, ledcontrol, modulation, sof_bits); + + DBG Dbprintf("rx %d bits:", *rxlen); + DBG Dbhexdump((int) (*rxlen + 7) / 8, rx, false); + + // Check if frame was captured and store it + if (*rxlen > 0) { + DBG { + uint8_t response_bit[sizeofrx * 8]; + + for (size_t i = 0; i < *rxlen; i++) { + response_bit[i] = (rx[i / 8] >> (7 - (i % 8))) & 1; + } + + Dbprintf("ht?: rxlen...... %zu", *rxlen); + Dbprintf("ht?: sizeofrx... %zu", sizeofrx); + DbpString("ht?: response_bit:"); + Dbhexdump((int) *rxlen, response_bit, false); + } + + LogTraceBits(rx, *rxlen, start_time, TIMESTAMP, false); + } + + return PM3_SUCCESS; +} + // Tag functions - depends on modulation type -static void hitag_tag_send_bit(int bit, MOD modulation, bool ledcontrol) { +static void hitag_tag_send_bit(int bit, hitag_mod_t modulation, bool ledcontrol) { // Reset clock for the next bit AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - if (ledcontrol) LED_A_ON(); + if (ledcontrol) + LED_A_ON(); switch (modulation) { case AC2K: { if (bit == 0) { // AC Coding --__ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 64) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 64) { + }; } else { // AC coding -_-_ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) { + }; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 48) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 48) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 64) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 64) { + }; } break; } case AC4K: { if (bit == 0) { // AC Coding --__ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_HALF_PERIOD) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_HALF_PERIOD) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_FULL_PERIOD) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * HITAG_T_TAG_FULL_PERIOD) { + }; } else { // AC coding -_-_ - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 8) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) { + }; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 24) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 24) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) { + }; } break; } case MC4K: { if (bit == 0) { // Manchester: Unloaded, then loaded |__--| - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) { + }; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) { + }; } else { // Manchester: Loaded, then unloaded |--__| - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 32) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 32) { + }; } break; } case MC8K: { if (bit == 0) { // Manchester: Unloaded, then loaded |__--| - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 8) { + }; - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) { + }; } else { // Manchester: Loaded, then unloaded |--__| - HIGH(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 8) {}; + Gpio_SSC_DOUT_High(); + while (AT91C_BASE_TC0->TC_CV < T0 * 8) { + }; - LOW(GPIO_SSC_DOUT); - while (AT91C_BASE_TC0->TC_CV < T0 * 16) {}; + Gpio_SSC_DOUT_Low(); + while (AT91C_BASE_TC0->TC_CV < T0 * 16) { + }; } break; } } - if (ledcontrol) LED_A_OFF(); + if (ledcontrol) + LED_A_OFF(); } -void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *start_time, bool ledcontrol, int *overflow) { +void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *start_time, bool ledcontrol, + int *overflow) { uint16_t next_edge_event = AT91C_TC_LDRBS; uint8_t edges[160] = {0}; uint32_t rb_i = 0; // Receive frame, watch for at most T0*EOF periods while (AT91C_BASE_TC1->TC_CV < T0 * HITAG_T_EOF) { - // Check if edge in modulation is detected if (AT91C_BASE_TC1->TC_SR & next_edge_event) { next_edge_event = next_edge_event ^ (AT91C_TC_LDRAS | AT91C_TC_LDRBS); @@ -473,7 +549,8 @@ void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32 edges[rb_i++] = rb; - if (ledcontrol) LED_B_INV(); + if (ledcontrol) + LED_B_INV(); // Capture reader cmd start timestamp if (*start_time == 0) { @@ -502,28 +579,33 @@ void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32 } } - if (ledcontrol) LED_B_OFF(); + if (ledcontrol) + LED_B_OFF(); - DBG if (rb_i) { - Dbprintf("RX %i bits.. start_time:%i edges:", *rxlen, *start_time); - Dbhexdump(rb_i, edges, false); - } + DBG + if (rb_i) { + Dbprintf("RX %i bits.. start_time:%i edges:", *rxlen, *start_time); + Dbhexdump(rb_i, edges, false); + } } -void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, MOD modulation, bool ledcontrol) { +void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, hitag_mod_t modulation, + bool ledcontrol) { // The beginning of the frame is hidden in some high level; pause until our bits will have an effect AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); switch (modulation) { case AC4K: case MC8K: { - while (AT91C_BASE_TC0->TC_CV < T0 * 40) {}; // FADV + while (AT91C_BASE_TC0->TC_CV < T0 * 40) { + }; // FADV break; } case AC2K: case MC4K: { - while (AT91C_BASE_TC0->TC_CV < T0 * 20) {}; // STD + ADV + while (AT91C_BASE_TC0->TC_CV < T0 * 20) { + }; // STD + ADV break; } } @@ -543,5 +625,5 @@ void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, hitag_tag_send_bit(TEST_BIT_MSB(frame, i), modulation, ledcontrol); } - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); } diff --git a/armsrc/hitag_common.h b/armsrc/hitag_common.h index 16a966240..d1d53d774 100644 --- a/armsrc/hitag_common.h +++ b/armsrc/hitag_common.h @@ -8,25 +8,33 @@ // Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) // T0 = TIMER_CLOCK3 / 125000 = 12 -#define T0 12 +#define T0 12 // 12 timer period ~= 8us #define HITAG_FRAME_LEN 20 // TC0 and TC1 are 16-bit counters and will overflow after 5461 * T0 // Ensure not to set these timings above 5461 (~43ms) when comparing without considering overflow, as they will never reach that value. +// Gap time between bits #define HITAG_T_LOW 8 /* T_LOW should be 4..10 */ +// Logic 0 Bit length #define HITAG_T_0 20 /* T[0] should be 18..22 */ +// Logic 1 Bit length #define HITAG_T_1 28 /* T[1] should be 26..32 */ #define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */ #define HITAG_T_1_MIN 25 /* T[1] should be 26..32 */ +// Duration for end of frame condition #define HITAG_T_STOP 36 /* T_EOF should be > 36 */ #define HITAG_T_CODE_VIOLATION 36 /* Hitag µ TFcv should be 34..38 */ #define HITAG_T_EOF 80 /* T_EOF should be > 36 */ #define HITAG_T_WAIT_RESP 200 /* T_wresp should be 204..212 */ + +// Read/Write Device waiting time before sending a subsequent command #define HITAG_T_WAIT_SC 200 /* T_wsc should be 90..5000 */ +// Read/Write Device waiting time before sending the first command #define HITAG_T_WAIT_FIRST 300 /* T_wfc should be 280..565 (T_ttf) */ +// HITAG S Transponder programming time #define HITAG_T_PROG_MAX 750 /* T_prog should be 716..726 */ #define HITAG_T_TAG_ONE_HALF_PERIOD 10 @@ -43,15 +51,18 @@ #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 extern uint16_t timestamp_high; -#define TIMESTAMP ( (AT91C_BASE_TC2->TC_SR & AT91C_TC_COVFS) ? timestamp_high += 1 : 0, ((timestamp_high << 16) + AT91C_BASE_TC2->TC_CV) / T0) +#define TIMESTAMP 0 // TODO DXL 时间戳暂时全部归零,后期时间计算手动完成 +// #define TIMESTAMP ( (AT91C_BASE_TC2->TC_SR & AT91C_TC_COVFS) ? timestamp_high += 1 : 0, ((timestamp_high << 16) + AT91C_BASE_TC2->TC_CV) / T0) // Common hitag functions void hitag_setup_fpga(uint16_t conf, uint8_t threshold, bool ledcontrol); void hitag_cleanup(bool ledcontrol); void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool ledcontrol, bool send_sof); -void hitag_reader_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol, MOD modulation, +void hitag_reader_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *resptime, bool ledcontrol, hitag_mod_t modulation, int sof_bits); +int hitag_reader_transfer(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *rxlen, int t_wait, + bool ledcontrol, hitag_mod_t modulation, uint8_t sof_bits, uint8_t send_sof); void hitag_tag_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint32_t *start_time, bool ledcontrol, int *overflow); -void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, MOD modulation, bool ledcontrol); +void hitag_tag_send_frame(const uint8_t *frame, size_t frame_len, int sof_bits, hitag_mod_t modulation, bool ledcontrol); #endif diff --git a/armsrc/hitagu.c b/armsrc/hitagu.c index 34e337803..b257671d9 100644 --- a/armsrc/hitagu.c +++ b/armsrc/hitagu.c @@ -14,6 +14,10 @@ // See LICENSE.txt for the text of the license. //----------------------------------------------------------------------------- // Low frequency HITAG µ (micro) functions +// HitagU. There are two frequency models, of which the 125kHz model has been discontinued. +// 125k clock: https://www.nxp.com/products/no-longer-manufactured/hitag-%CE%BC-iso18000-2-transponder-ic:HTMS8301FTK +// 134k clock: https://www.nxp.com/products/rfid-nfc/hitag-lf/hitag-%C2%B5-advanced-advanced-plus:HTMS1X01_HTMS8X01 +//----------------------------------------------------------------------------- #include "hitagu.h" #include "hitag_common.h" @@ -24,19 +28,19 @@ #include "commonutil.h" #include "crc16.h" #include "dbprint.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "hitag2/hitag2_crypto.h" -#include "lfadc.h" #include "protocols.h" #include "proxmark3_arm.h" #include "string.h" -#include "ticks.h" +#include "ticks_apis.h" #include "util.h" // Hitag µ specific definitions #define HTU_SOF_BITS 4 // Start of frame bits is always 3 for Hitag µ (110) plus 1 bit error flag -MOD M = MC4K; // Modulation type +hitag_mod_t M = MC4K; // Modulation type // Structure to hold the state of the Hitag µ tag static struct hitagU_tag tag = { @@ -414,7 +418,7 @@ void htu_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, LogTraceBits(rx, rxlen, start_time, TIMESTAMP, true); // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + StopInputCapture(); // Prepare tag response (tx) memset(tx, 0x00, sizeof(tx)); @@ -428,7 +432,7 @@ void htu_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, // with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low) // periods. The gap time T_Low varies (4..10). All timer values are in // terms of T0 units - while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_WAIT_RESP - HITAG_T_LOW)) { + while (GetPrecisionCounter() < T0 * (HITAG_T_WAIT_RESP - HITAG_T_LOW)) { }; // Send and store the tag answer (if there is any) @@ -440,7 +444,7 @@ void htu_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, } // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + EnableInputCapture(); // Reset the received frame and response timing info memset(rx, 0x00, sizeof(rx)); @@ -449,9 +453,9 @@ void htu_simulate(bool tag_mem_supplied, int8_t threshold, const uint8_t *data, // Reset the frame length rxlen = 0; // Save the timer overflow, will be 0 when frame was received - overflow += (AT91C_BASE_TC1->TC_CV / T0); + overflow += (GetInputCaptureCount() / T0); // Reset the timer to restart while-loop that receives frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; + ResetInputCapture(); } hitag_cleanup(ledcontrol); @@ -470,14 +474,13 @@ static int htu_reader_send_receive(uint8_t *tx, size_t txlen, uint8_t *rx, size_ memset(rx, 0x00, sizeofrx); // Disable timer 1 with external trigger to avoid triggers during our own modulation - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + StopInputCapture(); DBG Dbprintf("tx %d bits:", txlen); DBG Dbhexdump((txlen + 7) / 8, tx, false); // Wait until we can send the command - while (AT91C_BASE_TC0->TC_CV < T0 * t_wait) { - }; + while (GetPrecisionCounter() < T0 * t_wait) {}; // Set up tracing uint32_t start_time = TIMESTAMP; @@ -492,7 +495,7 @@ static int htu_reader_send_receive(uint8_t *tx, size_t txlen, uint8_t *rx, size_ LogTraceBits(tx, txlen, start_time, TIMESTAMP, true); // Enable and reset external trigger in timer for capturing future frames - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + EnableInputCapture(); // Capture response - SOF is automatically stripped by hitag_reader_receive_frame hitag_reader_receive_frame(rx, sizeofrx, rxlen, &start_time, ledcontrol, modulation, sof_bits); diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 4df227d18..323971975 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -20,38 +20,37 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "ticks.h" +#include "ticks_apis.h" #include "dbprint.h" #include "util.h" #include "string.h" -#define GPIO_RST AT91C_PIO_PA1 -#define GPIO_SCL AT91C_PIO_PA5 -#define GPIO_SDA AT91C_PIO_PA7 +#define SCL_H Gpio_I2C_SCL_High() +#define SCL_L Gpio_I2C_SCL_Low() +#define SDA_H Gpio_I2C_SDA_High() +#define SDA_L Gpio_I2C_SDA_Low() +#define RST_H Gpio_I2C_RST_High() +#define RST_L Gpio_I2C_RST_Low() -#define SCL_H HIGH(GPIO_SCL) -#define SCL_L LOW(GPIO_SCL) -#define SDA_H HIGH(GPIO_SDA) -#define SDA_L LOW(GPIO_SDA) - -#define SCL_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL) == GPIO_SCL) -#define SDA_read ((AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA) == GPIO_SDA) +#define SCL_read Gpio_I2C_SCL_Read() +#define SDA_read Gpio_I2C_SDA_Read() #define I2C_ERROR "I2C_WaitAck Error" -// Direct use the loop to delay. 6 instructions loop, Masterclock 48MHz, // delay=1 is about 200kbps -// timer. -// I2CSpinDelayClk(4) = 12.31us -// I2CSpinDelayClk(1) = 3.07us -static volatile uint32_t c; -static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { - for (c = delay * 2; c; c--) {}; -} +// I2CSpinDelayClk(4) about 12us +// I2CSpinDelayClk(1) about 3us +// static void I2CSpinDelayClk(const uint16_t delay) { +// for (uint16_t i = 0; i < delay; i++) { +// SpinDelayUsPrecision(2); +// } +// } -#define I2C_DELAY_1CLK I2CSpinDelayClk(1) -#define I2C_DELAY_2CLK I2CSpinDelayClk(2) -#define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) +// TODO DXL 修改了速度到比较慢的情况,测完需要改回来,原先是2和4 + +#define I2C_DELAY_1CLK SpinDelayUsPrecision(20) +#define I2C_DELAY_2CLK SpinDelayUsPrecision(22) +// #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x)) // try i2c bus recovery at 100kHz = 5us high, 5us low void I2C_recovery(void) { @@ -89,19 +88,7 @@ void I2C_recovery(void) { } void I2C_init(bool has_ticks) { - // Configure reset pin, close up pull up, push-pull output, default high - AT91C_BASE_PIOA->PIO_PPUDR = GPIO_RST; - AT91C_BASE_PIOA->PIO_MDDR = GPIO_RST; - - // Configure I2C pin, open up, open leakage - AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_SCL | GPIO_SDA); - AT91C_BASE_PIOA->PIO_MDER |= (GPIO_SCL | GPIO_SDA); - - // default three lines all pull up - AT91C_BASE_PIOA->PIO_SODR |= (GPIO_SCL | GPIO_SDA | GPIO_RST); - - AT91C_BASE_PIOA->PIO_OER |= (GPIO_SCL | GPIO_SDA | GPIO_RST); - AT91C_BASE_PIOA->PIO_PER |= (GPIO_SCL | GPIO_SDA | GPIO_RST); + gpio_sw_i2c_rst_setup(); if (has_ticks) { WaitMS(2); @@ -115,19 +102,19 @@ void I2C_init(bool has_ticks) { // set the reset state void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) { if (LineRST) - HIGH(GPIO_RST); + RST_H; else - LOW(GPIO_RST); + RST_L; if (LineSCK) - HIGH(GPIO_SCL); + SCL_H; else - LOW(GPIO_SCL); + SCL_L; if (LineSDA) - HIGH(GPIO_SDA); + SDA_H; else - LOW(GPIO_SDA); + SDA_L; } // Reset the SIM_Adapter, then enter the main program diff --git a/armsrc/i2c.h b/armsrc/i2c.h index be2ced3f4..ee0ba4c45 100644 --- a/armsrc/i2c.h +++ b/armsrc/i2c.h @@ -43,7 +43,7 @@ void I2C_recovery(void); void I2C_init(bool has_ticks); -void I2C_Reset(void); +void I2C_Reset(void); // TODO DXL: Not implemented but defined? void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA); void I2C_Reset_EnterMainProgram(void); diff --git a/armsrc/i2c_direct.c b/armsrc/i2c_direct.c index 096a5daa9..bdfe26823 100644 --- a/armsrc/i2c_direct.c +++ b/armsrc/i2c_direct.c @@ -23,7 +23,8 @@ #include "BigBuf.h" #include "string.h" #include "mifareutil.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "proxmark3_arm.h" #include "cmd.h" #include "protocols.h" @@ -32,7 +33,7 @@ #include "commonutil.h" #include "crc16.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "i2c.h" #include "i2c_direct.h" diff --git a/armsrc/iclass.c b/armsrc/iclass.c index e98e1f77e..c374d12ee 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -29,12 +29,13 @@ #include "appmain.h" #include "BigBuf.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "string.h" #include "util.h" #include "dbprint.h" #include "protocols.h" -#include "ticks.h" +#include "ticks_apis.h" #include "iso15693.h" #include "iclass_cmd.h" // iclass_card_select_t struct #include "i2c.h" // i2c defines (SIM module access) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index df4d73ea9..631ddc60d 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -24,8 +24,10 @@ #include "cmd.h" #include "appmain.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" +#include "rssi_apis.h" #include "dbprint.h" #include "util.h" #include "parity.h" @@ -37,7 +39,7 @@ #include "desfire_crypto.h" // UL-C authentication helpers #include "mifare.h" // for iso14a_polling_frame_t structure #include "cmac_calc.h" -#include "usb_cdc.h" +#include "usb_cdc_apis.h" // Forward declaration: HID Config Card jam support (implemented in secc.c). // Called from SniffIso14443a when param bit 0x04 is set. @@ -45,8 +47,6 @@ bool hid_config_card_jam(const uint8_t *cmd, int len, uint8_t *dma_buf); static uint32_t iso14a_timeout; -static uint8_t colpos = 0; - // the block number for the ISO14443-4 PCB static uint8_t iso14_pcb_blocknum = 0; @@ -845,8 +845,8 @@ void RAMFUNC SniffIso14443a(uint8_t param) { uint8_t *data = dma->buf; // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); + if (FpgaSetupSscRxDmaRepeat((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); return; } @@ -875,7 +875,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { } register int readBufDataP = data - dma->buf; - register int dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + register int dmaBufDataP = DMA_BUFFER_SIZE - FPGA_SSC_DMA_RX_Remaining_Count(); if (readBufDataP <= dmaBufDataP) { dataLen = dmaBufDataP - readBufDataP; } else { @@ -886,6 +886,11 @@ void RAMFUNC SniffIso14443a(uint8_t param) { maxDataLen = dataLen; } + // TODO DXL This cross platform issue needs to be addressed + // When the current buffer address is zeroed, it usually means the next buffer hasn't been assigned a value in time, + // indicating that the MCU's processing speed is slow. + // The logic here is to reset the state machine to receive data again. + // DMA fully stalled: both buffers exhausted. Re-arm primary + secondary, // resync the read pointer, and drop the in-flight frame. if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { @@ -918,6 +923,13 @@ void RAMFUNC SniffIso14443a(uint8_t param) { continue; } + /** + * TODO DXL This problem needs to be addressed. + * if (FPGA_SSC_DMA_RX_Done()) { + * FPGA_SSC_DMA_RX_Refresh_Repeat(dma->buf, DMA_BUFFER_SIZE); + * } + */ + // secondary buffer exhausted, primary still running — refill secondary if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; @@ -929,6 +941,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { // Need two samples to feed Miller and Manchester-Decoder if (rx_samples & 0x01) { + // Reader -> Tag // no need to try decoding reader data if the tag is sending if (TagIsActive == false) { @@ -967,6 +980,7 @@ void RAMFUNC SniffIso14443a(uint8_t param) { ReaderIsActive = (Uart.state != STATE_14A_UNSYNCD); } + // Tag -> Reader // no need to try decoding tag data if the reader is sending - and we cannot afford the time if (ReaderIsActive == false) { @@ -1151,7 +1165,7 @@ bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, Uart14aInit(received, received_maxlen, par); // clear RXRDY: - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + uint8_t b = (uint8_t)FPGA_SSC_RX_Value(); (void)b; uint8_t flip = 0; @@ -1180,8 +1194,8 @@ bool GetIso14443aCommandFromReader(uint8_t *received, uint16_t received_maxlen, checker = 4000; } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + b = (uint8_t)FPGA_SSC_RX_Value(); if (MillerDecoding(b, 0)) { *len = Uart.len; return true; @@ -2597,7 +2611,6 @@ static void PrepareDelayedTransfer(uint16_t delay) { } } - //------------------------------------------------------------------------------------- // Transmit the command (to the tag) that was placed in ToSend[]. // Parameter timing: @@ -2613,7 +2626,10 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing return; } - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + // DXL: If the mode is set to FPGA_MAJOR_MODE_OFF before transmission, the timing wait will freeze. + // If you need to handle this situation, you can uncomment the code below(SPEED is affected). + // And do not use the FPGA_HF_ISO14443A_READER_MOD!!! + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN); if (timing) { @@ -2632,14 +2648,28 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing ThisTransferTime = ((MAX(NextTransferTime, GetCountSspClk()) & 0xfffffff8) + 8); while (GetCountSspClk() < ThisTransferTime) {}; - LastTimeProxToAirStart = ThisTransferTime; + } + // DXL: Switch to this mode before actually starting to send. Otherwise, it may cause delays between frames to fail. + // 14b also has this problem, which requires waiting for the frame delay to complete + // before switching to modulation transmission mode to send data. + // If we don't do this, there is a possibility of randomly encountering communication exception bugs + // on high-performance processors such as AT32, which is very fatal! + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + + // If the transmission is not cleared, there is a high probability of communication abnormalities. + // I suspect that the wrong DOUT level may have modulated data that should not have been modulated. + // If further research is needed, an oscilloscope needs to be used to observe the specific DOUT modulation status. + // --- + // Clear TXRDY: + FPGA_SSC_TX_Value(SEC_Y); + uint16_t c = 0; while (c < len) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = cmd[c]; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(cmd[c]); c++; } } @@ -2750,23 +2780,13 @@ int EmGetCmd(uint8_t *received, uint16_t received_max_len, uint16_t *len, uint8_ LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN); - // Set ADC to read field strength - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; - AT91C_BASE_ADC->ADC_MR = - ADC_MODE_PRESCALE(63) | - ADC_MODE_STARTUP_TIME(1) | - ADC_MODE_SAMPLE_HOLD_TIME(15); - - AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF); - - // start ADC - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + AdcSetupRssiChannel(ADC_RSSI_CH_HF); // Now run a 'software UART' on the stream of incoming samples. Uart14aInit(received, received_max_len, par); // Clear RXRDY: - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + uint8_t b = (uint8_t)FPGA_SSC_RX_Value(); (void)b; uint8_t flip = 0; @@ -2802,17 +2822,17 @@ int EmGetCmd(uint8_t *received, uint16_t received_max_len, uint16_t *len, uint8_ // test if the field exists - if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { + if (AdcRssiDataReady(ADC_RSSI_CH_HF)) { analogCnt++; - analogAVG += (AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF] & 0x3FF); + analogAVG += AdcRssiDataRead(ADC_RSSI_CH_HF); - AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + AdcRssiConversionStart(); if (analogCnt >= 32) { - if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { + if (AdcRssiDataToMilliVolt(analogAVG / analogCnt, ADC_RSSI_CH_HF) < MF_MINFIELDV) { if (timer == 0) { timer = GetTickCount(); @@ -2831,8 +2851,8 @@ int EmGetCmd(uint8_t *received, uint16_t received_max_len, uint16_t *len, uint8_ } // receive and test the miller decoding - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + b = (uint8_t)FPGA_SSC_RX_Value(); if (MillerDecoding(b, 0)) { *len = Uart.len; return 0; @@ -2862,14 +2882,14 @@ int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen) { i = (correction_needed) ? 0 : 1; // clear receiving shift register and holding register - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); - b = AT91C_BASE_SSC->SSC_RHR; + FPGA_SSC_RX_READY_WAIT(); + b = FPGA_SSC_RX_Value(); (void) b; // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); - if (AT91C_BASE_SSC->SSC_RHR) { + FPGA_SSC_RX_READY_WAIT(); + if (FPGA_SSC_RX_Value()) { break; } } @@ -2877,22 +2897,24 @@ int EmSendCmd14443aRaw(const uint8_t *resp, uint16_t respLen) { while ((ThisTransferTime = GetCountSspClk()) & 0x00000007); // Clear TXRDY: - AT91C_BASE_SSC->SSC_THR = SEC_F; + FPGA_SSC_TX_Value(SEC_F); // send cycle for (; i < respLen;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = resp[i++]; - FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(resp[i++]); + FPGA_SSC_RX_READY_WAIT(); + FpgaSendQueueDelay = (uint8_t)FPGA_SSC_RX_Value(); } } // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again: uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3; for (i = 0; i <= (fpga_queued_bits >> 3) + 1;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = SEC_F; - FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(SEC_F); + FPGA_SSC_RX_READY_WAIT(); + FpgaSendQueueDelay = (uint8_t)FPGA_SSC_RX_Value(); i++; } } @@ -3014,7 +3036,7 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t rec_ Demod14aInit(receivedResponse, rec_maxlen, NULL); // clear RXRDY: - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + uint8_t b = (uint8_t)FPGA_SSC_RX_Value(); (void)b; uint32_t timeout = iso14a_get_timeout(); @@ -3023,8 +3045,8 @@ bool GetIso14443aAnswerFromTag_Thinfilm(uint8_t *receivedResponse, uint16_t rec_ for (;;) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + b = (uint8_t)FPGA_SSC_RX_Value(); if (ManchesterDecoding_Thinfilm(b)) { *received_len = Demod.len; LogTrace(receivedResponse, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, NULL, false); @@ -3064,7 +3086,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint16_t rec_max Demod14aInit(receivedResponse, rec_maxlen, receivedResponsePar); // clear RXRDY: - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + uint8_t b = (uint8_t)FPGA_SSC_RX_Value(); (void)b; volatile uint32_t c = 0; @@ -3073,8 +3095,8 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint16_t rec_max for (;;) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + b = (uint8_t)FPGA_SSC_RX_Value(); if (ManchesterDecoding(b, offset, 0)) { NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FRAME_DELAY_TIME_PICC_TO_PCD); return true; @@ -3186,11 +3208,9 @@ void iso14443a_antifuzz(uint32_t flags) { resp[2] = 0xFF; resp[3] = 0xFF; resp[4] = resp[0] ^ resp[1] ^ resp[2] ^ resp[3]; - colpos = 0; if (IS_FLAG_UID_IN_DATA(flags, 7)) { resp[0] = MIFARE_SELECT_CT; - colpos = 8; } // trigger a faulty/collision response @@ -3635,7 +3655,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) { // Set up the synchronous serial port FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); LED_D_OFF(); // Signal field is on with the appropriate LED diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 237dbb57c..e719470c9 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -29,10 +29,12 @@ #include "appmain.h" #include "BigBuf.h" #include "cmd.h" -#include "fpgaloader.h" +#include "fpga_loader.h" #include "commonutil.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" +#include "fpga_apis.h" +#include "rssi_apis.h" #include "iso14b.h" // defines for ETU conversions #include "iclass.h" // picopass buffer defines @@ -714,8 +716,8 @@ static bool GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) { while (BUTTON_PRESS() == false) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + uint8_t b = (uint8_t)FPGA_SSC_RX_Value(); for (uint8_t mask = 0x80; mask != 0x00; mask >>= 1) { if (Handle14443bSampleFromReader(b & mask)) { *len = Uart.byteCnt; @@ -742,8 +744,8 @@ static void TransmitFor14443b_AsTag(const uint8_t *response, uint16_t len) { for (uint16_t i = 0; i < len;) { // Put byte into tx holding register as soon as it is ready - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = response[i++]; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(response[i++]); // Start-up SSC once first byte is in SSC_THR if (i == 1) { @@ -774,7 +776,7 @@ void SimulateIso14443bTag(const uint8_t *pupi) { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // Set up the synchronous serial port FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); @@ -837,7 +839,7 @@ void SimulateIso14443bTag(const uint8_t *pupi) { } // find reader field - vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + vHf = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF); if (vHf > MF_MINFIELDV) { if (cardSTATE == SIM_POWER_OFF) { cardSTATE = SIM_IDLE; @@ -1002,7 +1004,7 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // Set up the synchronous serial port FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); @@ -1045,7 +1047,7 @@ void Simulate_iso14443b_srx_tag(uint8_t *uid) { // find reader field if (cardSTATE == SIM_NOFIELD) { - vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + vHf = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF); if (vHf > MF_MINFIELDV) { cardSTATE = SIM_IDLE; LED_A_ON(); @@ -1378,8 +1380,8 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t return PM3_EMALLOC; } - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); + if (FpgaSetupSscRxDmaRepeat((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); return PM3_EMALLOC; } @@ -1395,7 +1397,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t for (;;) { - volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); + volatile uint16_t behindBy = ((uint16_t *)FPGA_SSC_DMA_RX_Current_Address() - upTo) & (DMA_BUFFER_SIZE - 1); if (behindBy == 0) { WDT_HIT(); if (BUTTON_PRESS()) { @@ -1429,18 +1431,9 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t upTo = dma->buf; // DMA Counter Register had reached 0, already rotated. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { + if (FPGA_SSC_DMA_RX_Done()) { - // primary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + FPGA_SSC_DMA_RX_Refresh_Repeat(dma->buf, DMA_BUFFER_SIZE); WDT_HIT(); if (BUTTON_PRESS()) { @@ -1451,7 +1444,6 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t } if (Handle14443bSamplesFromTag(ci, cq)) { - // Response timing is measured from DMA start, but trace rows use // absolute SSP time like reader frames. uint32_t eof_delta = GetCountSspClkDelta(dma_start_time); @@ -1472,7 +1464,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t } } - FpgaDisableSscDma(); + FPGA_SSC_DMA_RX_Disable(); if (ret < 0) { return ret; } @@ -1492,6 +1484,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, uint32_t if (retlen) { *retlen = Demod.len; } + return PM3_SUCCESS; } @@ -1503,28 +1496,33 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) { tosend_t *ts = get_tosend(); -#ifdef RDV4 + // TODO DXL 可能此函数会被 Get14443bAnswerFromTag 的改动所影响,需要进行测试。 + + // TR2 minimum 14 ETUs + if (*start_time < ISO14B_TR0) { + // *start_time = DELAY_ARM_TO_TAG; + *start_time = ISO14B_TR0; + } + // *start_time = (*start_time - DELAY_ARM_TO_TAG) & 0xfffffff0; + *start_time = (*start_time & 0xfffffff0); + if (GetCountSspClk() > *start_time) { // we may miss the intended time + *start_time = (GetCountSspClk() + 32) & 0xfffffff0; // next possible time + } + // waiting for T2(minimum delay between two frames) + while (GetCountSspClk() < *start_time) {} + + // DXL: It is best to perform a clearance once. + FPGA_SSC_TX_Clear(); + + // DXL: + // We only switch to the transmission modulation mode before starting the transmission, and before that, + // we may still be delaying and waiting for T2 (14 ETUs) between two frames +#if defined RDV4 || defined PM5 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD_RDV4); #else FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); #endif - // TR2 minimum 14 ETUs - if (*start_time < ISO14B_TR0) { -// *start_time = DELAY_ARM_TO_TAG; - *start_time = ISO14B_TR0; - } - -// *start_time = (*start_time - DELAY_ARM_TO_TAG) & 0xfffffff0; - *start_time = (*start_time & 0xfffffff0); - - if (GetCountSspClk() > *start_time) { // we may miss the intended time - *start_time = (GetCountSspClk() + 32) & 0xfffffff0; // next possible time - } - - // wait - while (GetCountSspClk() < *start_time); - LED_B_ON(); for (int c = 0; c < ts->max; c++) { volatile uint8_t data = ts->buf[c]; @@ -1532,11 +1530,11 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) { for (uint8_t i = 0; i < 8; i++) { volatile uint16_t send_word = (data & 0x80) ? 0x0000 : 0xFFFF; - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; - AT91C_BASE_SSC->SSC_THR = send_word; + while (!FPGA_SSC_TX_Ready()) ; + FPGA_SSC_TX_Value(send_word); - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; - AT91C_BASE_SSC->SSC_THR = send_word; + while (!FPGA_SSC_TX_Ready()) ; + FPGA_SSC_TX_Value(send_word); data <<= 1; } @@ -1550,23 +1548,25 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) { for (uint8_t i = 0; i < last_bits; i++) { volatile uint16_t send_word = (data & 0x80) ? 0x0000 : 0xFFFF; - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; - AT91C_BASE_SSC->SSC_THR = send_word; + while (!FPGA_SSC_TX_Ready()) ; + FPGA_SSC_TX_Value(send_word); - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; - AT91C_BASE_SSC->SSC_THR = send_word; + while (!FPGA_SSC_TX_Ready()) ; + FPGA_SSC_TX_Value(send_word); data <<= 1; } + + // DXL: Very important!!! If not cleared, ST25 will always fail communication on at32 platform. + FPGA_SSC_TX_Clear(); + WDT_HIT(); - - LED_B_OFF(); // *start_time += DELAY_ARM_TO_TAG; // wait for last transfer to complete - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) {}; + while (!FPGA_SSC_TX_Done()) {}; } static uint32_t ToSendBitCount(const tosend_t *ts) { @@ -2457,13 +2457,13 @@ void iso14443b_setup(void) { Uart14bInit(BigBuf_calloc(MAX_FRAME_SIZE)); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // Set up the synchronous serial port FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // Signal field is on with the appropriate LED -#ifdef RDV4 +#if defined RDV4 || defined PM5 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD_RDV4); #else FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD); @@ -2594,7 +2594,7 @@ void SniffIso14443b(void) { // FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_SNIFF_AMPLITUDE); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); StartCountSspClk(); @@ -2603,8 +2603,8 @@ void SniffIso14443b(void) { dmabuf16_t *dma = get_dma16(); // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) DbpString("FpgaSetupSscDma failed. Exiting"); + if (FpgaSetupSscRxDmaRepeat((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) DbpString("FpgaSetupSscRxDmaRepeat failed. Exiting"); switch_off(); return; } @@ -2615,7 +2615,7 @@ void SniffIso14443b(void) { bool tag_is_active = false; bool reader_is_active = false; bool expect_tag_answer = false; - int dma_start_time = 0; + uint32_t dma_start_time = 0; // Count of samples received so far, so that we can include timing int samples = 0; @@ -2624,7 +2624,7 @@ void SniffIso14443b(void) { for (;;) { - volatile int behind_by = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); + volatile int behind_by = ((uint16_t *)FPGA_SSC_DMA_RX_Current_Address() - upTo) & (DMA_BUFFER_SIZE - 1); if (behind_by < 1) continue; samples++; @@ -2644,18 +2644,9 @@ void SniffIso14443b(void) { upTo = dma->buf; // DMA Counter Register had reached 0, already rotated. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { + if (FPGA_SSC_DMA_RX_Done()) { - // primary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + FPGA_SSC_DMA_RX_Refresh_Repeat(dma->buf, DMA_BUFFER_SIZE); WDT_HIT(); if (BUTTON_PRESS()) { @@ -2782,7 +2773,7 @@ static void tearoff_field_on(void) { Demod14bInit(BigBuf_calloc(MAX_FRAME_SIZE), MAX_FRAME_SIZE); Uart14bInit(BigBuf_calloc(MAX_FRAME_SIZE)); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // programs PDC with fresh BigBuf address #ifdef RDV4 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD_RDV4); diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index e8b82c241..276640305 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -69,9 +69,11 @@ #include "cmd.h" #include "appmain.h" #include "dbprint.h" -#include "fpgaloader.h" +#include "fpga_loader.h" #include "commonutil.h" -#include "ticks.h" +#include "ticks_apis.h" +#include "fpga_apis.h" +#include "rssi_apis.h" #include "BigBuf.h" #include "crc16.h" @@ -300,7 +302,7 @@ void CodeIso15693AsTag(const uint8_t *cmd, size_t len) { // Transmit the command (to the tag) that was placed in cmd[]. void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time, bool shallow_mod) { -#ifdef RDV4 +#if defined RDV4 || defined PM5 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | (shallow_mod ? FPGA_HF_READER_MODE_SEND_SHALLOW_MOD_RDV4 : FPGA_HF_READER_MODE_SEND_FULL_MOD)); #else FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | (shallow_mod ? FPGA_HF_READER_MODE_SEND_SHALLOW_MOD : FPGA_HF_READER_MODE_SEND_FULL_MOD)); @@ -328,11 +330,11 @@ void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time, bool for (uint8_t i = 0; i < 8; i++) { uint16_t send_word = (data & 0x80) ? 0xffff : 0x0000; - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; - AT91C_BASE_SSC->SSC_THR = send_word; + while (!FPGA_SSC_TX_Ready()) ; + FPGA_SSC_TX_Value(send_word); - while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ; - AT91C_BASE_SSC->SSC_THR = send_word; + while (!FPGA_SSC_TX_Ready()) ; + FPGA_SSC_TX_Value(send_word); data <<= 1; } @@ -379,9 +381,9 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint8_t cmd_bits = ((cmd[c] >> i) & 0x01) ? 0xff : 0x00; for (int j = 0; j < (slow ? 4 : 1);) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + if (FPGA_SSC_TX_Ready()) { bits_to_send = bits_to_shift << (8 - shift_delay) | cmd_bits >> shift_delay; - AT91C_BASE_SSC->SSC_THR = bits_to_send; + FPGA_SSC_TX_Value(bits_to_send); bits_to_shift = cmd_bits; j++; } @@ -394,8 +396,8 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, bits_to_send = bits_to_shift << (8 - shift_delay); if (bits_to_send) { for (; ;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = bits_to_send; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(bits_to_send); break; } } @@ -1018,7 +1020,7 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo } // wait for last transfer to complete - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)); + while (!FPGA_SSC_TX_Done()); // And put the FPGA in the appropriate mode FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_2SUBCARRIERS_424_484_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); @@ -1030,10 +1032,8 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo dmabuf16_t *dma = get_dma16(); // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) { - Dbprintf("FpgaSetupSscDma failed. Exiting"); - } + if (FpgaSetupSscRxDmaRepeat((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); return PM3_EINIT; } @@ -1042,7 +1042,7 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo for (;;) { - volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); + volatile uint16_t behindBy = ((uint16_t *)FPGA_SSC_DMA_RX_Current_Address() - upTo) & (DMA_BUFFER_SIZE - 1); if (behindBy == 0) { continue; } @@ -1059,18 +1059,9 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo upTo = dma->buf; // start reading the circular buffer from the beginning // DMA Counter Register had reached 0, already rotated. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { + if (FPGA_SSC_DMA_RX_Done()) { - // primary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + FPGA_SSC_DMA_RX_Refresh_Repeat(dma->buf, DMA_BUFFER_SIZE); WDT_HIT(); if (BUTTON_PRESS()) { @@ -1137,7 +1128,7 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo } } - FpgaDisableSscDma(); + FPGA_SSC_DMA_RX_Disable(); FpgaDisableTracing(); uint32_t sof_time = *eof_time - (32 * 16); // time for SOF transfer @@ -1530,22 +1521,20 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo DecodeReaderInit(dr, received, max_len, 0, NULL); // wait for last transfer to complete - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)); + while (!FPGA_SSC_TX_Done()); LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); // clear receive register and wait for next transfer - uint32_t temp = AT91C_BASE_SSC->SSC_RHR; + uint32_t temp = FPGA_SSC_RX_Value(); (void) temp; - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) ; + FPGA_SSC_RX_READY_WAIT(); // Setup and start DMA. dmabuf8_t *dma = get_dma8(); - if (FpgaSetupSscDma(dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) { - Dbprintf("FpgaSetupSscDma failed. Exiting"); - } + if (FpgaSetupSscRxDmaRepeat(dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); return -4; } const uint8_t *upTo = dma->buf; @@ -1553,7 +1542,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo uint32_t dma_start_time = GetCountSspClk() & 0xfffffff8; for (;;) { - volatile uint16_t behindBy = ((uint8_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); + volatile uint16_t behindBy = ((uint8_t *)FPGA_SSC_DMA_RX_Current_Address() - upTo) & (DMA_BUFFER_SIZE - 1); if (behindBy == 0) { continue; } @@ -1571,9 +1560,9 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo break; } } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { // DMA Counter Register had reached 0, already rotated. - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; // refresh the DMA Next Buffer and - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; // DMA Next Counter registers + + if (FPGA_SSC_DMA_RX_Done()) { // DMA Counter Register had reached 0, already rotated. + FPGA_SSC_DMA_RX_Refresh_Single(dma->buf, DMA_BUFFER_SIZE); } for (int i = 7; i >= 0; i--) { @@ -1605,7 +1594,7 @@ int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eo WDT_HIT(); } - FpgaDisableSscDma(); + FPGA_SSC_DMA_RX_Disable(); if (dr->byteCount >= 0) { uint32_t sof_time = *eof_time @@ -1651,7 +1640,7 @@ void AcquireRawAdcSamplesIso15693(void) { // initialize SSC and select proper AD input FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); StartCountSspClk(); @@ -1665,19 +1654,19 @@ void AcquireRawAdcSamplesIso15693(void) { TransmitTo15693Tag(ts->buf, ts->max, &start_time, false); // wait for last transfer to complete - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) ; + while (!FPGA_SSC_TX_Done()) ; FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_424_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE); for (int c = 0; c < 4000;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - uint16_t r = AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + uint16_t r = FPGA_SSC_RX_Value(); dest[c++] = r >> 5; } } - FpgaDisableSscDma(); + FPGA_SSC_DMA_RX_Disable(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } @@ -1712,7 +1701,7 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla LED_D_OFF(); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); StartCountSspClk(); @@ -1721,10 +1710,8 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla dmabuf16_t *dma = get_dma16(); // Setup and start DMA. - if (FpgaSetupSscDma((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) { - DbpString("FpgaSetupSscDma failed. Exiting"); - } + if (FpgaSetupSscRxDmaRepeat((uint8_t *) dma->buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) DbpString("FpgaSetupSscRxDmaRepeat failed. Exiting"); switch_off(); return; } @@ -1743,7 +1730,7 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla for (;;) { - volatile int behind_by = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1); + volatile int behind_by = ((uint16_t *)FPGA_SSC_DMA_RX_Current_Address() - upTo) & (DMA_BUFFER_SIZE - 1); if (behind_by < 1) { continue; } @@ -1765,18 +1752,9 @@ void SniffIso15693(uint8_t jam_search_len, uint8_t *jam_search_string, bool icla upTo = dma->buf; // DMA Counter Register had reached 0, already rotated. - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) { + if (FPGA_SSC_DMA_RX_Done()) { - // primary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dma->buf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; - } + FPGA_SSC_DMA_RX_Refresh_Repeat(dma->buf, DMA_BUFFER_SIZE); WDT_HIT(); if (BUTTON_PRESS()) { @@ -1925,7 +1903,7 @@ void Iso15693InitReader(void) { // initialize SSC and select proper AD input FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); set_tracing(true); @@ -2173,7 +2151,7 @@ void Iso15693InitTag(void) { // initialize SSC and select proper AD input FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); clear_trace(); set_tracing(true); @@ -2285,7 +2263,7 @@ void SimTagIso15693(const uint8_t *uid, uint8_t block_size) { // find reader field if (tag->state == TAG_STATE_NO_FIELD) { - vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15; + vHf = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_HF); if (vHf > MF_MINFIELDV) { tag->state = TAG_STATE_READY; LED_A_ON(); diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index 6239f27cb..f11067118 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -24,8 +24,9 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "dbprint.h" #include "util.h" #include "string.h" @@ -75,8 +76,8 @@ static uint16_t rx_frame_from_fpga(void) { WDT_HIT(); // wait for frame be become available in rx holding register - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - return AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + return FPGA_SSC_RX_Value(); } } return 0; @@ -143,12 +144,12 @@ static bool rx_bit(void) { static void tx_bit(bool bit) { // insert pause - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); last_frame_end += RWD_TIME_PAUSE; while (GET_TICKS < last_frame_end) { }; // return to carrier on, wait for bit periode to end - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); last_frame_end += (bit ? RWD_TIME_1 : RWD_TIME_0) - RWD_TIME_PAUSE; while (GET_TICKS < last_frame_end) { }; } @@ -181,10 +182,10 @@ static void tx_frame(uint32_t frame, uint8_t len) { }; // add pause to mark end of the frame - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); last_frame_end += RWD_TIME_PAUSE; while (GET_TICKS < last_frame_end) { }; - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); // log uint8_t cmdbytes[] = {len, BYTEx(frame, 0), BYTEx(frame, 1), BYTEx(frame, 2)}; @@ -288,16 +289,15 @@ static void init_reader(void) { // configure FPGA FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_212_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); LED_A_ON(); // configure SSC with defaults FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); // re-claim GPIO_SSC_DOUT as GPIO and enable output - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - LOW(GPIO_SSC_DOUT); + gpio_fpga_mod_only_setup(); + Gpio_SSC_DOUT_Low(); // reserve a cardmem, meaning we can use the tracelog function in bigbuff easier. legic_mem = BigBuf_get_EM_addr(); diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index ccd3c7c63..f66d2e3b6 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -24,8 +24,9 @@ #include "cmd.h" #include "proxmark3_arm.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "fpga_apis.h" +#include "ticks_apis.h" #include "dbprint.h" #include "util.h" @@ -75,7 +76,7 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */ // Returns true if a pulse/pause is received within timeout // Note: inlining this function would fail with -Os static bool wait_for(bool value, const uint32_t timeout) { - while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { + while (Gpio_SSC_DIN_Read() != value) { WDT_HIT(); if (GetCountSspClk() > timeout) { return false; @@ -142,10 +143,10 @@ static void tx_bit(bool bit) { if (bit) { // modulate subcarrier - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); } else { // do not modulate subcarrier - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); } // wait for tx timeslot to end @@ -181,7 +182,7 @@ static void tx_frame(uint32_t frame, uint8_t len) { }; // disable subcarrier - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); // log uint8_t cmdbytes[] = {len, BYTEx(frame, 0), BYTEx(frame, 1)}; @@ -202,7 +203,7 @@ static void tx_ack(void) { legic_prng_forward(1); // disable subcarrier - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); // log uint8_t cmdbytes[] = {1, 1}; @@ -313,15 +314,14 @@ static void init_tag(void) { // configure FPGA FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K); - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // configure SSC with defaults FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR); // first pull output to low to prevent glitches then re-claim GPIO_SSC_DOUT - LOW(GPIO_SSC_DOUT); - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; + Gpio_SSC_DOUT_Low(); + gpio_fpga_mod_only_setup(); // reserve a cardmem, meaning we can use the tracelog function in bigbuff easier. legic_mem = BigBuf_get_EM_addr(); diff --git a/armsrc/lfadc.c b/armsrc/lfadc.c index 18712a7bb..e89881cab 100644 --- a/armsrc/lfadc.c +++ b/armsrc/lfadc.c @@ -18,8 +18,9 @@ #include "lfadc.h" #include "lfsampling.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "dbprint.h" #include "appmain.h" @@ -40,14 +41,15 @@ // Exported global variables ////////////////////////////////////////////////////////////////////////////// -bool g_logging = true; +bool g_logging = false; // TODO DXL 在某些情况下,读不到卡的时候,此处可能会造成内存溢出,需要解决 ////////////////////////////////////////////////////////////////////////////// // Global variables ////////////////////////////////////////////////////////////////////////////// static bool rising_edge = false; -static bool reader_mode = false; +static lf_adc_init_mode_t g_init_mode = LF_ADC_READER; +static lf_adc_edge_mode_t g_edge_mode = LF_ADC_WAV_REVERSED; ////////////////////////////////////////////////////////////////////////////// // Auxiliary functions @@ -62,32 +64,35 @@ bool lf_test_periods(size_t expected, size_t count) { ////////////////////////////////////////////////////////////////////////////// // Low frequency (LF) adc passthrough functionality ////////////////////////////////////////////////////////////////////////////// -static uint8_t previous_adc_val = 0; //0xFF; +static uint8_t previous_adc_val = 0; // 0xFF; static uint8_t adc_avg = 0; +static uint8_t adc_max; +static uint8_t adc_min; -uint8_t get_adc_avg(void) { +uint8_t lf_get_adc_avg(void) { return adc_avg; } + void lf_sample_mean(void) { uint8_t periods = 0; uint32_t adc_sum = 0; + adc_max = 0; + adc_min = 255; while (periods < 32) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - adc_sum += AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + const uint8_t adc_val = FPGA_SSC_RX_Value(); + if (adc_val < adc_min) adc_min = adc_val; + if (adc_val > adc_max) adc_max = adc_val; + adc_sum += adc_val; periods++; } } - // division by 32 - adc_avg = adc_sum >> 5; + adc_avg = adc_sum >> 5; // division by 32 previous_adc_val = adc_avg; - - if (g_dbglevel >= DBG_EXTENDED) { - Dbprintf("LF ADC average %u", adc_avg); - } + DBG Dbprintf("LF ADC average %u, max %u, min %u, diff %u", adc_avg, adc_max, adc_min, adc_max - adc_min); } static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { - #define LIMIT_DEV 20 // timeout limit to 100 000 w/o @@ -101,61 +106,68 @@ static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) { timeout--; if (timeout == 0) { + DBG Dbprintf("Error, timeout for wait adc value rx"); return 0; } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x00; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(0x00); continue; } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (FPGA_SSC_RX_Ready() == false) { + continue; + } - periods++; + periods++; // T0 increment, 1(TO) = 8us, same with 125khz clock. + timeout = 100000; // reset timeout + volatile uint8_t adc_val = FPGA_SSC_RX_Value(); // Get current adc value. - // reset timeout - timeout = 100000; + if (g_logging) { + logSampleSimple(adc_val); + } - volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR; - - if (g_logging) { - logSampleSimple(adc_val); - } - - // Only test field changes if state of adc values matter - if (wait == false) { - // Test if we are locating a field modulation (100% ASK = complete field drop) - if (detect_gap) { - // Only return when the field completely disappeared - if (adc_val == 0) { - return periods; - } - - } else { - // Trigger on a modulation swap by observing an edge change + // Only test field changes if state of adc values matter + if (wait == false) { + // Test if we are locating a field modulation (100% ASK = complete field drop) + if (detect_gap) { + // Only return when the field completely disappeared + if (adc_val == 0) { + return periods; + } + } else { + if (g_edge_mode == LF_ADC_WAV_REVERSED) { if (rising_edge) { - if ((previous_adc_val > avg_peak) && (adc_val <= previous_adc_val)) { rising_edge = false; return periods; } - } else { - if ((previous_adc_val < avg_through) && (adc_val >= previous_adc_val)) { rising_edge = true; return periods; } - + } + } else if (g_edge_mode == LF_ADC_NOT_REVERSED) { + if (rising_edge) { + if (adc_val <= adc_avg && adc_val <= avg_through) { + rising_edge = false; + return periods; + } + } else { + if (adc_val >= avg_peak) { + rising_edge = true; + return periods; + } } } } + } - previous_adc_val = adc_val; + previous_adc_val = adc_val; - if (periods >= max) { - return 0; - } + if (periods >= max) { + return 0; } } @@ -175,18 +187,17 @@ size_t lf_detect_gap(size_t max) { } void lf_reset_counter(void) { - // TODO: find out the correct reset settings for tag and reader mode -// if (reader_mode) { + // if (g_init_mode == LF_ADC_READER) { // Reset values for reader mode rising_edge = false; previous_adc_val = 0xFF; -// } else { + // } else { // Reset values for tag/transponder mode -// rising_edge = false; -// previous_adc_val = 0xFF; -// } + // rising_edge = false; + // previous_adc_val = 0xFF; + // } } bool lf_get_tag_modulation(void) { @@ -198,15 +209,15 @@ bool lf_get_reader_modulation(void) { } void lf_wait_periods(size_t periods) { - // wait detect gap + // wait for detect gap lf_count_edge_periods_ex(periods, true, false); } -void lf_init(bool reader, bool simulate, bool ledcontrol) { - +void lf_init(lf_adc_init_mode_t init_mode, lf_adc_edge_mode_t edge_mode, bool ledcontrol) { StopTicks(); - reader_mode = reader; + g_init_mode = init_mode; + g_edge_mode = edge_mode; FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -216,21 +227,22 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) { FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); - if (reader) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - } else { - - if (simulate) { + // Different fpga config for different mode. + switch (g_init_mode) { + case LF_ADC_READER: + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + break; + case LF_ADC_TAG_SIM: FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); - } else { - // Sniff + break; + case LF_ADC_SNIFF: FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC); // FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); - } + break; } // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); // Now set up the SSC to get the ADC samples that are now streaming at us. FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER); @@ -242,12 +254,16 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) { // maximum: 545T0 = 545 * 8us = 4360us = 4.36ms - Hitag2 command waiting time before it starts transmitting in public mode (if configured so) // 565T0 = 565 * 8us = 4520us = 4.52ms - HitagS waiting time before entering TTF mode (if configured so) // Thus (2.50 ms + 4.36 ms) / 2 ~= 3 ms (rounded down to integer), should be a good timing for both tag models - SpinDelay(3); + SpinDelay(2); // TODO DXL 之前是 3ms,改成2ms测试hitagU + // TODO DXL 经测试,3ms时hitag2工作的很好,但是hitagu会进入TTF模式导致无法寻卡 + // hitagu用2ms延时比较靠谱 + // lf_wait_periods(200); // TODO DXL zx8268 用这个时长才能正常寻卡,3ms的话,8268直接开始广播了,没办法通信上了 // Steal this pin from the SSP (SPI communication channel with fpga) and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - LOW(GPIO_SSC_DOUT); + gpio_fpga_mod_only_setup(); + Gpio_SSC_DOUT_Low(); + + /* TODO DXL 暂时注释,看看哪里没用到这些定时器的,如果都没用到,则可以删掉 // Enable peripheral Clock for TIMER_CLOCK 0 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); @@ -259,9 +275,13 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) { AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK; + */ + // Clear all leds if (ledcontrol) LEDsoff(); + /* TODO DXL 暂时注释,看看哪里没用到这些定时器的,如果都没用到,则可以删掉 + // Reset and enable timers AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; @@ -269,6 +289,8 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) { // Assert a sync signal. This sets all timers to 0 on next active clock edge AT91C_BASE_TCB->TCB_BCR = 1; + */ + // Prepare data trace uint32_t bufsize = 10000; @@ -281,6 +303,8 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) { } void lf_finalize(bool ledcontrol) { + /* TODO DXL 暂时注释,看看哪里没用到这些定时器的,如果都没用到,则可以删掉 + // Disable timers AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; @@ -289,6 +313,8 @@ void lf_finalize(bool ledcontrol) { AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; + */ + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); if (ledcontrol) LEDsoff(); @@ -316,9 +342,9 @@ size_t lf_detect_field_drop(size_t max) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { + if (FPGA_SSC_RX_Ready()) { periods++; - volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR; + volatile uint8_t adc_val = FPGA_SSC_RX_Value(); if (g_logging) logSampleSimple(adc_val); @@ -334,11 +360,19 @@ size_t lf_detect_field_drop(size_t max) { return 0; } +void lf_reset_field(size_t periods) { + // FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + Gpio_SSC_DOUT_High(); + lf_wait_periods(periods); + Gpio_SSC_DOUT_Low(); + // FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); +} + void lf_modulation(bool modulation) { if (modulation) { - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); } else { - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); } } @@ -352,8 +386,8 @@ static void lf_manchester_send_bit(uint8_t bit) { // simulation bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len, bool ledcontrol) { - - if (ledcontrol) LED_B_ON(); + if (ledcontrol) + LED_B_ON(); lf_manchester_send_bit(1); lf_manchester_send_bit(1); @@ -366,6 +400,7 @@ bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len, bool ledco lf_manchester_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); } - if (ledcontrol) LED_B_OFF(); + if (ledcontrol) + LED_B_OFF(); return true; } diff --git a/armsrc/lfadc.h b/armsrc/lfadc.h index 322584de2..6cfe56935 100644 --- a/armsrc/lfadc.h +++ b/armsrc/lfadc.h @@ -27,7 +27,30 @@ extern bool g_logging; -uint8_t get_adc_avg(void); +/* + * Trigger on a modulation swap by observing an edge change + * PEAK_THROUGH_LEFT: + * 1. When the peak of the falling edge appears to rise, it is considered to be the rising edge. + * 2. When the peak of the rising edge drops, it is considered a falling edge. + * Note: The edge status is from waveform of the analog signal is reversed. + * PEAK_THROUGH_CENTER: + * 1. The timing for edge judgment is based on the level range without modulation. + * 2. The edge switching will not be determined within the range of the peak of the falling edge and the peak of the rising edge. + * Note: not reversed. + */ +typedef enum { + LF_ADC_WAV_REVERSED = 0U, + LF_ADC_NOT_REVERSED = 1U, +} lf_adc_edge_mode_t; + +// What working mode should the module be initialized to? +typedef enum { + LF_ADC_READER = 0U, + LF_ADC_TAG_SIM = 1U, + LF_ADC_SNIFF = 2U, +} lf_adc_init_mode_t; + +uint8_t lf_get_adc_avg(void); void lf_sample_mean(void); bool lf_test_periods(size_t expected, size_t count); size_t lf_count_edge_periods(size_t max); @@ -38,10 +61,10 @@ bool lf_get_tag_modulation(void); bool lf_get_reader_modulation(void); void lf_wait_periods(size_t periods); -//void lf_init(bool reader); -void lf_init(bool reader, bool simulate, bool ledcontrol); +void lf_init(lf_adc_init_mode_t init_mode, lf_adc_edge_mode_t edge_mode, bool ledcontrol); void lf_finalize(bool ledcontrol); size_t lf_detect_field_drop(size_t max); +void lf_reset_field(size_t periods); bool lf_manchester_send_bytes(const uint8_t *frame, size_t frame_len, bool ledcontrol); void lf_modulation(bool modulation); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 39e20f696..776dd5907 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -24,8 +24,9 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "dbprint.h" #include "util.h" #include "commonutil.h" @@ -36,7 +37,7 @@ #include "lfsampling.h" #include "protocols.h" #include "pmflash.h" -#include "flashmem.h" // persistence on flash +#include "flashmem.h" #include "spiffs.h" // spiffs #include "appmain.h" // print stack @@ -517,6 +518,12 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint 101010101010101[0]000... [5555fe852c5555555555555555fe0000] + + +The current read-write implementation is based on the discontinued model RI-TRP-WR2B-30. +The old model is single page, while the new model is multi page, with different operation instructions and communication formats. +https://e2e.ti.com/support/wireless-connectivity/other-wireless-group/other-wireless/f/other-wireless-technologies-forum/863988/ri-trp-wr2b-30-replacement-part?tisearch=e2e-sitesearch&keymatch=RI-TRP-WR2B# + */ void ReadTItag(bool ledcontrol) { StartTicks(); @@ -554,6 +561,19 @@ void ReadTItag(bool ledcontrol) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + // 周期的判断,就是实际上固定的频率采集到的数据,计算实际上所需的过零点的数量,在整个频率内所占用的采集点的数量 + // 比如123khz的数据调制,从0跨越到1需要更多的时间,那实际上所耗费的在固定频率下所采集的数据的数量更多。 + // 模拟固定频率采集的 CROSS_LO 数据(123):000001111100000 + // 模拟固定频率采集的 CROSS_LO 数据(134):000011110000111 + // 以上例子可以描述出大概的数据变化在采集到的数据中的特征 + // 采样点数量所需的计算实际易于理解的公式 + // 123.2khz 一个周期需要 8.116us + // 123.2khz 16个周期需要 129.856us + // 2mhz 采样一个周期需要 0.0000005s = 500ns + // 129.856us / 500ns(0.5us) 就是所需的采样点数量。 + // 所以看16个fsk的过零点所需要的采样点数量,就基本上能猜测出来当前调制的频率是多少。 + // HDX调制16个周期的134khz或者123khz,所以这个判断的方法可以这么工作起来。 + for (i = 0; i < n - 1; i++) { // count cycles by looking for lo to hi zero crossings if ((dest[i] < 0) && (dest[i + 1] > 0)) { @@ -655,17 +675,17 @@ static void WriteTIbyte(uint8_t b) { for (i = 0; i < 8; i++) { if (b & (1 << i)) { // stop modulating antenna 1ms - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); WaitUS(1000); // modulate antenna 1ms - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); WaitUS(1000); } else { // stop modulating antenna 0.3ms - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); WaitUS(300); // modulate antenna 1.7ms - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); WaitUS(1700); } } @@ -683,14 +703,12 @@ void AcquireTiType(bool ledcontrol) { //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); + // TODO DXL Waiting for cross-platform implementation. + // Set up the synchronous serial port AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN; - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST; AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN; @@ -704,24 +722,29 @@ void AcquireTiType(bool ledcontrol) { AT91C_BASE_SSC->SSC_TCMR = 0; // Transmit Frame Mode Register AT91C_BASE_SSC->SSC_TFMR = 0; + // iceman, FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER) ?? the code above? can it be replaced? + + // steal this pin from the SSP and use it to control the modulation + gpio_fpga_mod_only_setup(); + if (ledcontrol) LED_D_ON(); - // modulate antenna - HIGH(GPIO_SSC_DOUT); + // start modulate antenna + Gpio_SSC_DOUT_High(); // Charge TI tag for 50ms. WaitMS(50); // stop modulating antenna and listen - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); if (ledcontrol) LED_D_OFF(); i = 0; for (;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - buf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + if (FPGA_SSC_RX_Ready()) { + buf[i] = FPGA_SSC_RX_Value(); // store 32 bit values in buffer i++; if (i >= TIBUFLEN) break; } @@ -779,8 +802,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc, bool ledcontrol) { if (ledcontrol) LED_A_ON(); // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + gpio_fpga_mod_only_setup(); // writing algorithm: // a high bit consists of a field off for 1ms and field on for 1ms @@ -793,7 +815,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc, bool ledcontrol) { // finish with 50ms programming time // modulate antenna - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); WaitMS(50); // charge time WriteTIbyte(0xbb); // keyword @@ -810,7 +832,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc, bool ledcontrol) { WriteTIbyte((crc >> 8) & 0xff); // crc hi WriteTIbyte(0x00); // write frame lo WriteTIbyte(0x03); // write frame hi - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); WaitMS(50); // programming time if (ledcontrol) LED_A_OFF(); @@ -826,7 +848,6 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc, bool ledcontrol) { // note: a call to FpgaDownloadAndGo(FPGA_BITSTREAM_LF) must be done before, but // this may destroy the bigbuf so be sure this is called before calling SimulateTagLowFrequencyEx void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycles) { - // start us timer StartTicks(); @@ -847,9 +868,7 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; + gpio_fpga_mod_feedback_setup(); uint16_t check = 0; @@ -868,7 +887,7 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl // wait until SSC_CLK goes HIGH // used as a simple detection of a reader field? - while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + while (!(Gpio_SSC_CLK_Read())) { WDT_HIT(); if (check == 1000) { if (data_available() || BUTTON_PRESS()) @@ -888,7 +907,7 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl check = 0; //wait until SSC_CLK goes LOW - while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + while (Gpio_SSC_CLK_Read()) { WDT_HIT(); if (check == 2000) { if (BUTTON_PRESS() || data_available()) @@ -1665,7 +1684,7 @@ void turn_read_lf_on(uint32_t delay) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD); // measure antenna strength. - //int adcval = ((MAX_ADC_LF_VOLTAGE * (SumAdc(ADC_CHAN_LF, 32) >> 1)) >> 14); + //int adcval = AdcRssiAvgToMilliVolt(ADC_RSSI_CH_LF); WaitUS(delay); } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 8d2bb17d4..25245adec 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -20,14 +20,15 @@ #include "proxmark3_arm.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" #include "dbprint.h" #include "util.h" #include "lfdemod.h" #include "string.h" // memset #include "appmain.h" // print stack -#include "usb_cdc.h" // real-time sampling +#include "usb_cdc_apis.h" #include "lfops.h" /* @@ -273,7 +274,7 @@ void LFSetupFPGAForADC(int divisor, bool reader_field) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | (reader_field ? FPGA_LF_ADC_READER_FIELD : 0)); // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); // Now set up the SSC to get the ADC samples that are now streaming at us. FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER); @@ -335,12 +336,12 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in WDT_HIT(); - if (ledcontrol && (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY)) { + if (ledcontrol && FPGA_SSC_TX_Ready()) { LED_D_ON(); } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); // (RDV4) Test point 8 (TP8) can be used to trigger oscilloscope if (ledcontrol) LED_D_OFF(); @@ -399,6 +400,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in uint32_t DoAcquisition_default(int trigger_threshold, bool verbose, bool ledcontrol) { return DoAcquisition(1, 8, 0, trigger_threshold, verbose, 0, 0, 0, ledcontrol); } + uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size, bool ledcontrol) { return DoAcquisition(config.decimation , config.bits_per_sample @@ -468,9 +470,11 @@ int ReadLF_realtime(bool reader_field, bool cotag) { uint8_t curr_byte = 0; int return_value = PM3_SUCCESS; - uint32_t sample_buffer_len = AT91C_USB_EP_IN_SIZE; + uint32_t usb_buffer_len = 0, sample_buffer_len; + usb_get_ep_size(NULL, &usb_buffer_len, NULL); + sample_buffer_len = usb_buffer_len; // If sample_buffer_len is not specified, a buffer of random length may be requested. initSampleBuffer(&sample_buffer_len); - if (sample_buffer_len != AT91C_USB_EP_IN_SIZE) { + if (sample_buffer_len != usb_buffer_len) { return PM3_EFAILED; } @@ -503,12 +507,12 @@ int ReadLF_realtime(bool reader_field, bool cotag) { WDT_HIT(); - if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY)) { + if (FPGA_SSC_TX_Ready()) { LED_D_ON(); } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); // (RDV4) Test point 8 (TP8) can be used to trigger oscilloscope LED_D_OFF(); @@ -621,12 +625,12 @@ void doT55x7Acquisition(size_t sample_size, bool ledcontrol) { WDT_HIT(); - if (ledcontrol && (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY)) { + if (ledcontrol && FPGA_SSC_TX_Ready()) { LED_D_ON(); } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); if (ledcontrol) LED_D_OFF(); // skip until the first high sample above threshold @@ -700,9 +704,8 @@ void doCotagAcquisition(void) { WDT_HIT(); - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); // find first peak if (firsthigh == false) { @@ -770,8 +773,8 @@ uint16_t doCotagAcquisitionManchester(uint8_t *dest, uint16_t destlen) { } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); // find first peak if (firsthigh == false) { diff --git a/armsrc/lfzx.c b/armsrc/lfzx.c index f95b2c2b7..0f69d4a82 100644 --- a/armsrc/lfzx.c +++ b/armsrc/lfzx.c @@ -20,13 +20,14 @@ #include "BigBuf.h" #include "crc.h" // CRC-8 / Hitag1 / ZX8211 -#include "fpgaloader.h" +#include "fpga_loader.h" #include "dbprint.h" #include "lfops.h" // turn_read_lf_on / off #include "lfadc.h" #include "lfsampling.h" // getSamplingConfig #include "pm3_cmd.h" // struct -#include "ticks.h" +#include "ticks_apis.h" +#include "fpga_apis.h" /* ZX8211 @@ -106,7 +107,7 @@ static void zx8211_setup_read(void) { FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + SetAdcMuxFor(ADC_MUXSEL_LOPKD); // Start the timer StartTicks(); @@ -145,12 +146,12 @@ static void zx_get(bool ledcontrol) { WDT_HIT(); - if (ledcontrol && (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY)) { + if (ledcontrol && FPGA_SSC_TX_Ready()) { LED_D_ON(); } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_RX_Ready()) { + volatile uint8_t sample = (uint8_t)FPGA_SSC_RX_Value(); (void)sample; // (RDV4) Test point 8 (TP8) can be used to trigger oscilloscope diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 2162e48af..3dabebad1 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -26,15 +26,16 @@ #include "BigBuf.h" #include "cmd.h" #include "flashmem.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "iso14443a.h" #include "mifaredesfire.h" #include "util.h" #include "commonutil.h" #include "crc16.h" #include "dbprint.h" -#include "ticks.h" -#include "usb_cdc.h" // usb_poll_validate_length +#include "ticks_apis.h" +#include "usb_cdc_apis.h" #include "spiffs.h" // spiffs #include "appmain.h" // print_stack_usage #include "cmac_calc.h" @@ -3431,7 +3432,7 @@ void MifareHasStaticNonce(void) { nt = bytes_to_num(rec, 4); // some cards with static nonce need to be reset before next query - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // TODO DXL Can we use mf_reset_card(); ? LEDsoff(); CHK_TIMEOUT(); diff --git a/armsrc/mifaredesfire.c b/armsrc/mifaredesfire.c index 7553453bc..dcc8d7234 100644 --- a/armsrc/mifaredesfire.c +++ b/armsrc/mifaredesfire.c @@ -23,13 +23,14 @@ #include "desfire_crypto.h" #include "cmd.h" #include "dbprint.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "iso14443a.h" #include "crc16.h" #include "commonutil.h" #include "util.h" #include "mifare.h" -#include "ticks.h" +#include "ticks_apis.h" #include "protocols.h" #define MAX_APPLICATION_COUNT 28 diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 989345493..29b69689a 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -35,7 +35,7 @@ #include "BigBuf.h" #include "string.h" #include "mifareutil.h" -#include "fpgaloader.h" +#include "fpga_apis.h" #include "proxmark3_arm.h" #include "cmd.h" #include "protocols.h" @@ -44,7 +44,7 @@ #include "commonutil.h" #include "crc16.h" #include "dbprint.h" -#include "ticks.h" +#include "ticks_apis.h" #include "parity.h" static bool IsKeyBReadable(uint8_t blockNo) { diff --git a/armsrc/mifaresniff_disabled.c b/armsrc/mifaresniff_disabled.c index ac6142e91..95f4bb61f 100644 --- a/armsrc/mifaresniff_disabled.c +++ b/armsrc/mifaresniff_disabled.c @@ -83,8 +83,8 @@ void RAMFUNC SniffMifare(uint8_t param) { // Setup and start DMA. // set transfer address and number of bytes. Start transfer. - if (FpgaSetupSscDma(dmaBuf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); + if (FpgaSetupSscRxDmaRepeat(dmaBuf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("[!] FpgaSetupSscRxDmaRepeat failed. Exiting"); return; } @@ -111,7 +111,7 @@ void RAMFUNC SniffMifare(uint8_t param) { maxDataLen = 0; ReaderIsActive = false; TagIsActive = false; - FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer. + FpgaSetupSscRxDmaRepeat((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer. } } */ @@ -119,7 +119,7 @@ void RAMFUNC SniffMifare(uint8_t param) { // number of bytes we have processed so far int register readBufDataP = data - dmaBuf; // number of bytes already transferred - int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR; + int register dmaBufDataP = DMA_BUFFER_SIZE - FPGA_SSC_DMA_RX_Remaining_Length(); if (readBufDataP <= dmaBufDataP) // we are processing the same block of data which is currently being transferred dataLen = dmaBufDataP - readBufDataP; // number of bytes still to be processed else @@ -135,16 +135,8 @@ void RAMFUNC SniffMifare(uint8_t param) { } if (dataLen < 1) continue; - // primary buffer was stopped ( <-- we lost data! - if (AT91C_BASE_PDC_SSC->PDC_RCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE; - Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary - } - // secondary buffer sets as primary, secondary buffer was stopped - if (AT91C_BASE_PDC_SSC->PDC_RNCR == 0) { - AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + if (FPGA_SSC_DMA_RX_Done()) { + FPGA_SSC_DMA_RX_Refresh_Repeat(dmaBuf, DMA_BUFFER_SIZE); } LED_A_OFF(); diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index e223b14fb..d9542fd60 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -24,7 +24,7 @@ #include "string.h" #include "BigBuf.h" #include "iso14443a.h" -#include "ticks.h" +#include "ticks_apis.h" #include "dbprint.h" #include "parity.h" #include "commonutil.h" diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 8eefd354e..2ca53d15e 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -18,8 +18,9 @@ #include "proxmark3_arm.h" #include "cmd.h" #include "BigBuf.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "fpga_apis.h" +#include "ticks_apis.h" #include "dbprint.h" #include "util.h" #include "lfsampling.h" @@ -564,10 +565,8 @@ void SendCmdPCF7931(uint32_t *tab, bool ledcontrol) { break; } - // steal this pin from the SSP and use it to control the modulation - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; + gpio_fpga_mod_only_setup(); //initialization of the timer AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0); @@ -582,19 +581,19 @@ void SendCmdPCF7931(uint32_t *tab, bool ledcontrol) { tempo = AT91C_BASE_TC0->TC_CV; for (u = 0; tab[u] != 0; u += 3) { // modulate antenna - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); while ((uint32_t)tempo < tab[u]) { tempo = AT91C_BASE_TC0->TC_CV; } // stop modulating antenna - LOW(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_Low(); while ((uint32_t)tempo < tab[u + 1]) { tempo = AT91C_BASE_TC0->TC_CV; } // modulate antenna - HIGH(GPIO_SSC_DOUT); + Gpio_SSC_DOUT_High(); while ((uint32_t)tempo < tab[u + 2]) { tempo = AT91C_BASE_TC0->TC_CV; } diff --git a/armsrc/sam_common.c b/armsrc/sam_common.c index 4f1002d50..843d6c409 100644 --- a/armsrc/sam_common.c +++ b/armsrc/sam_common.c @@ -23,7 +23,7 @@ #include "proxmark3_arm.h" #include "BigBuf.h" #include "commonutil.h" -#include "ticks.h" +#include "ticks_apis.h" #include "dbprint.h" #include "i2c.h" #include "iso15693.h" diff --git a/armsrc/sam_picopass.c b/armsrc/sam_picopass.c index 147eeeac0..093558dcf 100644 --- a/armsrc/sam_picopass.c +++ b/armsrc/sam_picopass.c @@ -23,13 +23,14 @@ #include "BigBuf.h" #include "cmd.h" #include "commonutil.h" -#include "ticks.h" +#include "ticks_apis.h" #include "dbprint.h" #include "i2c.h" #include "iso15693.h" #include "protocols.h" #include "optimized_cipher.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "pm3_cmd.h" /** diff --git a/armsrc/sam_sc.c b/armsrc/sam_sc.c index dad76591d..47945eb2d 100644 --- a/armsrc/sam_sc.c +++ b/armsrc/sam_sc.c @@ -25,7 +25,7 @@ #include "i2c.h" // ISO7816_MAX_FRAME, I2C_Reset_EnterMainProgram #include "proxmark3_arm.h" #include "sam_common.h" -#include "ticks.h" +#include "ticks_apis.h" #include "util.h" // LED_D_ON, LEDsoff // Tracks whether the SIM module has been initialised since the last reset. diff --git a/armsrc/sam_seos.c b/armsrc/sam_seos.c index 3f8c806e9..9d8d2c26c 100644 --- a/armsrc/sam_seos.c +++ b/armsrc/sam_seos.c @@ -29,12 +29,13 @@ #include "BigBuf.h" #include "cmd.h" #include "commonutil.h" -#include "ticks.h" +#include "ticks_apis.h" #include "dbprint.h" #include "i2c.h" #include "protocols.h" #include "optimized_cipher.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "pm3_cmd.h" #include "cmd.h" diff --git a/armsrc/secc.c b/armsrc/secc.c index 9a20cfcf3..85166b656 100644 --- a/armsrc/secc.c +++ b/armsrc/secc.c @@ -25,7 +25,8 @@ #include "dbprint.h" #include "BigBuf.h" // DMA_BUFFER_SIZE, MAX_PARITY_SIZE #include "crc16.h" // AddCrc14A, CheckCrc14A -#include "fpgaloader.h" // FpgaWriteConfWord, FpgaSetupSscDma +#include "fpga_loader.h" // FpgaWriteConfWord, FpgaSetupSscDma +#include "fpga_apis.h" // FPGA_MAJOR_MODE_HF_ISO14443A #include "desfire_crypto.h" // tdes_nxp_send #include "mbedtls/des.h" // mbedtls_des_*, mbedtls_des3_* #include "iso14443a.h" // ReaderTransmit, ReaderReceive, iso14a_get/set_timeout, iso14a_get/toggle_pcb_blocknum, MAX_ISO14A_TIMEOUT @@ -34,7 +35,7 @@ #include "cmd.h" // reply_ng #include "pm3_cmd.h" // CMD_HF_HIDCONFIG_SIM, CMD_HF_HIDCONFIG_SNIFF #include "dbprint.h" // Dbprintf, LED_* -#include "ticks.h" // WDT_HIT +#include "ticks_apis.h" // WDT_HIT #include "protocols.h" // ISO14443A_CMD_* constants // --------------------------------------------------------------------------- @@ -404,8 +405,8 @@ bool hid_config_card_jam(const uint8_t *cmd, int len, uint8_t *dma_buf) { // Restore sniffer FPGA mode and re-arm DMA FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER); - if (FpgaSetupSscDma(dma_buf, DMA_BUFFER_SIZE) == false) { - if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscDma failed. Exiting"); + if (FpgaSetupSscRxDmaRepeat(dma_buf, DMA_BUFFER_SIZE) == false) { + if (g_dbglevel > DBG_ERROR) Dbprintf("FpgaSetupSscRxDmaRepeat failed. Exiting"); return false; } diff --git a/armsrc/seos.c b/armsrc/seos.c index 6e2b40798..77104ef64 100644 --- a/armsrc/seos.c +++ b/armsrc/seos.c @@ -20,7 +20,8 @@ #include "iso14443a.h" #include "BigBuf.h" -#include "fpgaloader.h" +#include "fpga_loader.h" +#include "fpga_apis.h" #include "string.h" #include "dbprint.h" #include "protocols.h" diff --git a/armsrc/start.c b/armsrc/start.c index 63bddd7c7..95d802a31 100644 --- a/armsrc/start.c +++ b/armsrc/start.c @@ -18,9 +18,6 @@ // with the linker script. //----------------------------------------------------------------------------- -#ifndef __START_H -#define __START_H - #include "proxmark3_arm.h" #include "appmain.h" #ifdef WITH_COMPRESSION @@ -28,19 +25,32 @@ #endif #include "BigBuf.h" #include "string.h" -#include "ticks.h" +#include "ticks_apis.h" +#include "gpio_apis.h" +#include "sys_apis.h" extern common_area_t g_common_area; +// export by ldscript, is a fixed space in ram, the data from rom will copy and decompress(optional) to ram. extern uint32_t __data_src_start__[], __data_start__[], __data_end__[], __bss_start__[], __bss_end__[]; +// Define an empty unit test main program entry, +// and if the developer compiles the source file that implements the UnitTestMain function, +// this empty function will be automatically overwritten. +void __attribute__((weak)) UnitTestMain(void); +void UnitTestMain(void) { + // Nothing to do... + // In general, this function will be overridden. +} + #ifdef WITH_COMPRESSION static void uncompress_data_section(void) { int avail_in; memcpy(&avail_in, __data_src_start__, sizeof(int)); - int avail_out = (uint32_t)__data_end__ - (uint32_t)__data_start__; // uncompressed size. Correct. + // if compressed, the head 4byte of '.data' section will be uncompressed size. + int avail_out = (uint32_t) __data_end__ - (uint32_t) __data_start__; // uncompressed size. Correct. // uncompress data segment to RAM - char *p = (char *)__data_src_start__; - int res = LZ4_decompress_safe(p + 4, (char *)__data_start__, avail_in, avail_out); + char *p = (char *) __data_src_start__; + int res = LZ4_decompress_safe(p + 4, (char *) __data_start__, avail_in, avail_out); if (res < 0) { while (true) { LED_A_INV(); @@ -89,4 +99,3 @@ void Vector(void) { // Run App main loop AppMain(); } -#endif diff --git a/armsrc/thinfilm.c b/armsrc/thinfilm.c index b5a06bf11..96d8ef07d 100644 --- a/armsrc/thinfilm.c +++ b/armsrc/thinfilm.c @@ -23,8 +23,10 @@ #include "appmain.h" #include "BigBuf.h" #include "iso14443a.h" -#include "fpgaloader.h" -#include "ticks.h" +#include "fpga_loader.h" +#include "ticks_apis.h" +#include "fpga_apis.h" +#include "rssi_apis.h" #include "dbprint.h" #include "util.h" @@ -59,7 +61,7 @@ void ReadThinFilm(void) { #define SEC_F 0x00 static uint16_t ReadReaderField(void) { - return AvgAdc(ADC_CHAN_HF); + return AdcRssiAvg(ADC_RSSI_CH_HF); } static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) { @@ -86,34 +88,35 @@ static int EmSendCmdThinfilmRaw(const uint8_t *resp, uint16_t respLen) { uint32_t ThisTransferTime ; // clear receiving shift register and holding register - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); - b = AT91C_BASE_SSC->SSC_RHR; + FPGA_SSC_RX_READY_WAIT(); + b = FPGA_SSC_RX_Value(); (void) b; // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never - while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); - if (AT91C_BASE_SSC->SSC_RHR) { + FPGA_SSC_RX_READY_WAIT(); + if (FPGA_SSC_RX_Value()) { break; } } while ((ThisTransferTime = GetCountSspClk()) & 0x00000007); // Clear TXRDY: - AT91C_BASE_SSC->SSC_THR = SEC_F; + FPGA_SSC_TX_Value(SEC_F); uint16_t FpgaSendQueueDelay = 0; // send cycle size_t i = 0; for (; i < respLen;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = resp[i++]; - FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(resp[i++]); + FPGA_SSC_RX_READY_WAIT(); + FpgaSendQueueDelay = (uint8_t)FPGA_SSC_RX_Value(); } - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); + if (FPGA_SSC_RX_Ready()) { + b = (uint8_t)(FPGA_SSC_RX_Value()); (void)b; } if (BUTTON_PRESS()) break; @@ -124,9 +127,10 @@ static int EmSendCmdThinfilmRaw(const uint8_t *resp, uint16_t respLen) { fpga_queued_bits >>= 3; // divide by 8 (again?) fpga_queued_bits += 1u; for (i = 0; i <= fpga_queued_bits;) { - if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = SEC_F; - FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if (FPGA_SSC_TX_Ready()) { + FPGA_SSC_TX_Value(SEC_F); + FPGA_SSC_RX_READY_WAIT(); + FpgaSendQueueDelay = (uint8_t)FPGA_SSC_RX_Value(); i++; } } @@ -147,7 +151,7 @@ void SimulateThinFilm(uint8_t *data, size_t len) { Dbprintf("Simulate " _YELLOW_("%i-bit Thinfilm") " tag", len * 8); // connect Demodulated Signal to ADC: - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + SetAdcMuxFor(ADC_MUXSEL_HIPKD); // Set up the synchronous serial port FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER); @@ -185,14 +189,12 @@ void SimulateThinFilm(uint8_t *data, size_t len) { uint16_t hf_av = ReadReaderField(); + /* TODO DXL: Do not use the ADC value directly, which will result in cross platform failure. if (hf_av < hf_baseline) { hf_baseline = hf_av; } - if (hf_av > hf_baseline + 10) { - EmSendCmdThinfilmRaw(ts->buf, ts->max); - if (len == 16) { // wait 3.6ms SpinDelayUs(3600); @@ -201,6 +203,23 @@ void SimulateThinFilm(uint8_t *data, size_t len) { SpinDelayUs(2400); } } + */ + + if (hf_av < hf_baseline) { + hf_baseline = hf_av; + } else if (hf_av > hf_baseline) { + if (AdcRssiDataToMilliVolt(hf_av - hf_baseline, ADC_RSSI_CH_HF) > 1375) { + EmSendCmdThinfilmRaw(ts->buf, ts->max); + if (len == 16) { + // wait 3.6ms + SpinDelayUs(3600); + } else { + // wait 2.4ms + SpinDelayUs(2400); + } + } + } + } LED_A_OFF(); diff --git a/armsrc/util.c b/armsrc/util.c index 0df89352d..c41c0c57a 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -19,11 +19,11 @@ #include "util.h" #include "proxmark3_arm.h" -#include "ticks.h" +#include "ticks_apis.h" #include "commonutil.h" #include "dbprint.h" #include "string.h" -#include "usb_cdc.h" +#include "usb_cdc_apis.h" #include "usart.h" size_t nbytes(size_t nbits) { @@ -231,37 +231,25 @@ void SpinUp(uint32_t speed) { LED_D_OFF(); } - // Determine if a button is double clicked, single clicked, // not clicked, or held down (for ms || 1sec) // In general, don't use this function unless you expect a // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead +// Note: StartTickCount required. int BUTTON_CLICKED(int ms) { - // Up to 500ms in between clicks to mean a double click - // timer counts in 21.3us increments (1024/48MHz) - // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) - if (ms > 1390) { - if (g_dbglevel >= DBG_ERROR) Dbprintf(_RED_("Error, BUTTON_CLICKED called with %i > 1390"), ms); - ms = 1390; - } - int ticks = ((MCK / 1000) * (ms ? ms : 1000)) >> 10; - // If we're not even pressed, forget about it! if (BUTTON_PRESS() == false) return BUTTON_NO_CLICK; - // Borrow a PWM unit for my real-time clock - AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); - // 48 MHz / 1024 gives 46.875 kHz - AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); - AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; - AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; - - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + ms = ms ? ms : 1000; // use ms param if valid. int letoff = 0; for (;;) { - uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + + // Using a very short delay period to count how long has passed is much safer than using other methods, + // as other timers may be stopped/reset + SpinDelay(1); + --ms; // We haven't let off the button yet if (!letoff) { @@ -269,15 +257,14 @@ int BUTTON_CLICKED(int ms) { if (BUTTON_PRESS() == false) { letoff = 1; - // reset our timer for 500ms - start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; - ticks = ((MCK / 1000) * (500)) >> 10; + // reset our timer for 500ms next press waiting + ms = 500; } // Still haven't let it off else // Have we held down a full second? - if (now == (uint16_t)(start + ticks)) + if (ms <= 0) return BUTTON_HOLD; } @@ -287,8 +274,8 @@ int BUTTON_CLICKED(int ms) { if (BUTTON_PRESS()) return BUTTON_DOUBLE_CLICK; - // Have we ran out of time to double click? - else if (now == (uint16_t)(start + ticks)) + // Have we ran out of time to double click? + else if (ms <= 0) // At least we did a single click return BUTTON_SINGLE_CLICK; @@ -300,40 +287,29 @@ int BUTTON_CLICKED(int ms) { } // Determine if a button is held down +// Note: StartTickCount required. int BUTTON_HELD(int ms) { - // timer counts in 21.3us increments (1024/48MHz) - // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) - if (ms > 1390) { - if (g_dbglevel >= DBG_ERROR) Dbprintf(_RED_("Error, BUTTON_HELD called with %i > 1390"), ms); - ms = 1390; - } - // If button is held for one second - int ticks = (48000 * (ms ? ms : 1000)) >> 10; - // If we're not even pressed, forget about it! if (BUTTON_PRESS() == false) { return BUTTON_NO_CLICK; } - // Borrow a PWM unit for my real-time clock - AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); - // 48 MHz / 1024 gives 46.875 kHz - AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10); - AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; - AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff; - - uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + ms = ms ? ms : 1000; // use ms param if valid. for (;;) { - uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; // As soon as our button let go, we didn't hold long enough if (BUTTON_PRESS() == false) { return BUTTON_SINGLE_CLICK; } + // Using a very short delay period to count how long has passed is much safer than using other methods, + // as other timers may be stopped/reset + SpinDelay(1); + --ms; + // Have we waited the full second? - else if (now == (uint16_t)(start + ticks)) { + if (ms <= 0) { return BUTTON_HOLD; } @@ -365,37 +341,6 @@ bool data_available_fast(void) { #endif } -uint32_t flash_size_from_cidr(uint32_t cidr) { - uint8_t nvpsiz = (cidr & 0xF00) >> 8; - switch (nvpsiz) { - case 0: - return 0; - case 1: - return 8 * 1024; - case 2: - return 16 * 1024; - case 3: - return 32 * 1024; - case 5: - return 64 * 1024; - case 7: - return 128 * 1024; - case 9: - return 256 * 1024; - case 10: - return 512 * 1024; - case 12: - return 1024 * 1024; - case 14: - default: // for 'reserved' values, guess 2MB - return 2048 * 1024; - } -} - -uint32_t get_flash_size(void) { - return flash_size_from_cidr(*AT91C_DBGU_CIDR); -} - // Combined function to convert an unsigned int to an array of hex values corresponding to the last three bits of k1 void convertToHexArray(uint32_t num, uint8_t *partialkey) { char binaryStr[25]; // 24 bits for binary representation + 1 for null terminator diff --git a/armsrc/util.h b/armsrc/util.h index fd99ac73e..d69e754d3 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -30,11 +30,11 @@ // Basic macros #ifndef SHORT_COIL -#define SHORT_COIL() LOW(GPIO_SSC_DOUT) +#define SHORT_COIL() Gpio_SSC_DOUT_Low() #endif #ifndef OPEN_COIL -#define OPEN_COIL() HIGH(GPIO_SSC_DOUT) +#define OPEN_COIL() Gpio_SSC_DOUT_High() #endif #ifndef BYTEx @@ -102,7 +102,4 @@ int BUTTON_HELD(int ms); bool data_available(void); bool data_available_fast(void); -uint32_t flash_size_from_cidr(uint32_t cidr); -uint32_t get_flash_size(void); - #endif diff --git a/include/hitag.h b/include/hitag.h index 850ea68be..e6b4175e9 100644 --- a/include/hitag.h +++ b/include/hitag.h @@ -71,7 +71,7 @@ typedef enum modulation { AC4K, // Amplitude modulation 4000 bits/s MC4K, // Manchester modulation 4000 bits/s MC8K // Manchester modulation 8000 bits/s -} MOD; +} hitag_mod_t; typedef enum { HTSF_PLAIN,