From: pwpiwi Date: Sat, 11 Apr 2020 06:56:14 +0000 (+0200) Subject: Merge pull request #926 from pwpiwi/fix_iso15693_fpga X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/ebf1404a813867dbfb60dc5f4b13cfee62fb3b71?hp=c85805b8a2e96f2d66a4728abe14053436e36068 Merge pull request #926 from pwpiwi/fix_iso15693_fpga * make fpga_version_info.c phony and delete it on 'make clean' * wait for transfer to complete before returning from FpgaSendCommand() * log correct tag times in iclass simulation * shorten pulse from TC1 to TC0 in StartCountSspClk() * shorten ssp_frame pulse in fpga/hi_reader.v * some reformatting and whitespace fixes * NOISE_THRESHOLD /= 2 (starting with c41dd5f it became a relative threshold) * remove superfluous reader initialization --- diff --git a/armsrc/Makefile b/armsrc/Makefile index 7b9e1356..f4ad2ad6 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -83,8 +83,9 @@ all: $(OBJS) .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) $^ $@ @@ -132,7 +133,7 @@ clean: $(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: diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 4f0a19b9..56bf67e0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1467,13 +1467,13 @@ void __attribute__((noreturn)) AppMain(void) { // 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 diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 8693d6b5..61db66d3 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -32,7 +32,7 @@ extern uint8_t _binary_obj_fpga_all_bit_z_start, _binary_obj_fpga_all_bit_z_end; 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 @@ -49,16 +49,16 @@ void SetupSpi(int mode) // 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; @@ -71,41 +71,41 @@ void SetupSpi(int mode) 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; } @@ -118,9 +118,9 @@ void SetupSpi(int mode) 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; @@ -135,14 +135,14 @@ void FpgaSetupSsc(uint16_t FPGA_mode) { // 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 @@ -157,8 +157,7 @@ void FpgaSetupSsc(uint16_t FPGA_mode) { // 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 @@ -173,11 +172,11 @@ bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count) //---------------------------------------------------------------------------- // 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; @@ -190,7 +189,7 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8 } uncompressed_bytes_cnt++; - + return *fpga_image_ptr++; } @@ -207,7 +206,7 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga } return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); - + } @@ -224,14 +223,14 @@ static void fpga_inflate_free(voidpf opaque, voidpf address) //---------------------------------------------------------------------------- -// 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; @@ -247,7 +246,7 @@ static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_s 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; @@ -275,25 +274,25 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp { //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 | @@ -305,8 +304,8 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp 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 @@ -335,7 +334,7 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp } DownloadFPGA_byte(b); } - + // continue to clock FPGA until ready signal goes high i=100000; while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) { @@ -407,14 +406,14 @@ static int bitparse_find_section(int bitstream_version, char section_name, unsig //---------------------------------------------------------------------------- -// 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(); @@ -422,8 +421,8 @@ void FpgaDownloadAndGo(int bitstream_version) } // 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; } @@ -435,13 +434,13 @@ void FpgaDownloadAndGo(int bitstream_version) } 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); +} //----------------------------------------------------------------------------- @@ -451,8 +450,8 @@ void FpgaDownloadAndGo(int bitstream_version) //----------------------------------------------------------------------------- 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 } //----------------------------------------------------------------------------- diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 9746638d..57e9c28a 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -35,16 +35,17 @@ void SetAdcMuxFor(uint32_t whichGpio); #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) @@ -58,6 +59,7 @@ void SetAdcMuxFor(uint32_t whichGpio); // 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) diff --git a/armsrc/iclass.c b/armsrc/iclass.c index afe1a607..3f89ae85 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -538,7 +538,7 @@ int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf) { 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); } } @@ -566,17 +566,11 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain 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(); @@ -589,9 +583,8 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain 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 }; @@ -636,9 +629,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain 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); } diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 9f6516aa..f16698bb 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -291,7 +291,6 @@ void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) { 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(); @@ -299,7 +298,6 @@ void TransmitTo15693Tag(const uint8_t *cmd, int len, uint32_t *start_time) { LED_B_OFF(); *start_time = *start_time + DELAY_ARM_TO_TAG; - } @@ -370,7 +368,7 @@ void TransmitTo15693Reader(const uint8_t *cmd, size_t len, uint32_t *start_time, // false if we are still waiting for some more //============================================================================= -#define NOISE_THRESHOLD 160 // don't try to correlate noise +#define NOISE_THRESHOLD 80 // don't try to correlate noise #define MAX_PREVIOUS_AMPLITUDE (-1 - NOISE_THRESHOLD) typedef struct DecodeTag { @@ -1357,20 +1355,23 @@ void SnoopIso15693(uint8_t jam_search_len, uint8_t *jam_search_string) { // 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); } @@ -1573,26 +1574,8 @@ void ReaderIso15693(uint32_t parameter) { 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 @@ -1650,6 +1633,17 @@ void ReaderIso15693(uint32_t parameter) { } +// 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 @@ -1657,20 +1651,14 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) { 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); diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index e48e4d4a..15dfe763 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -22,21 +22,22 @@ #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 diff --git a/armsrc/util.c b/armsrc/util.c index 4bff3a26..b0cd1818 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -137,8 +137,7 @@ void LED(int led, int ms) // 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; @@ -200,8 +199,7 @@ int BUTTON_CLICKED(int ms) } // 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; @@ -218,8 +216,7 @@ int BUTTON_HELD(int ms) 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 @@ -227,8 +224,7 @@ int BUTTON_HELD(int ms) 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(); @@ -240,8 +236,7 @@ int BUTTON_HELD(int ms) // 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 @@ -262,8 +257,7 @@ void SpinDelayUs(int us) } } -void SpinDelay(int ms) -{ +void SpinDelay(int ms) { // convert to uS and call microsecond delay function SpinDelayUs(ms*1000); } @@ -314,8 +308,7 @@ void FormatVersionInformation(char *dst, int len, const char *prefix, void *vers // 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 @@ -328,7 +321,7 @@ void StartTickCount() /* * Get the current count. */ -uint32_t RAMFUNC GetTickCount(){ +uint32_t RAMFUNC GetTickCount(void) { return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2; } @@ -336,8 +329,7 @@ uint32_t RAMFUNC GetTickCount(){ // ------------------------------------------------------------------------- // 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; @@ -359,14 +351,14 @@ void StartCountUS() } -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; @@ -377,8 +369,7 @@ uint32_t RAMFUNC GetDeltaCountUS(){ // ------------------------------------------------------------------------- // 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 @@ -395,7 +386,7 @@ void StartCountSspClk() | 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 @@ -425,7 +416,7 @@ void StartCountSspClk() 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; @@ -439,8 +430,8 @@ void StartCountSspClk() 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); diff --git a/common/Makefile_Enabled_Options.common b/common/Makefile_Enabled_Options.common index d9f6d3b9..edc86b85 100644 --- a/common/Makefile_Enabled_Options.common +++ b/common/Makefile_Enabled_Options.common @@ -4,7 +4,7 @@ # #BEGIN APP_CFLAGS += -DWITH_ISO14443a_StandAlone \ - -DWITH_LF\ + -DWITH_LF \ -DWITH_ISO15693 \ -DWITH_ISO14443a \ -DWITH_ISO14443b \ diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit index ea7c7ebf..c5beb0b9 100644 Binary files a/fpga/fpga_hf.bit and b/fpga/fpga_hf.bit differ diff --git a/fpga/hi_reader.v b/fpga/hi_reader.v index fe5ae4e5..edb9a8a6 100644 --- a/fpga/hi_reader.v +++ b/fpga/hi_reader.v @@ -30,16 +30,16 @@ reg after_hysteresis, after_hysteresis_prev, after_hysteresis_prev_prev; 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; @@ -235,6 +235,16 @@ end // 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; @@ -249,7 +259,7 @@ begin // (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