mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-09-26 00:14:20 +00:00
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
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
@@ -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 <string.h> // memcmp
|
||||
#include "mifareutil.h"
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -18,11 +18,12 @@
|
||||
// main code for legic prime simulator aka LEGICSIM
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <inttypes.h>
|
||||
#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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
/*
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
// main code for mifare classic simulator aka MFCSIM
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <inttypes.h>
|
||||
#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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
#include <inttypes.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 "commonutil.h"
|
||||
#include "mifarecmd.h"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
// main code for EM4x50 simulator and collector aka THAREXDE
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <inttypes.h>
|
||||
#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) {
|
||||
|
||||
+423
-98
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+17
-1
@@ -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)
|
||||
|
||||
+103
-94
@@ -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 <pl> corresponds to given length <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 <maxperiods> 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
|
||||
|
||||
+51
-18
@@ -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());
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
+24
-23
@@ -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());
|
||||
|
||||
|
||||
+5
-4
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
+11
-9
@@ -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++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+19
-23
@@ -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;
|
||||
|
||||
+19
-18
@@ -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
|
||||
|
||||
+12
-11
@@ -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);
|
||||
|
||||
|
||||
+345
-263
@@ -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();
|
||||
}
|
||||
|
||||
+15
-4
@@ -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
|
||||
|
||||
+16
-13
@@ -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);
|
||||
|
||||
+28
-41
@@ -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
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
+3
-2
@@ -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"
|
||||
|
||||
|
||||
+3
-2
@@ -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)
|
||||
|
||||
+74
-54
@@ -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
|
||||
|
||||
+64
-73
@@ -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);
|
||||
|
||||
+44
-66
@@ -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();
|
||||
|
||||
+12
-12
@@ -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();
|
||||
|
||||
+11
-11
@@ -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();
|
||||
|
||||
+111
-76
@@ -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;
|
||||
}
|
||||
|
||||
+26
-3
@@ -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);
|
||||
|
||||
+46
-27
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+23
-20
@@ -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) {
|
||||
|
||||
+7
-6
@@ -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
|
||||
|
||||
+5
-4
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+7
-8
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+3
-2
@@ -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"
|
||||
|
||||
+5
-4
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -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"
|
||||
|
||||
+17
-8
@@ -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
|
||||
|
||||
+39
-20
@@ -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();
|
||||
|
||||
+22
-77
@@ -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
|
||||
|
||||
+2
-5
@@ -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
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user