From 5f5b83b7435ae85f2ffa06f1f8994bda22ce64b2 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 2 Feb 2017 15:32:21 +0100 Subject: [PATCH] ADD: 'lf cotag read' - COTAG can be read now. --- armsrc/appmain.c | 2 +- armsrc/apps.h | 2 +- armsrc/lfops.c | 55 ++++++++++++-------- armsrc/lfsampling.c | 124 ++++++++++++++++++++++++++++++++++++++++++-- armsrc/lfsampling.h | 9 +++- client/cmdhw.c | 5 +- client/cmdlfcotag.c | 70 +++++++++++++++++++++---- client/cmdlfcotag.h | 2 + common/lfdemod.c | 4 +- 9 files changed, 232 insertions(+), 41 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e457f438..3db56845 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1017,7 +1017,7 @@ void UsbPacketReceived(uint8_t *packet, int len) CopyVikingtoT55xx(c->arg[0], c->arg[1], c->arg[2]); break; case CMD_COTAG: - Cotag(); + Cotag(c->arg[0]); break; #endif diff --git a/armsrc/apps.h b/armsrc/apps.h index 6ea9d5ea..90e4da99 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -98,7 +98,7 @@ void T55xxWakeUp(uint32_t Pwd); void TurnReadLFOn(uint32_t delay); void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode); void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode); -void Cotag(); +void Cotag(uint32_t arg0); /// iso14443b.h void SimulateIso14443bTag(uint32_t pupi); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 1c11ad09..3c69770e 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -799,7 +799,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) WDT_HIT(); if (ledcontrol) LED_A_ON(); - DoAcquisition_default(-1,true); + DoAcquisition_default(0, true); // FSK demodulator size = 50*128*2; //big enough to catch 2 sequences of largest format idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo); @@ -1740,18 +1740,36 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode LED_D_OFF(); } -void Cotag() { +/* +Reading a COTAG. + +COTAG needs the reader to send a startsequence and the card has an extreme slow datarate. +because of this, we can "sample" the data signal but we interpreate it to Manchester direct. + +READER START SEQUENCE: +burst 800 us, gap 2.2 msecs +burst 3.6 msecs gap 2.2 msecs +burst 800 us gap 2.2 msecs +pulse 3.6 msecs + +This triggers a COTAG tag to response +*/ +void Cotag(uint32_t arg0) { #define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); } -//#define WAIT2200 { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2200); } -#define ON(x) { FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } - LED_A_ON(); +#define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } + + uint8_t rawsignal = arg0 & 0xF; + + LED_A_ON(); + + // Switching to LF image on FPGA. This might empty BigBuff + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); //clear buffer now so it does not interfere with timing later BigBuf_Clear_ext(false); - - // Set up FPGA, 132kHz to power up the tag - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + // Set up FPGA, 132kHz to power up the tag FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); @@ -1761,27 +1779,20 @@ void Cotag() { // Now set up the SSC to get the ADC samples that are now streaming at us. FpgaSetupSsc(); - // start a 1.5ticks is 1us + // start clock - 1.5ticks is 1us StartTicks(); - //send start pulse + //send COTAG start pulse ON(740) OFF ON(3330) OFF ON(740) OFF ON(1000) -/* - ON(800) OFF - ON(3600) OFF - ON(800) OFF - ON(1000) - -burst 800 us, gap 2.2 msecs -burst 3.6 msecs gap 2.2 msecs -burst 800 us gap 2.2 msecs -pulse 3.6 msecs -*/ - DoAcquisition_config(FALSE); + switch(rawsignal) { + case 0: doCotagAcquisition(50000); break; + case 1: doCotagAcquisitionManchester(); break; + case 2: DoAcquisition_config(TRUE); break; + } // Turn the field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index 0fcaf3ce..841bfab8 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -20,7 +20,7 @@ sample_config config = { 1, 8, 1, 95, 0 } ; void printConfig() { Dbprintf("LF Sampling config: "); - Dbprintf(" [q] divisor: %d ", config.divisor); + Dbprintf(" [q] divisor: %d (%d KHz)", config.divisor, 12000 / (config.divisor+1)); Dbprintf(" [b] bps: %d ", config.bits_per_sample); Dbprintf(" [d] decimation: %d ", config.decimation); Dbprintf(" [a] averaging: %s ", (config.averaging) ? "Yes" : "No"); @@ -140,7 +140,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag while(!BUTTON_PRESS() && !usb_poll_validate_length() ) { WDT_HIT(); if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x00; //0x43; + AT91C_BASE_SSC->SSC_THR = 0x43; LED_D_ON(); } if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { @@ -310,4 +310,122 @@ void doT55x7Acquisition(size_t sample_size) { } } } - \ No newline at end of file +/** +* acquisition of Cotag LF signal. Similart to other LF, since the Cotag has such long datarate RF/384 +* and is Manchester?, we directly gather the manchester data into bigbuff +**/ + +#define COTAG_T1 384 +#define COTAG_T2 (COTAG_T1>>1) +#define COTAG_ONE_THRESHOLD 128+30 +#define COTAG_ZERO_THRESHOLD 128-30 +void doCotagAcquisition(size_t sample_size) { + + uint8_t *dest = BigBuf_get_addr(); + uint16_t bufsize = BigBuf_max_traceLen(); + + if ( bufsize > sample_size ) + bufsize = sample_size; + + dest[0] = 0; + uint8_t sample = 0, firsthigh = 0, firstlow = 0; + uint16_t i = 0; + + while (!BUTTON_PRESS() && !usb_poll_validate_length() && (i < bufsize) ) { + WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + + // find first peak + if ( !firsthigh ) { + if (sample < COTAG_ONE_THRESHOLD) + continue; + firsthigh = 1; + } + if ( !firstlow ){ + if (sample > COTAG_ZERO_THRESHOLD ) + continue; + firstlow = 1; + } + + ++i; + + if ( sample > COTAG_ONE_THRESHOLD) + dest[i] = 255; + else if ( sample < COTAG_ZERO_THRESHOLD) + dest[i] = 0; + else + dest[i] = dest[i-1]; + } + } +} + +uint32_t doCotagAcquisitionManchester() { + + uint8_t *dest = BigBuf_get_addr(); + uint16_t bufsize = BigBuf_max_traceLen(); + + if ( bufsize > 320 ) + bufsize = 320; + + dest[0] = 0; + uint8_t sample = 0, firsthigh = 0, firstlow = 0; + uint16_t sample_counter = 0, period = 0; + uint8_t curr = 0, prev = 0; + + while (!BUTTON_PRESS() && !usb_poll_validate_length() && (sample_counter < bufsize) ) { + WDT_HIT(); + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { + AT91C_BASE_SSC->SSC_THR = 0x43; + LED_D_ON(); + } + + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + LED_D_OFF(); + + // find first peak + if ( !firsthigh ) { + if (sample < COTAG_ONE_THRESHOLD) + continue; + firsthigh = 1; + } + + if ( !firstlow ){ + if (sample > COTAG_ZERO_THRESHOLD ) + continue; + firstlow = 1; + } + + // set sample 255, 0, or previous + if ( sample > COTAG_ONE_THRESHOLD){ + prev = curr; + curr = 1; + } + else if ( sample < COTAG_ZERO_THRESHOLD) { + prev = curr; + curr = 0; + } + else { + curr = prev; + } + + // full T1 periods, + if ( period > 0 ) { + --period; + continue; + } + + dest[sample_counter] = curr; + ++sample_counter; + period = COTAG_T1; + } + } + return sample_counter; +} \ No newline at end of file diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index b37b786e..a31e2dc5 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -11,7 +11,14 @@ typedef struct BitstreamOut BitstreamOut; /** -* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds +* acquisition of Cotag LF signal. Similar to other LF, since the Cotag has such long datarate RF/384 +* and is Manchester?, we directly gather the manchester data into bigbuff +**/ +void doCotagAcquisition(size_t sample_size); +uint32_t doCotagAcquisitionManchester(void); + +/** +* acquisition of T55x7 LF signal. Similar to other LF, but adjusted with @marshmellows thresholds * the data is collected in BigBuf. **/ void doT55x7Acquisition(size_t sample_size); diff --git a/client/cmdhw.c b/client/cmdhw.c index 4dae7a32..537e6335 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -222,10 +222,11 @@ int CmdSetDivisor(const char *Cmd) PrintAndLog("divisor must be between 19 and 255"); return 1; } - + // 12 000 000 (12Mhz) + // clearCommandBuffer(); SendCommand(&c); - PrintAndLog("Divisor set, expected freq=%dHz", 12000000 / (c.arg[0]+1)); + PrintAndLog("Divisor set, expected %.1f KHz", ((double)12000 / (c.arg[0]+1)) ); return 0; } diff --git a/client/cmdlfcotag.c b/client/cmdlfcotag.c index 5e3f28b6..8b71a031 100644 --- a/client/cmdlfcotag.c +++ b/client/cmdlfcotag.c @@ -11,26 +11,78 @@ static int CmdHelp(const char *Cmd); -int CmdCOTAGRead(const char *Cmd) { - -// if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read(); +int usage_lf_cotag_read(void){ + PrintAndLog("Usage: lf COTAG read [h] "); + PrintAndLog("Options:"); + PrintAndLog(" h : This help"); + PrintAndLog(" <0|1|2> : 0 - HIGH/LOW signal; maxlength bigbuff"); + PrintAndLog(" : 1 - translation of HI/LO into bytes with manchester 0,1"); + PrintAndLog(" : 2 - raw signal; maxlength bigbuff"); + PrintAndLog(""); + PrintAndLog("Sample:"); + PrintAndLog(" lf cotag read 0"); + PrintAndLog(" lf cotag read 1"); + return 0; +} +int CmdCOTAGDemod(const char *Cmd) { + return 0; +} - CmdLFSetConfig("q 89"); +// When reading a COTAG. +// 0 = HIGH/LOW signal - maxlength bigbuff +// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300 +// 2 = raw signal - maxlength bigbuff +int CmdCOTAGRead(const char *Cmd) { + + if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read(); + + uint8_t bits[320] = {0}; + uint32_t rawsignal = 0; + sscanf(Cmd, "%u", &rawsignal); - UsbCommand c = {CMD_COTAG, {0, 0, 0}}; + UsbCommand c = {CMD_COTAG, {rawsignal, 0, 0}}; clearCommandBuffer(); SendCommand(&c); - if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500) ) { + if ( !WaitForResponseTimeout(CMD_ACK, NULL, 7000) ) { PrintAndLog("command execution time out"); - return 1; + return 1; } - getSamples("", true); + + switch ( rawsignal ){ + case 0: + case 2: { + CmdPlot(""); + CmdGrid("384"); + getSamples("", true); break; + } + case 1: { + GetFromBigBuf(bits, sizeof(bits), 0); + UsbCommand response; + if ( !WaitForResponseTimeout(CMD_ACK, &response, 500) ) { + PrintAndLog("timeout while waiting for reply."); + return 1; + } + + size_t size = sizeof(bits); + int err = manrawdecode(bits, &size, 1); + if (err){ + PrintAndLog("DEBUG: Error - COTAG too many errors: %d", err); + return 0; + } + PrintAndLog("%s", sprint_bin(bits, size)); + setDemodBuf(bits, sizeof(bits), 0); + + // CmdCOTAGDemod(); + break; + } + } return 0; } static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, - {"read", CmdCOTAGRead, 0, "Attempt to read and extract tag data"}, + {"demod", CmdCOTAGDemod, 1, "Tries to decode a COTAG signal"}, + {"read", CmdCOTAGRead, 0, "Attempt to read and extract tag data"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlfcotag.h b/client/cmdlfcotag.h index 37009a0b..ab808b40 100644 --- a/client/cmdlfcotag.h +++ b/client/cmdlfcotag.h @@ -21,5 +21,7 @@ int CmdLFCOTAG(const char *Cmd); int CmdCOTAGRead(const char *Cmd); +int CmdCOTAGDemod(const char *Cmd); +int usage_lf_cotag_read(void); #endif diff --git a/common/lfdemod.c b/common/lfdemod.c index 49c5877e..910b2af4 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -350,9 +350,9 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr //take 10 and 01 and manchester decode //run through 2 times and take least errCnt int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert){ - uint16_t bitnum = 0, MaxBits = 512, errCnt = 0; + int errCnt = 0, bestErr = 1000; + uint16_t bitnum = 0, MaxBits = 512, bestRun = 0; size_t i, k; - uint16_t bestErr = 1000, bestRun = 0; if (*size < 16) return -1; //find correct start position [alignment] for (k=0; k < 2; ++k){ -- 2.39.2