.DELETE_ON_ERROR:
-# version.c should be remade on every compilation
-.PHONY: version.c
+# version.c and fpga_version_info.c to be remade on every compilation
+.PHONY: version.c fpga_version_info.c
+
version.c: default_version.c
perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@
$(DELETE) $(OBJDIR)$(PATHSEP)*.d
$(DELETE) $(OBJDIR)$(PATHSEP)*.z
$(DELETE) $(OBJDIR)$(PATHSEP)*.bin
- $(DELETE) version.c
+ $(DELETE) version.c fpga_version_info.c
.PHONY: all clean help
help:
// Reset SPI
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
+ AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; // required twice on some AT91SAM Revisions (see Errata in AT91SAM datasheet)
// Reset SSC
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
- // Load the FPGA image, which we have stored in our flash.
- // (the HF version by default)
+ // Load the FPGA image, which we have stored in our flash (HF version by default)
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-
+
StartTickCount();
#ifdef WITH_LCD
static uint8_t *fpga_image_ptr = NULL;
static uint32_t uncompressed_bytes_cnt;
-#define OUTPUT_BUFFER_LEN 80
+#define OUTPUT_BUFFER_LEN 80
//-----------------------------------------------------------------------------
// Set up the Serial Peripheral Interface as master
// Disable PIO control of the following pins, allows use by the SPI peripheral
AT91C_BASE_PIOA->PIO_PDR =
- GPIO_NCS0 |
- GPIO_NCS2 |
- GPIO_MISO |
- GPIO_MOSI |
+ GPIO_NCS0 |
+ GPIO_NCS2 |
+ GPIO_MISO |
+ GPIO_MOSI |
GPIO_SPCK;
AT91C_BASE_PIOA->PIO_ASR =
- GPIO_NCS0 |
- GPIO_MISO |
- GPIO_MOSI |
+ GPIO_NCS0 |
+ GPIO_MISO |
+ GPIO_MOSI |
GPIO_SPCK;
AT91C_BASE_PIOA->PIO_BSR = GPIO_NCS2;
switch (mode) {
case SPI_FPGA_MODE:
AT91C_BASE_SPI->SPI_MR =
- ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
- (14 << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
- ( 0 << 7) | // Local Loopback Disabled
- ( 1 << 4) | // Mode Fault Detection disabled
- ( 0 << 2) | // Chip selects connected directly to peripheral
- ( 0 << 1) | // Fixed Peripheral Select
- ( 1 << 0); // Master Mode
+ ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
+ (14 << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
+ ( 0 << 7) | // Local Loopback Disabled
+ ( 1 << 4) | // Mode Fault Detection disabled
+ ( 0 << 2) | // Chip selects connected directly to peripheral
+ ( 0 << 1) | // Fixed Peripheral Select
+ ( 1 << 0); // Master Mode
AT91C_BASE_SPI->SPI_CSR[0] =
- ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
- ( 1 << 16) | // Delay Before SPCK (1 MCK period)
- ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
- ( 8 << 4) | // Bits per Transfer (16 bits)
- ( 0 << 3) | // Chip Select inactive after transfer
- ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
- ( 0 << 0); // Clock Polarity inactive state is logic 0
+ ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
+ ( 1 << 16) | // Delay Before SPCK (1 MCK period)
+ ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
+ ( 8 << 4) | // Bits per Transfer (16 bits)
+ ( 0 << 3) | // Chip Select inactive after transfer
+ ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
+ ( 0 << 0); // Clock Polarity inactive state is logic 0
break;
case SPI_LCD_MODE:
AT91C_BASE_SPI->SPI_MR =
- ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
- (11 << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
- ( 0 << 7) | // Local Loopback Disabled
- ( 1 << 4) | // Mode Fault Detection disabled
- ( 0 << 2) | // Chip selects connected directly to peripheral
- ( 0 << 1) | // Fixed Peripheral Select
- ( 1 << 0); // Master Mode
+ ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
+ (11 << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
+ ( 0 << 7) | // Local Loopback Disabled
+ ( 1 << 4) | // Mode Fault Detection disabled
+ ( 0 << 2) | // Chip selects connected directly to peripheral
+ ( 0 << 1) | // Fixed Peripheral Select
+ ( 1 << 0); // Master Mode
AT91C_BASE_SPI->SPI_CSR[2] =
- ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
- ( 1 << 16) | // Delay Before SPCK (1 MCK period)
- ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
- ( 1 << 4) | // Bits per Transfer (9 bits)
- ( 0 << 3) | // Chip Select inactive after transfer
- ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
- ( 0 << 0); // Clock Polarity inactive state is logic 0
+ ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
+ ( 1 << 16) | // Delay Before SPCK (1 MCK period)
+ ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
+ ( 1 << 4) | // Bits per Transfer (9 bits)
+ ( 0 << 3) | // Chip Select inactive after transfer
+ ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
+ ( 0 << 0); // Clock Polarity inactive state is logic 0
break;
- default: // Disable SPI
+ default: // Disable SPI
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
break;
}
void FpgaSetupSsc(uint16_t FPGA_mode) {
// First configure the GPIOs, and get ourselves a clock.
AT91C_BASE_PIOA->PIO_ASR =
- GPIO_SSC_FRAME |
- GPIO_SSC_DIN |
- GPIO_SSC_DOUT |
+ GPIO_SSC_FRAME |
+ GPIO_SSC_DIN |
+ GPIO_SSC_DOUT |
GPIO_SSC_CLK;
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
// 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync
// pulse, no output sync
- if ((FPGA_mode & 0x1c0) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) {
+ if ((FPGA_mode & FPGA_MAJOR_MODE_MASK) == FPGA_MAJOR_MODE_HF_READER && FpgaGetCurrent() == FPGA_BITSTREAM_HF) {
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
} else {
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
- }
+ }
- // TX clock comes from TK pin, no clock output, outputs change on falling
- // edge of TK, frame sync is sampled on rising edge of TK, start TX on rising edge of TF
+ // TX clock comes from TK pin, no clock output, outputs change on rising edge of TK,
+ // TF (frame sync) is sampled on falling edge of TK, start TX on rising edge of TF
AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
// tx framing is the same as the rx framing
// ourselves, not to another buffer). The stuff to manipulate those buffers
// is in apps.h, because it should be inlined, for speed.
//-----------------------------------------------------------------------------
-bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count)
-{
+bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count) {
if (buf == NULL) return false;
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer
//----------------------------------------------------------------------------
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with
-// each call.
+// each call.
//----------------------------------------------------------------------------
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer)
{
- if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
+ if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
compressed_fpga_stream->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
fpga_image_ptr = output_buffer;
}
uncompressed_bytes_cnt++;
-
+
return *fpga_image_ptr++;
}
}
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
-
+
}
//----------------------------------------------------------------------------
-// Initialize decompression of the respective (HF or LF) FPGA stream
+// Initialize decompression of the respective (HF or LF) FPGA stream
//----------------------------------------------------------------------------
static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
{
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
-
+
uncompressed_bytes_cnt = 0;
-
+
// initialize z_stream structure for inflate:
compressed_fpga_stream->next_in = &_binary_obj_fpga_all_bit_z_start;
compressed_fpga_stream->avail_in = &_binary_obj_fpga_all_bit_z_end - &_binary_obj_fpga_all_bit_z_start;
for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++) {
header[i] = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer);
}
-
+
// Check for a valid .bit file (starts with bitparse_fixed_header)
if(memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0) {
return true;
{
//Dbprintf("DownloadFPGA(len: %d)", FpgaImageLen);
-
+
int i=0;
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
- HIGH(GPIO_FPGA_ON); // ensure everything is powered on
+ HIGH(GPIO_FPGA_ON); // ensure everything is powered on
SpinDelay(50);
LED_D_ON();
// These pins are inputs
- AT91C_BASE_PIOA->PIO_ODR =
- GPIO_FPGA_NINIT |
- GPIO_FPGA_DONE;
+ AT91C_BASE_PIOA->PIO_ODR =
+ GPIO_FPGA_NINIT |
+ GPIO_FPGA_DONE;
// PIO controls the following pins
- AT91C_BASE_PIOA->PIO_PER =
- GPIO_FPGA_NINIT |
- GPIO_FPGA_DONE;
+ AT91C_BASE_PIOA->PIO_PER =
+ GPIO_FPGA_NINIT |
+ GPIO_FPGA_DONE;
// Enable pull-ups
AT91C_BASE_PIOA->PIO_PPUER =
GPIO_FPGA_NINIT |
LOW(GPIO_FPGA_DIN);
// These pins are outputs
AT91C_BASE_PIOA->PIO_OER =
- GPIO_FPGA_NPROGRAM |
- GPIO_FPGA_CCLK |
+ GPIO_FPGA_NPROGRAM |
+ GPIO_FPGA_CCLK |
GPIO_FPGA_DIN;
// enter FPGA configuration mode
}
DownloadFPGA_byte(b);
}
-
+
// continue to clock FPGA until ready signal goes high
i=100000;
while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) {
//----------------------------------------------------------------------------
-// Check which FPGA image is currently loaded (if any). If necessary
+// Check which FPGA image is currently loaded (if any). If necessary
// decompress and load the correct (HF or LF) image to the FPGA
//----------------------------------------------------------------------------
void FpgaDownloadAndGo(int bitstream_version)
{
z_stream compressed_fpga_stream;
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
-
+
// check whether or not the bitstream is already loaded
if (downloaded_bitstream == bitstream_version) {
FpgaEnableTracing();
}
// make sure that we have enough memory to decompress
- BigBuf_free(); BigBuf_Clear_ext(false);
-
+ BigBuf_free(); BigBuf_Clear_ext(false);
+
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) {
return;
}
}
inflateEnd(&compressed_fpga_stream);
-
+
// turn off antenna
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-
+
// free eventually allocated BigBuf memory
- BigBuf_free(); BigBuf_Clear_ext(false);
-}
+ BigBuf_free(); BigBuf_Clear_ext(false);
+}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void FpgaSendCommand(uint16_t cmd, uint16_t v) {
SetupSpi(SPI_FPGA_MODE);
- while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
- AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data
+ AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // write the data to be sent
+ while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
}
//-----------------------------------------------------------------------------
#define FPGA_BITSTREAM_HF 2
// Definitions for the FPGA commands.
+#define FPGA_CMD_MASK 0xF000
// BOTH
-#define FPGA_CMD_SET_CONFREG (1<<12)
+#define FPGA_CMD_SET_CONFREG (1<<12)
// LF
-#define FPGA_CMD_SET_DIVISOR (2<<12)
-#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD (3<<12)
-
+#define FPGA_CMD_SET_DIVISOR (2<<12)
+#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD (3<<12)
// HF
-#define FPGA_CMD_TRACE_ENABLE (2<<12)
+#define FPGA_CMD_TRACE_ENABLE (2<<12)
// Definitions for the FPGA configuration word.
+#define FPGA_MAJOR_MODE_MASK 0x01C0
// LF
#define FPGA_MAJOR_MODE_LF_ADC (0<<6)
#define FPGA_MAJOR_MODE_LF_EDGE_DETECT (1<<6)
// BOTH
#define FPGA_MAJOR_MODE_OFF (7<<6)
+#define FPGA_MINOR_MODE_MASK 0x003F
// Options for LF_ADC
#define FPGA_LF_ADC_READER_FIELD (1<<0)
if (modulated_response_size > 0) {
uint32_t response_time = reader_eof_time + DELAY_ICLASS_VCD_TO_VICC_SIM;
TransmitTo15693Reader(modulated_response, modulated_response_size, &response_time, 0, false);
- LogTrace_ISO15693(trace_data, trace_data_size, response_time*32, response_time*32 + modulated_response_size/2, NULL, false);
+ LogTrace_ISO15693(trace_data, trace_data_size, response_time*32, response_time*32 + modulated_response_size*32*64, NULL, false);
}
}
LED_A_ON();
+ Iso15693InitTag();
+
uint32_t simType = arg0;
uint32_t numberOfCSNS = arg1;
- // setup hardware for simulation:
- FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
- LED_D_OFF();
- FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
- StartCountSspClk();
-
// Enable and clear the trace
set_tracing(true);
clear_trace();
doIClassSimulation(ICLASS_SIM_MODE_CSN, NULL);
} else if (simType == ICLASS_SIM_MODE_CSN_DEFAULT) {
//Default CSN
- uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
- // Use the CSN from commandline
- memcpy(emulator, csn_crc, 8);
+ uint8_t csn[] = {0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0};
+ memcpy(emulator, csn, 8);
doIClassSimulation(ICLASS_SIM_MODE_CSN, NULL);
} else if (simType == ICLASS_SIM_MODE_READER_ATTACK) {
uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 };
static void ReaderTransmitIClass(uint8_t *frame, int len, uint32_t *start_time) {
CodeIso15693AsReader(frame, len);
-
TransmitTo15693Tag(ToSend, ToSendMax, start_time);
-
uint32_t end_time = *start_time + 32*(8*ToSendMax-4); // substract the 4 padding bits after EOF
LogTrace_ISO15693(frame, len, *start_time*4, end_time*4, NULL, true);
}
AT91C_BASE_SSC->SSC_THR = send_word;
while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
AT91C_BASE_SSC->SSC_THR = send_word;
-
data <<= 1;
}
WDT_HIT();
LED_B_OFF();
*start_time = *start_time + DELAY_ARM_TO_TAG;
-
}
// Initialize the proxmark as iso15k reader
-void Iso15693InitReader() {
+void Iso15693InitReader(void) {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- // Start from off (no field generated)
- LED_D_OFF();
+ // switch field off and wait until tag resets
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_D_OFF();
SpinDelay(10);
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+ // switch field on
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
+ LED_D_ON();
+
+ // initialize SSC and select proper AD input
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- // Give the tags time to energize
- LED_D_ON();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
+ // give tags some time to energize
SpinDelay(250);
}
LED_A_ON();
+ Iso15693InitReader();
+
+ StartCountSspClk();
set_tracing(true);
uint8_t TagUID[8] = {0x00};
-
- FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
-
uint8_t answer[ISO15693_MAX_RESPONSE_LENGTH];
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- // Setup SSC
- FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
-
- // Start from off (no field generated)
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelay(200);
-
- // Give the tags time to energize
- LED_D_ON();
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER);
- SpinDelay(200);
- StartCountSspClk();
-
-
// FIRST WE RUN AN INVENTORY TO GET THE TAG UID
// THIS MEANS WE CAN PRE-BUILD REQUESTS TO SAVE CPU TIME
}
+// Initialize the proxmark as iso15k tag
+void Iso15693InitTag(void) {
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
+ LED_D_OFF();
+ FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
+ StartCountSspClk();
+}
+
+
// Simulate an ISO15693 TAG.
// For Inventory command: print command and send Inventory Response with given UID
// TODO: interpret other reader commands and send appropriate response
LED_A_ON();
- FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
- FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
-
- StartCountSspClk();
-
- uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
+ Iso15693InitTag();
// Build a suitable response to the reader INVENTORY command
BuildInventoryResponse(uid);
// Listen to reader
while (!BUTTON_PRESS()) {
+ uint8_t cmd[ISO15693_MAX_COMMAND_LENGTH];
uint32_t eof_time = 0, start_time = 0;
int cmd_len = GetIso15693CommandFromReader(cmd, sizeof(cmd), &eof_time);
#define DELAY_ISO15693_VCD_TO_VICC_READER 1056 // 1056/3,39MHz = 311.5us from end of command EOF to start of tag response
#define DELAY_ISO15693_VICC_TO_VCD_READER 1024 // 1024/3.39MHz = 302.1us between end of tag response and next reader command
-void Iso15693InitReader();
-void CodeIso15693AsReader(uint8_t *cmd, int n);
-void CodeIso15693AsTag(uint8_t *cmd, size_t len);
-void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint32_t slot_time, bool slow);
-int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time);
-void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time);
-int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time);
-void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string);
-void AcquireRawAdcSamplesIso15693(void);
-void ReaderIso15693(uint32_t parameter);
-void SimTagIso15693(uint32_t parameter, uint8_t *uid);
-void BruteforceIso15693Afi(uint32_t speed);
-void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]);
-void SetTag15693Uid(uint8_t *uid);
-void SetDebugIso15693(uint32_t flag);
-bool LogTrace_ISO15693(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
+extern void Iso15693InitReader(void);
+extern void Iso15693InitTag(void);
+extern void CodeIso15693AsReader(uint8_t *cmd, int n);
+extern void CodeIso15693AsTag(uint8_t *cmd, size_t len);
+extern void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, uint32_t slot_time, bool slow);
+extern int GetIso15693CommandFromReader(uint8_t *received, size_t max_len, uint32_t *eof_time);
+extern void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time);
+extern int GetIso15693AnswerFromTag(uint8_t* response, uint16_t max_len, uint16_t timeout, uint32_t *eof_time);
+extern void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string);
+extern void AcquireRawAdcSamplesIso15693(void);
+extern void ReaderIso15693(uint32_t parameter);
+extern void SimTagIso15693(uint32_t parameter, uint8_t *uid);
+extern void BruteforceIso15693Afi(uint32_t speed);
+extern void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t data[]);
+extern void SetTag15693Uid(uint8_t *uid);
+extern void SetDebugIso15693(uint32_t flag);
+extern bool LogTrace_ISO15693(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
#endif
// 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
-int BUTTON_CLICKED(int ms)
-{
+int BUTTON_CLICKED(int ms) {
// Up to 500ms in between clicks to mean a double click
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
}
// Determine if a button is held down
-int BUTTON_HELD(int ms)
-{
+int BUTTON_HELD(int ms) {
// If button is held for one second
int ticks = (48000 * (ms ? ms : 1000)) >> 10;
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
- for(;;)
- {
+ for(;;) {
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
// As soon as our button let go, we didn't hold long enough
return BUTTON_SINGLE_CLICK;
// Have we waited the full second?
- else
- if (now == (uint16_t)(start + ticks))
+ else if (now == (uint16_t)(start + ticks))
return BUTTON_HOLD;
WDT_HIT();
// attempt at high resolution microsecond timer
// beware: timer counts in 21.3uS increments (1024/48Mhz)
-void SpinDelayUs(int us)
-{
+void SpinDelayUs(int us) {
int ticks = (48*us) >> 10;
// Borrow a PWM unit for my real-time clock
}
}
-void SpinDelay(int ms)
-{
+void SpinDelay(int ms) {
// convert to uS and call microsecond delay function
SpinDelayUs(ms*1000);
}
// ti = GetTickCount() - ti;
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
-void StartTickCount()
-{
+void StartTickCount() {
// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency
/*
* Get the current count.
*/
-uint32_t RAMFUNC GetTickCount(){
+uint32_t RAMFUNC GetTickCount(void) {
return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
}
// -------------------------------------------------------------------------
// microseconds timer
// -------------------------------------------------------------------------
-void StartCountUS()
-{
+void StartCountUS(void) {
AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14);
// AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC1XC1S_TIOA0;
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
}
-uint32_t RAMFUNC GetCountUS(){
+uint32_t RAMFUNC GetCountUS(void) {
return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV * 2) / 3); //was /15) * 10);
}
static uint32_t GlobalUsCounter = 0;
-uint32_t RAMFUNC GetDeltaCountUS(){
+uint32_t RAMFUNC GetDeltaCountUS(void) {
uint32_t g_cnt = GetCountUS();
uint32_t g_res = g_cnt - GlobalUsCounter;
GlobalUsCounter = g_cnt;
// -------------------------------------------------------------------------
// Timer for iso14443 commands. Uses ssp_clk from FPGA
// -------------------------------------------------------------------------
-void StartCountSspClk()
-{
+void StartCountSspClk(void) {
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1
| AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none
| AT91C_TC_WAVE // Waveform Mode
| AT91C_TC_AEEVT_SET // Set TIOA1 on external event
| AT91C_TC_ACPC_CLEAR; // Clear TIOA1 on RC Compare
- AT91C_BASE_TC1->TC_RC = 0x02; // RC Compare value = 0x02
+ AT91C_BASE_TC1->TC_RC = 1; // RC Compare value = 1; pulse width to TC0
// use TC0 to count TIOA1 pulses
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // disable TC0
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high; 1st ssp_clk after start of frame
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK); // wait for ssp_clk to go low;
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high; 2nd ssp_clk after start of frame
- if ((AT91C_BASE_SSC->SSC_RFMR & SSC_FRAME_MODE_BITS_IN_WORD(32)) == SSC_FRAME_MODE_BITS_IN_WORD(16)) {
+ if ((AT91C_BASE_SSC->SSC_RFMR & SSC_FRAME_MODE_BITS_IN_WORD(32)) == SSC_FRAME_MODE_BITS_IN_WORD(16)) { // 16bit frame
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK); // wait for ssp_clk to go low;
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); // wait for ssp_clk to go high; 3rd ssp_clk after start of frame
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK); // wait for ssp_clk to go low;
AT91C_BASE_TCB->TCB_BCR = 1; // assert Sync (set all timers to 0 on next active clock edge)
// at the next (3rd/7th) ssp_clk rising edge, TC1 will be reset (and not generate a clock signal to TC0)
// at the next (4th/8th) ssp_clk rising edge, TC0 (the low word of our counter) will be reset. From now on,
- // whenever the last three bits of our counter go 0, we can be sure to be in the middle of a frame transfer.
- // (just started with the transfer of the 3rd Bit).
+ // whenever the last three/four bits of our counter go 0, we can be sure to be in the middle of a frame transfer.
+
// The high word of the counter (TC2) will not reset until the low word (TC0) overflows. Therefore need to wait quite some time before
// we can use the counter.
while (AT91C_BASE_TC0->TC_CV < 0xFFFF);
#
#BEGIN
APP_CFLAGS += -DWITH_ISO14443a_StandAlone \
- -DWITH_LF\
+ -DWITH_LF \
-DWITH_ISO15693 \
-DWITH_ISO14443a \
-DWITH_ISO14443b \
reg [11:0] has_been_low_for;
always @(negedge adc_clk)
begin
- if(& adc_d[7:0]) after_hysteresis <= 1'b1;
- else if(~(| adc_d[7:0])) after_hysteresis <= 1'b0;
+ if (& adc_d[7:0]) after_hysteresis <= 1'b1;
+ else if (~(| adc_d[7:0])) after_hysteresis <= 1'b0;
- if(after_hysteresis)
+ if (after_hysteresis)
begin
- has_been_low_for <= 7'b0;
+ has_been_low_for <= 12'd0;
end
else
begin
- if(has_been_low_for == 12'd4095)
+ if (has_been_low_for == 12'd4095)
begin
has_been_low_for <= 12'd0;
after_hysteresis <= 1'b1;
// ssp clock and frame signal for communication to and from ARM
+// _____ _____ _____ _
+// ssp_clk | |_____| |_____| |_____|
+// _____
+// ssp_frame ___| |____________________________
+// ___________ ___________ ___________ _
+// ssp_d_in X___________X___________X___________X_
+//
+// corr_i_cnt 0 1 2 3 4 5 6 7 8 9 10 11 12 ...
+//
+
reg ssp_clk;
reg ssp_frame;
// (send one frame with 16 Bits)
if (corr_i_cnt == 6'd1)
ssp_frame <= 1'b1;
- if (corr_i_cnt == 6'd5)
+ if (corr_i_cnt == 6'd3)
ssp_frame <= 1'b0;
end