mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
MAJOR update, added hitag2 reader, emulation and eavesdropping, lots of new code, including FPGA tweaks, part 2
This commit is contained in:
parent
db09cb3adb
commit
d19929cbe8
18 changed files with 1355 additions and 454 deletions
|
@ -10,7 +10,7 @@ APP_INCLUDES = apps.h
|
||||||
|
|
||||||
#remove one of the following defines and comment out the relevant line
|
#remove one of the following defines and comment out the relevant line
|
||||||
#in the next section to remove that particular feature from compilation
|
#in the next section to remove that particular feature from compilation
|
||||||
APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF
|
APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG
|
||||||
#-DWITH_LCD
|
#-DWITH_LCD
|
||||||
|
|
||||||
#SRC_LCD = fonts.c LCD.c
|
#SRC_LCD = fonts.c LCD.c
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "legicrf.h"
|
#include "legicrf.h"
|
||||||
|
#include <hitag2.h>
|
||||||
|
|
||||||
#ifdef WITH_LCD
|
#ifdef WITH_LCD
|
||||||
# include "fonts.h"
|
# include "fonts.h"
|
||||||
|
@ -125,7 +126,7 @@ void Dbprintf(const char *fmt, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// prints HEX & ASCII
|
// prints HEX & ASCII
|
||||||
void Dbhexdump(int len, uint8_t *d) {
|
void Dbhexdump(int len, uint8_t *d, bool bAsci) {
|
||||||
int l=0,i;
|
int l=0,i;
|
||||||
char ascii[9];
|
char ascii[9];
|
||||||
|
|
||||||
|
@ -140,7 +141,11 @@ void Dbhexdump(int len, uint8_t *d) {
|
||||||
for (i=0;i<l;i++)
|
for (i=0;i<l;i++)
|
||||||
if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
|
if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
|
||||||
|
|
||||||
Dbprintf("%-8s %*D",ascii,l,d," ");
|
if (bAsci) {
|
||||||
|
Dbprintf("%-8s %*D",ascii,l,d," ");
|
||||||
|
} else {
|
||||||
|
Dbprintf("%*D",l,d," ");
|
||||||
|
}
|
||||||
|
|
||||||
len-=8;
|
len-=8;
|
||||||
d+=8;
|
d+=8;
|
||||||
|
@ -185,14 +190,15 @@ int AvgAdc(int ch) // was static - merlok
|
||||||
|
|
||||||
void MeasureAntennaTuning(void)
|
void MeasureAntennaTuning(void)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
|
||||||
int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
|
int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
|
||||||
int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
|
int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
|
||||||
|
|
||||||
UsbCommand c;
|
UsbCommand c;
|
||||||
|
|
||||||
DbpString("Measuring antenna characteristics, please wait.");
|
LED_B_ON();
|
||||||
memset(BigBuf,0,sizeof(BigBuf));
|
DbpString("Measuring antenna characteristics, please wait...");
|
||||||
|
memset(dest,0,sizeof(FREE_BUFFER_SIZE));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sweeps the useful LF range of the proxmark from
|
* Sweeps the useful LF range of the proxmark from
|
||||||
|
@ -202,8 +208,10 @@ void MeasureAntennaTuning(void)
|
||||||
* the resonating frequency of your LF antenna
|
* the resonating frequency of your LF antenna
|
||||||
* ( hopefully around 95 if it is tuned to 125kHz!)
|
* ( hopefully around 95 if it is tuned to 125kHz!)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
|
||||||
for (i=255; i>19; i--) {
|
for (i=255; i>19; i--) {
|
||||||
|
WDT_HIT();
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
||||||
SpinDelay(20);
|
SpinDelay(20);
|
||||||
// Vref = 3.3V, and a 10000:240 voltage divider on the input
|
// Vref = 3.3V, and a 10000:240 voltage divider on the input
|
||||||
|
@ -221,6 +229,7 @@ void MeasureAntennaTuning(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
|
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||||
SpinDelay(20);
|
SpinDelay(20);
|
||||||
|
@ -232,7 +241,14 @@ void MeasureAntennaTuning(void)
|
||||||
c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
|
c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
|
||||||
c.arg[1] = vHf;
|
c.arg[1] = vHf;
|
||||||
c.arg[2] = peakf | (peakv << 16);
|
c.arg[2] = peakf | (peakv << 16);
|
||||||
|
|
||||||
|
DbpString("Measuring complete, sending report back to host");
|
||||||
|
|
||||||
UsbSendPacket((uint8_t *)&c, sizeof(c));
|
UsbSendPacket((uint8_t *)&c, sizeof(c));
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LED_A_OFF();
|
||||||
|
LED_B_OFF();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeasureAntennaTuningHf(void)
|
void MeasureAntennaTuningHf(void)
|
||||||
|
@ -258,8 +274,7 @@ void MeasureAntennaTuningHf(void)
|
||||||
|
|
||||||
void SimulateTagHfListen(void)
|
void SimulateTagHfListen(void)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
|
||||||
int n = sizeof(BigBuf);
|
|
||||||
uint8_t v = 0;
|
uint8_t v = 0;
|
||||||
int i;
|
int i;
|
||||||
int p = 0;
|
int p = 0;
|
||||||
|
@ -293,7 +308,7 @@ void SimulateTagHfListen(void)
|
||||||
p = 0;
|
p = 0;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(i >= n) {
|
if(i >= FREE_BUFFER_SIZE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,6 +659,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_HITAG
|
||||||
|
case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type
|
||||||
|
SnoopHitag(c->arg[0]);
|
||||||
|
break;
|
||||||
|
case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content
|
||||||
|
SimulateHitagTag((bool)c->arg[0],(byte_t*)c->d.asBytes);
|
||||||
|
break;
|
||||||
|
case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function
|
||||||
|
ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ISO15693
|
#ifdef WITH_ISO15693
|
||||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
|
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
|
||||||
AcquireRawAdcSamplesIso15693();
|
AcquireRawAdcSamplesIso15693();
|
||||||
|
@ -822,16 +849,14 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
UsbSendPacket((uint8_t *)&n, sizeof(n));
|
UsbSendPacket((uint8_t *)&n, sizeof(n));
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
} break;
|
||||||
}
|
|
||||||
|
|
||||||
case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
|
case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
|
||||||
uint8_t *b = (uint8_t *)BigBuf;
|
uint8_t *b = (uint8_t *)BigBuf;
|
||||||
memcpy(b+c->arg[0], c->d.asBytes, 48);
|
memcpy(b+c->arg[0], c->d.asBytes, 48);
|
||||||
//Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
|
//Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
|
||||||
UsbSendPacket((uint8_t*)&ack, sizeof(ack));
|
UsbSendPacket((uint8_t*)&ack, sizeof(ack));
|
||||||
break;
|
} break;
|
||||||
}
|
|
||||||
|
|
||||||
case CMD_READ_MEM:
|
case CMD_READ_MEM:
|
||||||
ReadMem(c->arg[0]);
|
ReadMem(c->arg[0]);
|
||||||
|
@ -854,10 +879,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
SendVersion();
|
SendVersion();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef WITH_LF
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_LCD
|
#ifdef WITH_LCD
|
||||||
case CMD_LCD_RESET:
|
case CMD_LCD_RESET:
|
||||||
LCDReset();
|
LCDReset();
|
||||||
|
@ -868,7 +889,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
#endif
|
#endif
|
||||||
case CMD_SETUP_WRITE:
|
case CMD_SETUP_WRITE:
|
||||||
case CMD_FINISH_WRITE:
|
case CMD_FINISH_WRITE:
|
||||||
case CMD_HARDWARE_RESET:
|
case CMD_HARDWARE_RESET: {
|
||||||
USB_D_PLUS_PULLUP_OFF();
|
USB_D_PLUS_PULLUP_OFF();
|
||||||
SpinDelay(1000);
|
SpinDelay(1000);
|
||||||
SpinDelay(1000);
|
SpinDelay(1000);
|
||||||
|
@ -876,16 +897,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
for(;;) {
|
for(;;) {
|
||||||
// We're going to reset, and the bootrom will take control.
|
// We're going to reset, and the bootrom will take control.
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case CMD_START_FLASH:
|
case CMD_START_FLASH: {
|
||||||
if(common_area.flags.bootrom_present) {
|
if(common_area.flags.bootrom_present) {
|
||||||
common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
|
common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
|
||||||
}
|
}
|
||||||
USB_D_PLUS_PULLUP_OFF();
|
USB_D_PLUS_PULLUP_OFF();
|
||||||
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
|
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
|
||||||
for(;;);
|
for(;;);
|
||||||
break;
|
} break;
|
||||||
|
|
||||||
case CMD_DEVICE_INFO: {
|
case CMD_DEVICE_INFO: {
|
||||||
UsbCommand c;
|
UsbCommand c;
|
||||||
|
@ -893,11 +914,11 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
c.arg[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
|
c.arg[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
|
||||||
if(common_area.flags.bootrom_present) c.arg[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
|
if(common_area.flags.bootrom_present) c.arg[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
|
||||||
UsbSendPacket((uint8_t*)&c, sizeof(c));
|
UsbSendPacket((uint8_t*)&c, sizeof(c));
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
default:
|
default: {
|
||||||
Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
|
Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
typedef unsigned char byte_t;
|
#include "common.h"
|
||||||
|
#include "hitag2.h"
|
||||||
|
|
||||||
// The large multi-purpose buffer, typically used to hold A/D samples,
|
// The large multi-purpose buffer, typically used to hold A/D samples,
|
||||||
// maybe processed in some way.
|
// maybe processed in some way.
|
||||||
|
@ -49,7 +50,7 @@ void SamyRun(void);
|
||||||
//void DbpIntegers(int a, int b, int c);
|
//void DbpIntegers(int a, int b, int c);
|
||||||
void DbpString(char *str);
|
void DbpString(char *str);
|
||||||
void Dbprintf(const char *fmt, ...);
|
void Dbprintf(const char *fmt, ...);
|
||||||
void Dbhexdump(int len, uint8_t *d);
|
void Dbhexdump(int len, uint8_t *d, bool bAsci);
|
||||||
|
|
||||||
int AvgAdc(int ch);
|
int AvgAdc(int ch);
|
||||||
|
|
||||||
|
@ -69,13 +70,9 @@ void FpgaDownloadAndGo(void);
|
||||||
void FpgaGatherVersion(char *dst, int len);
|
void FpgaGatherVersion(char *dst, int len);
|
||||||
void FpgaSetupSsc(void);
|
void FpgaSetupSsc(void);
|
||||||
void SetupSpi(int mode);
|
void SetupSpi(int mode);
|
||||||
void FpgaSetupSscDma(uint8_t *buf, int len);
|
bool FpgaSetupSscDma(uint8_t *buf, int len);
|
||||||
void inline FpgaDisableSscDma(void){
|
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||||
}
|
|
||||||
void inline FpgaEnableSscDma(void){
|
|
||||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
|
||||||
}
|
|
||||||
void SetAdcMuxFor(uint32_t whichGpio);
|
void SetAdcMuxFor(uint32_t whichGpio);
|
||||||
|
|
||||||
// Definitions for the FPGA commands.
|
// Definitions for the FPGA commands.
|
||||||
|
@ -83,19 +80,21 @@ void SetAdcMuxFor(uint32_t whichGpio);
|
||||||
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
#define FPGA_CMD_SET_DIVISOR (2<<12)
|
||||||
// Definitions for the FPGA configuration word.
|
// Definitions for the FPGA configuration word.
|
||||||
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
|
#define FPGA_MAJOR_MODE_LF_READER (0<<5)
|
||||||
#define FPGA_MAJOR_MODE_LF_SIMULATOR (1<<5)
|
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_READER_TX (2<<5)
|
#define FPGA_MAJOR_MODE_HF_READER_TX (2<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (3<<5)
|
#define FPGA_MAJOR_MODE_HF_READER_RX_XCORR (3<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_SIMULATOR (4<<5)
|
#define FPGA_MAJOR_MODE_HF_SIMULATOR (4<<5)
|
||||||
#define FPGA_MAJOR_MODE_HF_ISO14443A (5<<5)
|
#define FPGA_MAJOR_MODE_HF_ISO14443A (5<<5)
|
||||||
#define FPGA_MAJOR_MODE_LF_PASSTHRU (6<<5)
|
#define FPGA_MAJOR_MODE_LF_PASSTHRU (6<<5)
|
||||||
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
#define FPGA_MAJOR_MODE_OFF (7<<5)
|
||||||
|
// Options for LF_EDGE_DETECT
|
||||||
|
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
|
||||||
// Options for the HF reader, tx to tag
|
// Options for the HF reader, tx to tag
|
||||||
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
|
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
|
||||||
// Options for the HF reader, correlating against rx from tag
|
// Options for the HF reader, correlating against rx from tag
|
||||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
||||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||||
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
||||||
// Options for the HF simulated tag, how to modulate
|
// Options for the HF simulated tag, how to modulate
|
||||||
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
|
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
|
||||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
||||||
|
@ -139,7 +138,7 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
|
||||||
int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
|
int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
|
||||||
uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
|
uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
|
||||||
void iso14a_set_trigger(int enable);
|
void iso14a_set_trigger(int enable);
|
||||||
void iso14a_clear_tracelen(void);
|
void iso14a_clear_trace(void);
|
||||||
void iso14a_set_tracing(int enable);
|
void iso14a_set_tracing(int enable);
|
||||||
void RAMFUNC SniffMifare(uint8_t param);
|
void RAMFUNC SniffMifare(uint8_t param);
|
||||||
|
|
||||||
|
@ -176,6 +175,11 @@ void RAMFUNC SnoopIClass(void);
|
||||||
void SimulateIClass(uint8_t arg0, uint8_t *datain);
|
void SimulateIClass(uint8_t arg0, uint8_t *datain);
|
||||||
void ReaderIClass(uint8_t arg0);
|
void ReaderIClass(uint8_t arg0);
|
||||||
|
|
||||||
|
// hitag2.h
|
||||||
|
void SnoopHitag(uint32_t type);
|
||||||
|
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
|
||||||
|
void ReaderHitag(hitag_function htf, hitag_data* htd);
|
||||||
|
|
||||||
/// util.h
|
/// util.h
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -136,18 +136,20 @@ void FpgaSetupSsc(void)
|
||||||
// ourselves, not to another buffer). The stuff to manipulate those buffers
|
// ourselves, not to another buffer). The stuff to manipulate those buffers
|
||||||
// is in apps.h, because it should be inlined, for speed.
|
// is in apps.h, because it should be inlined, for speed.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void FpgaSetupSscDma(uint8_t *buf, int len)
|
bool FpgaSetupSscDma(uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
if (buf == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf;
|
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RCR = len;
|
AT91C_BASE_PDC_SSC->PDC_RCR = len;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf;
|
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RNCR = len;
|
AT91C_BASE_PDC_SSC->PDC_RNCR = len;
|
||||||
|
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||||
|
|
||||||
if (buf != NULL) {
|
return true;
|
||||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DownloadFPGA_byte(unsigned char w)
|
static void DownloadFPGA_byte(unsigned char w)
|
||||||
|
|
1267
armsrc/hitag2.c
1267
armsrc/hitag2.c
File diff suppressed because it is too large
Load diff
|
@ -691,7 +691,7 @@ void RAMFUNC SnoopIClass(void)
|
||||||
|
|
||||||
// reset traceLen to 0
|
// reset traceLen to 0
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
iso14a_set_trigger(FALSE);
|
iso14a_set_trigger(FALSE);
|
||||||
|
|
||||||
// The DMA buffer, used to stream samples from the FPGA
|
// The DMA buffer, used to stream samples from the FPGA
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
|
|
||||||
static uint32_t iso14a_timeout;
|
static uint32_t iso14a_timeout;
|
||||||
uint8_t *trace = (uint8_t *) BigBuf;
|
uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET;
|
||||||
int traceLen = 0;
|
int traceLen = 0;
|
||||||
int rsamples = 0;
|
int rsamples = 0;
|
||||||
int tracing = TRUE;
|
int tracing = TRUE;
|
||||||
|
@ -68,12 +68,15 @@ void iso14a_set_trigger(int enable) {
|
||||||
trigger = enable;
|
trigger = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso14a_clear_tracelen(void) {
|
void iso14a_clear_trace(void) {
|
||||||
|
memset(trace, 0x44, TRACE_SIZE);
|
||||||
traceLen = 0;
|
traceLen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso14a_set_tracing(int enable) {
|
void iso14a_set_tracing(int enable) {
|
||||||
tracing = enable;
|
tracing = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso14a_set_timeout(uint32_t timeout) {
|
void iso14a_set_timeout(uint32_t timeout) {
|
||||||
iso14a_timeout = timeout;
|
iso14a_timeout = timeout;
|
||||||
}
|
}
|
||||||
|
@ -580,8 +583,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
// init trace buffer
|
// init trace buffer
|
||||||
traceLen = 0;
|
iso14a_clear_trace();
|
||||||
memset(trace, 0x44, TRACE_SIZE);
|
|
||||||
|
|
||||||
// We won't start recording the frames that we acquire until we trigger;
|
// We won't start recording the frames that we acquire until we trigger;
|
||||||
// a good trigger condition to get started is probably when we see a
|
// a good trigger condition to get started is probably when we see a
|
||||||
|
@ -905,8 +907,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
|
||||||
{
|
{
|
||||||
// Enable and clear the trace
|
// Enable and clear the trace
|
||||||
tracing = TRUE;
|
tracing = TRUE;
|
||||||
traceLen = 0;
|
iso14a_clear_trace();
|
||||||
memset(trace, 0x44, TRACE_SIZE);
|
|
||||||
|
|
||||||
// This function contains the tag emulation
|
// This function contains the tag emulation
|
||||||
uint8_t sak;
|
uint8_t sak;
|
||||||
|
@ -2379,8 +2380,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
// C(red) A(yellow) B(green)
|
// C(red) A(yellow) B(green)
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
// init trace buffer
|
// init trace buffer
|
||||||
traceLen = 0;
|
iso14a_clear_trace();
|
||||||
memset(trace, 0x44, TRACE_SIZE);
|
|
||||||
|
|
||||||
// The command (reader -> tag) that we're receiving.
|
// The command (reader -> tag) that we're receiving.
|
||||||
// The length of a received command will in most cases be no more than 18 bytes.
|
// The length of a received command will in most cases be no more than 18 bytes.
|
||||||
|
|
|
@ -1102,7 +1102,7 @@ void ReaderIso15693(uint32_t parameter)
|
||||||
|
|
||||||
Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
|
Dbprintf("%d octets read from IDENTIFY request:", answerLen1);
|
||||||
DbdecodeIso15693Answer(answerLen1,answer1);
|
DbdecodeIso15693Answer(answerLen1,answer1);
|
||||||
Dbhexdump(answerLen1,answer1);
|
Dbhexdump(answerLen1,answer1,true);
|
||||||
|
|
||||||
// UID is reverse
|
// UID is reverse
|
||||||
if (answerLen1>=12)
|
if (answerLen1>=12)
|
||||||
|
@ -1113,11 +1113,11 @@ void ReaderIso15693(uint32_t parameter)
|
||||||
|
|
||||||
Dbprintf("%d octets read from SELECT request:", answerLen2);
|
Dbprintf("%d octets read from SELECT request:", answerLen2);
|
||||||
DbdecodeIso15693Answer(answerLen2,answer2);
|
DbdecodeIso15693Answer(answerLen2,answer2);
|
||||||
Dbhexdump(answerLen2,answer2);
|
Dbhexdump(answerLen2,answer2,true);
|
||||||
|
|
||||||
Dbprintf("%d octets read from XXX request:", answerLen3);
|
Dbprintf("%d octets read from XXX request:", answerLen3);
|
||||||
DbdecodeIso15693Answer(answerLen3,answer3);
|
DbdecodeIso15693Answer(answerLen3,answer3);
|
||||||
Dbhexdump(answerLen3,answer3);
|
Dbhexdump(answerLen3,answer3,true);
|
||||||
|
|
||||||
|
|
||||||
// read all pages
|
// read all pages
|
||||||
|
@ -1130,7 +1130,7 @@ void ReaderIso15693(uint32_t parameter)
|
||||||
if (answerLen2>0) {
|
if (answerLen2>0) {
|
||||||
Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
|
Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
|
||||||
DbdecodeIso15693Answer(answerLen2,answer2);
|
DbdecodeIso15693Answer(answerLen2,answer2);
|
||||||
Dbhexdump(answerLen2,answer2);
|
Dbhexdump(answerLen2,answer2,true);
|
||||||
if ( *((uint32_t*) answer2) == 0x07160101 ) break; // exit on NoPageErr
|
if ( *((uint32_t*) answer2) == 0x07160101 ) break; // exit on NoPageErr
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -1264,7 +1264,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Dbprintf("SEND");
|
Dbprintf("SEND");
|
||||||
Dbhexdump(datalen,data);
|
Dbhexdump(datalen,data,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
|
recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
|
||||||
|
@ -1280,7 +1280,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Dbprintf("RECV");
|
Dbprintf("RECV");
|
||||||
DbdecodeIso15693Answer(recvlen,recvbuf);
|
DbdecodeIso15693Answer(recvlen,recvbuf);
|
||||||
Dbhexdump(recvlen,recvbuf);
|
Dbhexdump(recvlen,recvbuf,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
190
armsrc/lfops.c
190
armsrc/lfops.c
|
@ -434,7 +434,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
||||||
int i;
|
int i;
|
||||||
uint8_t *tab = (uint8_t *)BigBuf;
|
uint8_t *tab = (uint8_t *)BigBuf;
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||||
|
|
||||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
|
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
|
||||||
|
|
||||||
|
@ -484,197 +484,9 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Provides a framework for bidirectional LF tag communication
|
|
||||||
* Encoding is currently Hitag2, but the general idea can probably
|
|
||||||
* be transferred to other encodings.
|
|
||||||
*
|
|
||||||
* The new FPGA code will, for the LF simulator mode, give on SSC_FRAME
|
|
||||||
* (PA15) a thresholded version of the signal from the ADC. Setting the
|
|
||||||
* ADC path to the low frequency peak detection signal, will enable a
|
|
||||||
* somewhat reasonable receiver for modulation on the carrier signal
|
|
||||||
* that is generated by the reader. The signal is low when the reader
|
|
||||||
* field is switched off, and high when the reader field is active. Due
|
|
||||||
* to the way that the signal looks like, mostly only the rising edge is
|
|
||||||
* useful, your mileage may vary.
|
|
||||||
*
|
|
||||||
* Neat perk: PA15 can not only be used as a bit-banging GPIO, but is also
|
|
||||||
* TIOA1, which can be used as the capture input for timer 1. This should
|
|
||||||
* make it possible to measure the exact edge-to-edge time, without processor
|
|
||||||
* intervention.
|
|
||||||
*
|
|
||||||
* Arguments: divisor is the divisor to be sent to the FPGA (e.g. 95 for 125kHz)
|
|
||||||
* t0 is the carrier frequency cycle duration in terms of MCK (384 for 125kHz)
|
|
||||||
*
|
|
||||||
* The following defines are in carrier periods:
|
|
||||||
*/
|
|
||||||
#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
|
|
||||||
#define HITAG_T_1_MIN 24 /* T[1] should be 26..30 */
|
|
||||||
#define HITAG_T_EOF 40 /* T_EOF should be > 36 */
|
|
||||||
#define HITAG_T_WRESP 208 /* T_wresp should be 204..212 */
|
|
||||||
|
|
||||||
static void hitag_handle_frame(int t0, int frame_len, char *frame);
|
|
||||||
//#define DEBUG_RA_VALUES 1
|
|
||||||
#define DEBUG_FRAME_CONTENTS 1
|
#define DEBUG_FRAME_CONTENTS 1
|
||||||
void SimulateTagLowFrequencyBidir(int divisor, int t0)
|
void SimulateTagLowFrequencyBidir(int divisor, int t0)
|
||||||
{
|
{
|
||||||
#if DEBUG_RA_VALUES || DEBUG_FRAME_CONTENTS
|
|
||||||
int i = 0;
|
|
||||||
#endif
|
|
||||||
char frame[10];
|
|
||||||
int frame_pos=0;
|
|
||||||
|
|
||||||
DbpString("Starting Hitag2 emulator, press button to end");
|
|
||||||
hitag2_init();
|
|
||||||
|
|
||||||
/* Set up simulator mode, frequency divisor which will drive the FPGA
|
|
||||||
* and analog mux selection.
|
|
||||||
*/
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
|
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
|
||||||
RELAY_OFF();
|
|
||||||
|
|
||||||
/* Set up Timer 1:
|
|
||||||
* Capture mode, timer source MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
|
||||||
* external trigger rising edge, load RA on rising edge of TIOA, load RB on rising
|
|
||||||
* edge of TIOA. Assign PA15 to TIOA1 (peripheral B)
|
|
||||||
*/
|
|
||||||
|
|
||||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
|
||||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
|
||||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK |
|
|
||||||
AT91C_TC_ETRGEDG_RISING |
|
|
||||||
AT91C_TC_ABETRG |
|
|
||||||
AT91C_TC_LDRA_RISING |
|
|
||||||
AT91C_TC_LDRB_RISING;
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN |
|
|
||||||
AT91C_TC_SWTRG;
|
|
||||||
|
|
||||||
/* calculate the new value for the carrier period in terms of TC1 values */
|
|
||||||
t0 = t0/2;
|
|
||||||
|
|
||||||
int overflow = 0;
|
|
||||||
while(!BUTTON_PRESS()) {
|
|
||||||
WDT_HIT();
|
|
||||||
if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
|
||||||
int ra = AT91C_BASE_TC1->TC_RA;
|
|
||||||
if((ra > t0*HITAG_T_EOF) | overflow) ra = t0*HITAG_T_EOF+1;
|
|
||||||
#if DEBUG_RA_VALUES
|
|
||||||
if(ra > 255 || overflow) ra = 255;
|
|
||||||
((char*)BigBuf)[i] = ra;
|
|
||||||
i = (i+1) % 8000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(overflow || (ra > t0*HITAG_T_EOF) || (ra < t0*HITAG_T_0_MIN)) {
|
|
||||||
/* Ignore */
|
|
||||||
} else if(ra >= t0*HITAG_T_1_MIN ) {
|
|
||||||
/* '1' bit */
|
|
||||||
if(frame_pos < 8*sizeof(frame)) {
|
|
||||||
frame[frame_pos / 8] |= 1<<( 7-(frame_pos%8) );
|
|
||||||
frame_pos++;
|
|
||||||
}
|
|
||||||
} else if(ra >= t0*HITAG_T_0_MIN) {
|
|
||||||
/* '0' bit */
|
|
||||||
if(frame_pos < 8*sizeof(frame)) {
|
|
||||||
frame[frame_pos / 8] |= 0<<( 7-(frame_pos%8) );
|
|
||||||
frame_pos++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
overflow = 0;
|
|
||||||
LED_D_ON();
|
|
||||||
} else {
|
|
||||||
if(AT91C_BASE_TC1->TC_CV > t0*HITAG_T_EOF) {
|
|
||||||
/* Minor nuisance: In Capture mode, the timer can not be
|
|
||||||
* stopped by a Compare C. There's no way to stop the clock
|
|
||||||
* in software, so we'll just have to note the fact that an
|
|
||||||
* overflow happened and the next loaded timer value might
|
|
||||||
* have wrapped. Also, this marks the end of frame, and the
|
|
||||||
* still running counter can be used to determine the correct
|
|
||||||
* time for the start of the reply.
|
|
||||||
*/
|
|
||||||
overflow = 1;
|
|
||||||
|
|
||||||
if(frame_pos > 0) {
|
|
||||||
/* Have a frame, do something with it */
|
|
||||||
#if DEBUG_FRAME_CONTENTS
|
|
||||||
((char*)BigBuf)[i++] = frame_pos;
|
|
||||||
memcpy( ((char*)BigBuf)+i, frame, 7);
|
|
||||||
i+=7;
|
|
||||||
i = i % sizeof(BigBuf);
|
|
||||||
#endif
|
|
||||||
hitag_handle_frame(t0, frame_pos, frame);
|
|
||||||
memset(frame, 0, sizeof(frame));
|
|
||||||
}
|
|
||||||
frame_pos = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
LED_D_OFF();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DbpString("All done");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hitag_send_bit(int t0, int bit) {
|
|
||||||
if(bit == 1) {
|
|
||||||
/* Manchester: Loaded, then unloaded */
|
|
||||||
LED_A_ON();
|
|
||||||
SHORT_COIL();
|
|
||||||
while(AT91C_BASE_TC1->TC_CV < t0*15);
|
|
||||||
OPEN_COIL();
|
|
||||||
while(AT91C_BASE_TC1->TC_CV < t0*31);
|
|
||||||
LED_A_OFF();
|
|
||||||
} else if(bit == 0) {
|
|
||||||
/* Manchester: Unloaded, then loaded */
|
|
||||||
LED_B_ON();
|
|
||||||
OPEN_COIL();
|
|
||||||
while(AT91C_BASE_TC1->TC_CV < t0*15);
|
|
||||||
SHORT_COIL();
|
|
||||||
while(AT91C_BASE_TC1->TC_CV < t0*31);
|
|
||||||
LED_B_OFF();
|
|
||||||
}
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset clock for the next bit */
|
|
||||||
|
|
||||||
}
|
|
||||||
static void hitag_send_frame(int t0, int frame_len, const char const * frame, int fdt)
|
|
||||||
{
|
|
||||||
OPEN_COIL();
|
|
||||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
|
||||||
|
|
||||||
/* Wait for HITAG_T_WRESP carrier periods after the last reader bit,
|
|
||||||
* not that since the clock counts since the rising edge, but T_wresp is
|
|
||||||
* with respect to the falling edge, we need to wait actually (T_wresp - T_g)
|
|
||||||
* periods. The gap time T_g varies (4..10).
|
|
||||||
*/
|
|
||||||
while(AT91C_BASE_TC1->TC_CV < t0*(fdt-8));
|
|
||||||
|
|
||||||
int saved_cmr = AT91C_BASE_TC1->TC_CMR;
|
|
||||||
AT91C_BASE_TC1->TC_CMR &= ~AT91C_TC_ETRGEDG; /* Disable external trigger for the clock */
|
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset the clock and use it for response timing */
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for(i=0; i<5; i++)
|
|
||||||
hitag_send_bit(t0, 1); /* Start of frame */
|
|
||||||
|
|
||||||
for(i=0; i<frame_len; i++) {
|
|
||||||
hitag_send_bit(t0, !!(frame[i/ 8] & (1<<( 7-(i%8) ))) );
|
|
||||||
}
|
|
||||||
|
|
||||||
OPEN_COIL();
|
|
||||||
AT91C_BASE_TC1->TC_CMR = saved_cmr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Callback structure to cleanly separate tag emulation code from the radio layer. */
|
|
||||||
static int hitag_cb(const char* response_data, const int response_length, const int fdt, void *cb_cookie)
|
|
||||||
{
|
|
||||||
hitag_send_frame(*(int*)cb_cookie, response_length, response_data, fdt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/* Frame length in bits, frame contents in MSBit first format */
|
|
||||||
static void hitag_handle_frame(int t0, int frame_len, char *frame)
|
|
||||||
{
|
|
||||||
hitag2_handle_command(frame, frame_len, hitag_cb, &t0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// compose fc/8 fc/10 waveform
|
// compose fc/8 fc/10 waveform
|
||||||
|
|
|
@ -35,7 +35,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
// iso14a_set_tracing(false);
|
// iso14a_set_tracing(false);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
@ -115,7 +115,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
// iso14a_set_tracing(false);
|
// iso14a_set_tracing(false);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
@ -213,7 +213,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
// iso14a_set_tracing(false);
|
// iso14a_set_tracing(false);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
@ -311,7 +311,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||||
for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11; // 11 - empty block;
|
for (i = 0; i < NES_MAX_INFO + 1; i++) nvectorcount[i] = 11; // 11 - empty block;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(false);
|
iso14a_set_tracing(false);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
@ -539,7 +539,7 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
MF_DBGLEVEL = MF_DBG_NONE;
|
MF_DBGLEVEL = MF_DBG_NONE;
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
@ -641,7 +641,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
uint8_t uid[8];
|
uint8_t uid[8];
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(false);
|
iso14a_set_tracing(false);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
@ -759,7 +759,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
|
|
||||||
if (workFlags & 0x08) {
|
if (workFlags & 0x08) {
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
@ -890,7 +890,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
|
|
||||||
if (workFlags & 0x08) {
|
if (workFlags & 0x08) {
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_tracelen();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
|
|
||||||
iso14443a_setup();
|
iso14443a_setup();
|
||||||
|
|
23
common/usb.c
23
common/usb.c
|
@ -401,12 +401,15 @@ void UsbSendPacket(uint8_t *packet, int len)
|
||||||
}
|
}
|
||||||
AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
|
AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
|
||||||
|
|
||||||
while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP))
|
while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)) {
|
||||||
;
|
WDT_HIT();
|
||||||
|
}
|
||||||
|
|
||||||
AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
|
AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
|
||||||
|
|
||||||
while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)
|
while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) {
|
||||||
;
|
WDT_HIT();
|
||||||
|
}
|
||||||
|
|
||||||
len -= thisTime;
|
len -= thisTime;
|
||||||
packet += thisTime;
|
packet += thisTime;
|
||||||
|
@ -426,8 +429,9 @@ static void HandleRxdData(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0;
|
AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0;
|
||||||
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0)
|
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
|
||||||
;
|
WDT_HIT();
|
||||||
|
}
|
||||||
|
|
||||||
if(UsbSoFarCount >= 64) {
|
if(UsbSoFarCount >= 64) {
|
||||||
UsbPacketReceived(UsbBuffer, UsbSoFarCount);
|
UsbPacketReceived(UsbBuffer, UsbSoFarCount);
|
||||||
|
@ -444,14 +448,17 @@ static void HandleRxdData(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1;
|
AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1;
|
||||||
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1)
|
while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
|
||||||
;
|
WDT_HIT();
|
||||||
|
}
|
||||||
|
|
||||||
if(UsbSoFarCount >= 64) {
|
if(UsbSoFarCount >= 64) {
|
||||||
UsbPacketReceived(UsbBuffer, UsbSoFarCount);
|
UsbPacketReceived(UsbBuffer, UsbSoFarCount);
|
||||||
UsbSoFarCount = 0;
|
UsbSoFarCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsbStart(void)
|
void UsbStart(void)
|
||||||
|
|
|
@ -6,7 +6,7 @@ clean:
|
||||||
$(DELETE) fpga.map fpga.ngc fpga_ngdbuild.xrpt fpga.pcf fpga-placed_pad.csv fpga-placed.ptwx fpga.rbt xlnx_auto_0_xdb
|
$(DELETE) fpga.map fpga.ngc fpga_ngdbuild.xrpt fpga.pcf fpga-placed_pad.csv fpga-placed.ptwx fpga.rbt xlnx_auto_0_xdb
|
||||||
$(DELETE) fpga.bld fpga.mrp fpga.ngc_xst.xrpt fpga.ngm fpga-placed.ncd fpga-placed_pad.txt fpga-placed.unroutes fpga_summary.xml netlist.lst xst
|
$(DELETE) fpga.bld fpga.mrp fpga.ngc_xst.xrpt fpga.ngm fpga-placed.ncd fpga-placed_pad.txt fpga-placed.unroutes fpga_summary.xml netlist.lst xst
|
||||||
|
|
||||||
fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_simulate.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
|
fpga.ngc: fpga.v fpga.ucf xst.scr util.v lo_edge_detect.v lo_read.v lo_passthru.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v
|
||||||
$(DELETE) fpga.ngc
|
$(DELETE) fpga.ngc
|
||||||
$(XILINX_TOOLS_PREFIX)xst -ifn xst.scr
|
$(XILINX_TOOLS_PREFIX)xst -ifn xst.scr
|
||||||
|
|
||||||
|
|
BIN
fpga/fpga.bit
BIN
fpga/fpga.bit
Binary file not shown.
11
fpga/fpga.v
11
fpga/fpga.v
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
`include "lo_read.v"
|
`include "lo_read.v"
|
||||||
`include "lo_passthru.v"
|
`include "lo_passthru.v"
|
||||||
`include "lo_simulate.v"
|
`include "lo_edge_detect.v"
|
||||||
`include "hi_read_tx.v"
|
`include "hi_read_tx.v"
|
||||||
`include "hi_read_rx_xcorr.v"
|
`include "hi_read_rx_xcorr.v"
|
||||||
`include "hi_simulate.v"
|
`include "hi_simulate.v"
|
||||||
|
@ -111,6 +111,10 @@ assign hi_read_rx_xcorr_quarter = conf_word[2];
|
||||||
wire [2:0] hi_simulate_mod_type;
|
wire [2:0] hi_simulate_mod_type;
|
||||||
assign hi_simulate_mod_type = conf_word[2:0];
|
assign hi_simulate_mod_type = conf_word[2:0];
|
||||||
|
|
||||||
|
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||||
|
wire lf_field;
|
||||||
|
assign lf_field = conf_word[0];
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// And then we instantiate the modules corresponding to each of the FPGA's
|
// And then we instantiate the modules corresponding to each of the FPGA's
|
||||||
// major modes, and use muxes to connect the outputs of the active mode to
|
// major modes, and use muxes to connect the outputs of the active mode to
|
||||||
|
@ -136,13 +140,14 @@ lo_passthru lp(
|
||||||
lp_dbg, divisor
|
lp_dbg, divisor
|
||||||
);
|
);
|
||||||
|
|
||||||
lo_simulate ls(
|
lo_edge_detect ls(
|
||||||
pck0, ck_1356meg, ck_1356megb,
|
pck0, ck_1356meg, ck_1356megb,
|
||||||
ls_pwr_lo, ls_pwr_hi, ls_pwr_oe1, ls_pwr_oe2, ls_pwr_oe3, ls_pwr_oe4,
|
ls_pwr_lo, ls_pwr_hi, ls_pwr_oe1, ls_pwr_oe2, ls_pwr_oe3, ls_pwr_oe4,
|
||||||
adc_d, ls_adc_clk,
|
adc_d, ls_adc_clk,
|
||||||
ls_ssp_frame, ls_ssp_din, ssp_dout, ls_ssp_clk,
|
ls_ssp_frame, ls_ssp_din, ssp_dout, ls_ssp_clk,
|
||||||
cross_hi, cross_lo,
|
cross_hi, cross_lo,
|
||||||
ls_dbg, divisor
|
ls_dbg, divisor,
|
||||||
|
lf_field
|
||||||
);
|
);
|
||||||
|
|
||||||
hi_read_tx ht(
|
hi_read_tx ht(
|
||||||
|
|
90
fpga/lo_edge_detect.v
Normal file
90
fpga/lo_edge_detect.v
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// The way that we connect things in low-frequency simulation mode. In this
|
||||||
|
// case just pass everything through to the ARM, which can bit-bang this
|
||||||
|
// (because it is so slow).
|
||||||
|
//
|
||||||
|
// Jonathan Westhues, April 2006
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module lo_edge_detect(
|
||||||
|
pck0, ck_1356meg, ck_1356megb,
|
||||||
|
pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4,
|
||||||
|
adc_d, adc_clk,
|
||||||
|
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||||
|
cross_hi, cross_lo,
|
||||||
|
dbg,
|
||||||
|
divisor,
|
||||||
|
lf_field
|
||||||
|
);
|
||||||
|
input pck0, ck_1356meg, ck_1356megb;
|
||||||
|
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||||
|
input [7:0] adc_d;
|
||||||
|
output adc_clk;
|
||||||
|
input ssp_dout;
|
||||||
|
output ssp_frame, ssp_din, ssp_clk;
|
||||||
|
input cross_hi, cross_lo;
|
||||||
|
output dbg;
|
||||||
|
input [7:0] divisor;
|
||||||
|
input lf_field;
|
||||||
|
|
||||||
|
// Divide the clock to be used for the ADC
|
||||||
|
reg [7:0] pck_divider;
|
||||||
|
reg clk_state;
|
||||||
|
|
||||||
|
wire tag_modulation;
|
||||||
|
assign tag_modulation = ssp_dout & !lf_field;
|
||||||
|
wire reader_modulation;
|
||||||
|
assign reader_modulation = !ssp_dout & lf_field & clk_state;
|
||||||
|
|
||||||
|
// No logic, straight through.
|
||||||
|
assign pwr_oe1 = 1'b0; // not used in LF mode
|
||||||
|
assign pwr_oe2 = tag_modulation;
|
||||||
|
assign pwr_oe3 = tag_modulation;
|
||||||
|
assign pwr_oe4 = tag_modulation;
|
||||||
|
assign ssp_clk = cross_lo;
|
||||||
|
assign pwr_lo = reader_modulation;
|
||||||
|
assign pwr_hi = 1'b0;
|
||||||
|
assign dbg = ssp_frame;
|
||||||
|
|
||||||
|
always @(posedge pck0)
|
||||||
|
begin
|
||||||
|
if(pck_divider == divisor[7:0])
|
||||||
|
begin
|
||||||
|
pck_divider <= 8'd0;
|
||||||
|
clk_state = !clk_state;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
pck_divider <= pck_divider + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign adc_clk = ~clk_state;
|
||||||
|
|
||||||
|
// Toggle the output with hysteresis
|
||||||
|
// Set to high if the ADC value is above 200
|
||||||
|
// Set to low if the ADC value is below 64
|
||||||
|
reg is_high;
|
||||||
|
reg is_low;
|
||||||
|
reg output_state;
|
||||||
|
|
||||||
|
always @(posedge pck0)
|
||||||
|
begin
|
||||||
|
if((pck_divider == 8'd7) && !clk_state) begin
|
||||||
|
is_high = (adc_d >= 8'd190);
|
||||||
|
is_low = (adc_d <= 8'd70);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge is_high or posedge is_low)
|
||||||
|
begin
|
||||||
|
if(is_high)
|
||||||
|
output_state <= 1'd1;
|
||||||
|
else if(is_low)
|
||||||
|
output_state <= 1'd0;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign ssp_frame = output_state;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define __COMMON_H
|
#define __COMMON_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
typedef unsigned char byte_t;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// ISO 14443A
|
// ISO 14443A
|
||||||
|
|
|
@ -1,19 +1,33 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
|
// (c) 2012 Roel Verdult
|
||||||
//
|
//
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
// the license.
|
// the license.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Hitag2 emulation public interface
|
// Hitag2 type prototyping
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef __HITAG2_H
|
#ifndef _HITAG2_H_
|
||||||
#define __HITAG2_H
|
#define _HITAG2_H_
|
||||||
|
|
||||||
typedef int (*hitag2_response_callback_t)(const char* response_data, const int response_length, const int fdt, void *cb_cookie);
|
typedef enum {
|
||||||
|
RHT2F_PASSWORD = 21,
|
||||||
|
RHT2F_AUTHENTICATE = 22,
|
||||||
|
RHT2F_TEST_AUTH_ATTEMPTS = 25,
|
||||||
|
} hitag_function;
|
||||||
|
|
||||||
extern int hitag2_init(void);
|
typedef struct {
|
||||||
extern int hitag2_handle_command(const char* data, const int length, hitag2_response_callback_t cb, void *cb_cookie);
|
byte_t password[4];
|
||||||
|
} PACKED rht2d_password;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
byte_t NrAr[8];
|
||||||
|
} PACKED rht2d_authenticate;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
rht2d_password pwd;
|
||||||
|
rht2d_authenticate auth;
|
||||||
|
} hitag_data;
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -86,6 +86,12 @@ typedef struct {
|
||||||
#define CMD_ISO_15693_COMMAND_DONE 0x0314
|
#define CMD_ISO_15693_COMMAND_DONE 0x0314
|
||||||
#define CMD_ISO_15693_FIND_AFI 0x0315
|
#define CMD_ISO_15693_FIND_AFI 0x0315
|
||||||
#define CMD_ISO_15693_DEBUG 0x0316
|
#define CMD_ISO_15693_DEBUG 0x0316
|
||||||
|
|
||||||
|
// For Hitag2 transponders
|
||||||
|
#define CMD_SNOOP_HITAG 0x0370
|
||||||
|
#define CMD_SIMULATE_HITAG 0x0371
|
||||||
|
#define CMD_READER_HITAG 0x0372
|
||||||
|
|
||||||
#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380
|
#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380
|
||||||
#define CMD_SIMULATE_TAG_ISO_14443 0x0381
|
#define CMD_SIMULATE_TAG_ISO_14443 0x0381
|
||||||
#define CMD_SNOOP_ISO_14443 0x0382
|
#define CMD_SNOOP_ISO_14443 0x0382
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue