#include "string.h"
#include "lfdemod.h"
#include "lfsampling.h"
+#include "usb_cdc.h"
/**
sample_config sc = { 0,0,1, divisor_used, 0};
setSamplingConfig(&sc);
- /* Make sure the tag is reset */
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelay(2500);
+ /* Make sure the tag is reset */
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelay(2500);
LFSetupFPGAForADC(sc.divisor, 1);
- // And a little more time for the tag to fully power up
- SpinDelay(2000);
+ // And a little more time for the tag to fully power up
+ SpinDelay(2000);
// now modulate the reader field
while(*command != '\0' && *command != ' ') {
DoAcquisition_config(false);
}
-
-
/* blank r/w tag data stream
...0000000000000000 01111111
1010101010101010101010101010101010101010101010101010101010101010
DbpString("Now use tiread to check");
}
-void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
+void SimulateTagLowFrequency(uint16_t period, uint32_t gap, uint8_t ledcontrol)
{
int i;
uint8_t *tab = BigBuf_get_addr();
i = 0;
for(;;) {
+ //wait until SSC_CLK goes HIGH
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS()) {
+ if(BUTTON_PRESS() || usb_poll()) {
DbpString("Stopped");
return;
}
WDT_HIT();
}
-
if (ledcontrol)
LED_D_ON();
if (ledcontrol)
LED_D_OFF();
- //wait for next sample time
+ //wait until SSC_CLK goes LOW
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
if(BUTTON_PRESS()) {
DbpString("Stopped");
return;
}
WDT_HIT();
- }
-
+ }
+
i++;
if(i == period) {
+
i = 0;
if (gap) {
SHORT_COIL();
dest[((*n)++)]=0;
}
- // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
+ // an fc/8 encoded bit is a bit pattern of 11110000 x6 = 48 samples
if(c==8) {
for (idx=0; idx<6; idx++) {
dest[((*n)++)]=1;
}
}
- // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
+ // an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples
if(c==10) {
for (idx=0; idx<5; idx++) {
dest[((*n)++)]=1;
}
}
// compose fc/X fc/Y waveform (FSKx)
-static void fcAll(uint8_t c, int *n, uint8_t clock)
+static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt)
{
uint8_t *dest = BigBuf_get_addr();
- uint8_t idx;
- uint8_t fcCnt;
- // c = count of field clock for this bit
-
- int mod = clock % c;
+ uint8_t halfFC = fc/2;
+ uint8_t wavesPerClock = clock/fc;
+ uint8_t mod = clock % fc; //modifier
+ uint8_t modAdj = fc/mod; //how often to apply modifier
+ bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk=TRUE;
// loop through clock - step field clock
- for (idx=0; idx < (uint8_t) clock/c; idx++){
- // loop through field clock length - put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave)
- for (fcCnt=0; fcCnt < c; fcCnt++){
- if (fcCnt < c/2){
- dest[((*n)++)]=1;
- } else {
- dest[((*n)++)]=0;
- }
- }
+ for (uint8_t idx=0; idx < wavesPerClock; idx++){
+ // put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave)
+ memset(dest+(*n), 0, fc-halfFC); //in case of odd number use extra here
+ memset(dest+(*n)+(fc-halfFC), 1, halfFC);
+ *n += fc;
}
- Dbprintf("mod: %d",mod);
- if (mod>0){ //for FC counts that don't add up to a full clock cycle padd with extra wave
- for (idx=0; idx < mod; idx++){
- if (idx < mod/2) {
- dest[((*n)++)]=1;
- } else {
- dest[((*n)++)]=0;
- }
+ if (mod>0) (*modCnt)++;
+ if ((mod>0) && modAdjOk){ //fsk2
+ if ((*modCnt % modAdj) == 0){ //if 4th 8 length wave in a rf/50 add extra 8 length wave
+ memset(dest+(*n), 0, fc-halfFC);
+ memset(dest+(*n)+(fc-halfFC), 1, halfFC);
+ *n += fc;
}
}
+ if (mod>0 && !modAdjOk){ //fsk1
+ memset(dest+(*n), 0, mod-(mod/2));
+ memset(dest+(*n)+(mod-(mod/2)), 1, mod/2);
+ *n += mod;
+ }
}
// prepare a waveform pattern in the buffer based on the ID given then
*/
if (hi>0xFFF) {
- DbpString("Tags can only have 44 bits.");
+ DbpString("Tags can only have 44 bits. - USE lf simfsk for larger tags");
return;
}
fc(0,&n);
int n=0, i=0;
uint8_t fcHigh = arg1 >> 8;
uint8_t fcLow = arg1 & 0xFF;
- //spacer bit
+ uint16_t modCnt = 0;
uint8_t clk = arg2 & 0xFF;
uint8_t invert = (arg2 >> 8) & 1;
- //fcAll(0, &n, clk);
-
- WDT_HIT();
+
for (i=0; i<size; i++){
- //if ((i%4==3) fcAll(0,&n));
if (BitStream[i] == invert){
- fcAll(fcLow, &n, clk);
+ fcAll(fcLow, &n, clk, &modCnt);
} else {
- fcAll(fcHigh, &n, clk);
+ fcAll(fcHigh, &n, clk, &modCnt);
}
}
Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, invert: %d, n: %d",fcHigh, fcLow, clk, invert, n);
- //Dbprintf("First 64:");
- //uint8_t *dest = BigBuf_get_addr();
- //i=0;
- //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
- //i+=16;
- //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
- //i+=16;
- //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
- //i+=16;
- //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
-
+ /*Dbprintf("DEBUG: First 32:");
+ uint8_t *dest = BigBuf_get_addr();
+ i=0;
+ Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+ i+=16;
+ Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+ */
if (ledcontrol)
LED_A_ON();
+
SimulateTagLowFrequency(n, 0, ledcontrol);
if (ledcontrol)
static void askSimBit(uint8_t c, int *n, uint8_t clock, uint8_t manchester)
{
uint8_t *dest = BigBuf_get_addr();
- uint8_t idx;
+ uint8_t halfClk = clock/2;
// c = current bit 1 or 0
- int i = 0;
- // for when we want a separator
- if (c==2) { //separator
- for (i=0; i<clock/2; i++){
- dest[((*n)++)]=0;
- }
+ if (manchester==1){
+ memset(dest+(*n), c, halfClk);
+ memset(dest+(*n) + halfClk, c^1, halfClk);
} else {
- if (manchester){
- for (idx=0; idx < (uint8_t) clock/2; idx++){
- dest[((*n)++)]=c;
- }
- for (idx=0; idx < (uint8_t) clock/2; idx++){
- dest[((*n)++)]=c^1;
- }
- } else {
- for (idx=0; idx < (uint8_t) clock; idx++){
- dest[((*n)++)]=c;
- }
- }
+ memset(dest+(*n), c, clock);
}
+ *n += clock;
+}
+
+static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase)
+{
+ uint8_t *dest = BigBuf_get_addr();
+ uint8_t halfClk = clock/2;
+ if (c){
+ memset(dest+(*n), c ^ 1 ^ *phase, halfClk);
+ memset(dest+(*n) + halfClk, c ^ *phase, halfClk);
+ } else {
+ memset(dest+(*n), c ^ *phase, clock);
+ *phase ^= 1;
+ }
+
}
// args clock, ask/man or askraw, invert, transmission separator
int ledcontrol = 1;
int n=0, i=0;
uint8_t clk = (arg1 >> 8) & 0xFF;
- uint8_t manchester = arg1 & 1;
+ uint8_t encoding = arg1 & 1;
uint8_t separator = arg2 & 1;
uint8_t invert = (arg2 >> 8) & 1;
- WDT_HIT();
+
+ if (encoding==2){ //biphase
+ uint8_t phase=0;
for (i=0; i<size; i++){
- askSimBit(BitStream[i]^invert, &n, clk, manchester);
+ biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
+ }
+ if (BitStream[0]==BitStream[size-1]){ //run a second set inverted to keep phase in check
+ for (i=0; i<size; i++){
+ biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
+ }
+ }
+ } else { // ask/manchester || ask/raw
+ for (i=0; i<size; i++){
+ askSimBit(BitStream[i]^invert, &n, clk, encoding);
+ }
+ if (encoding==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for biphase phase)
+ for (i=0; i<size; i++){
+ askSimBit(BitStream[i]^invert^1, &n, clk, encoding);
+ }
+ }
}
- if (separator==1) Dbprintf("sorry but separator option not yet available"); //askSimBit(2, &n, clk, manchester);
+
+ if (separator==1) Dbprintf("sorry but separator option not yet available");
- Dbprintf("Simulating with clk: %d, invert: %d, manchester: %d, separator: %d, n: %d",clk, invert, manchester, separator, n);
+ Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n);
//DEBUG
- //Dbprintf("First 64:");
+ //Dbprintf("First 32:");
//uint8_t *dest = BigBuf_get_addr();
//i=0;
//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
//i+=16;
//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
- //i+=16;
+
+ if (ledcontrol)
+ LED_A_ON();
+
+ SimulateTagLowFrequency(n, 0, ledcontrol);
+
+ if (ledcontrol)
+ LED_A_OFF();
+}
+
+//carrier can be 2,4 or 8
+static void pskSimBit(uint8_t waveLen, int *n, uint8_t clk, uint8_t *curPhase, bool phaseChg)
+{
+ uint8_t *dest = BigBuf_get_addr();
+ uint8_t halfWave = waveLen/2;
+ //uint8_t idx;
+ int i = 0;
+ if (phaseChg){
+ // write phase change
+ memset(dest+(*n), *curPhase^1, halfWave);
+ memset(dest+(*n) + halfWave, *curPhase, halfWave);
+ *n += waveLen;
+ *curPhase ^= 1;
+ i += waveLen;
+ }
+ //write each normal clock wave for the clock duration
+ for (; i < clk; i+=waveLen){
+ memset(dest+(*n), *curPhase, halfWave);
+ memset(dest+(*n) + halfWave, *curPhase^1, halfWave);
+ *n += waveLen;
+ }
+}
+
+// args clock, carrier, invert,
+void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
+{
+ int ledcontrol=1;
+ int n=0, i=0;
+ uint8_t clk = arg1 >> 8;
+ uint8_t carrier = arg1 & 0xFF;
+ uint8_t invert = arg2 & 0xFF;
+ uint8_t curPhase = 0;
+ for (i=0; i<size; i++){
+ if (BitStream[i] == curPhase){
+ pskSimBit(carrier, &n, clk, &curPhase, FALSE);
+ } else {
+ pskSimBit(carrier, &n, clk, &curPhase, TRUE);
+ }
+ }
+ Dbprintf("Simulating with Carrier: %d, clk: %d, invert: %d, n: %d",carrier, clk, invert, n);
+ //Dbprintf("DEBUG: First 32:");
+ //uint8_t *dest = BigBuf_get_addr();
+ //i=0;
//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
//i+=16;
//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
-
-
+
if (ledcontrol)
LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol);
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
- // FSK demodulator
+ // FSK demodulator
size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
size_t size=0, idx=0;
int clk=0, invert=0, errCnt=0, maxErr=20;
+ uint32_t hi=0;
uint64_t lo=0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
- size = BigBuf_max_traceLen();
+ size = BigBuf_max_traceLen();
//Dbprintf("DEBUG: Buffer got");
//askdemod and manchester decode
errCnt = askmandemod(dest, &size, &clk, &invert, maxErr);
WDT_HIT();
if (errCnt>=0){
- lo = Em410xDecode(dest, &size, &idx);
+ errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
//Dbprintf("DEBUG: EM GOT");
- if (lo>0){
+ if (errCnt){
+ if (size>64){
+ Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
+ hi,
+ (uint32_t)(lo>>32),
+ (uint32_t)lo,
+ (uint32_t)(lo&0xFFFF),
+ (uint32_t)((lo>>16LL) & 0xFF),
+ (uint32_t)(lo & 0xFFFFFF));
+ } else {
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
(uint32_t)(lo>>32),
(uint32_t)lo,
(uint32_t)((lo>>16LL) & 0xFF),
(uint32_t)(lo & 0xFFFFFF));
}
+ }
if (findone){
if (ledcontrol) LED_A_OFF();
*high=lo>>32;
uint8_t version=0;
uint8_t facilitycode=0;
uint16_t number=0;
+ uint8_t crc = 0;
+ uint16_t calccrc = 0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
- //fskdemod and get start index
+ //fskdemod and get start index
WDT_HIT();
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
if (idx>0){
//| | | | | | |
//01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
//-----------------------------------------------------------------------------
- //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
+ //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 checksum 11
//
+ //Checksum:
+ //00000000 0 11110000 1 11100000 1 00000001 1 00000011 1 10110110 1 01110101 11
+ //preamble F0 E0 01 03 B6 75
+ // How to calc checksum,
+ // http://www.proxmark.org/forum/viewtopic.php?id=364&p=6
+ // F0 + E0 + 01 + 03 + B6 = 28A
+ // 28A & FF = 8A
+ // FF - 8A = 75
+ // Checksum: 0x75
//XSF(version)facility:codeone+codetwo
//Handle the data
if(findone){ //only print binary if we are doing one
facilitycode = bytebits_to_byte(dest+idx+18,8) ;
number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
- Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
+ crc = bytebits_to_byte(dest+idx+54,8);
+ for (uint8_t i=1; i<6; ++i)
+ calccrc += bytebits_to_byte(dest+idx+9*i,8);
+ calccrc &= 0xff;
+ calccrc = 0xff - calccrc;
+
+ char *crcStr = (crc == calccrc) ? "ok":"!crc";
+
+ Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
// if we're only looking for one tag
if (findone){
if (ledcontrol) LED_A_OFF();
* To compensate antenna falling times shorten the write times
* and enlarge the gap ones.
*/
-#define START_GAP 250
-#define WRITE_GAP 160
-#define WRITE_0 144 // 192
-#define WRITE_1 400 // 432 for T55x7; 448 for E5550
+#define START_GAP 50*8 // 10 - 50fc 250
+#define WRITE_GAP 20*8 // 8 - 30fc
+#define WRITE_0 24*8 // 16 - 31fc 24fc 192
+#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550
+
+// VALUES TAKEN FROM EM4x function: SendForward
+// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
+// WRITE_GAP = 128; (16*8)
+// WRITE_1 = 256 32*8; (32*8)
+
+// These timings work for 4469/4269/4305 (with the 55*8 above)
+// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8);
+
+// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
+// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
+// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
+// T0 = TIMER_CLOCK1 / 125000 = 192
+// 1 Cycle = 8 microseconds(us)
+
+#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
// Write one bit to card
void T55xxWriteBit(int bit)
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- if (bit == 0)
+ if (!bit)
SpinDelayUs(WRITE_0);
else
SpinDelayUs(WRITE_1);
// Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
- //unsigned int i; //enio adjustment 12/10/14
- uint32_t i;
-
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ uint32_t i = 0;
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
+ // Set up FPGA, 125kHz
+ // Wait for config.. (192+8190xPOW)x8 == 67ms
+ LFSetupFPGAForADC(0, true);
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
+void TurnReadLFOn(){
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ // Give it a bit of time for the resonant antenna to settle.
+ SpinDelayUs(8*150);
+}
+
+
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
+ uint32_t i = 0;
uint8_t *dest = BigBuf_get_addr();
- //int m=0, i=0; //enio adjustment 12/10/14
- uint32_t m=0, i=0;
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- m = BigBuf_max_traceLen();
- // Clear destination buffer before sending the command
- memset(dest, 128, m);
- // Connect the A/D to the peak-detected low-frequency path.
- SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
-
- LED_D_ON();
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ uint16_t bufferlength = BigBuf_max_traceLen();
+ if ( bufferlength > T55xx_SAMPLES_SIZE )
+ bufferlength = T55xx_SAMPLES_SIZE;
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
+ // Clear destination buffer before sending the command
+ memset(dest, 0x80, bufferlength);
- // Now start writting
+ // Set up FPGA, 125kHz
+ // Wait for config.. (192+8190xPOW)x8 == 67ms
+ LFSetupFPGAForADC(0, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
T55xxWriteBit(Block & i);
// Turn field on to read the response
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
+ TurnReadLFOn();
// Now do the acquisition
i = 0;
for(;;) {
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) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- // we don't care about actual value, only if it's more or less than a
- // threshold essentially we capture zero crossings for later analysis
- // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
i++;
- if (i >= m) break;
+ LED_D_OFF();
+ if (i >= bufferlength) break;
}
}
+ cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
- DbpString("DONE!");
}
// Read card traceability data (page 1)
void T55xxReadTrace(void){
+
+ uint32_t i = 0;
uint8_t *dest = BigBuf_get_addr();
- int m=0, i=0;
+ uint16_t bufferlength = BigBuf_max_traceLen();
+ if ( bufferlength > T55xx_SAMPLES_SIZE )
+ bufferlength= T55xx_SAMPLES_SIZE;
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- m = BigBuf_max_traceLen();
// Clear destination buffer before sending the command
- memset(dest, 128, m);
- // Connect the A/D to the peak-detected low-frequency path.
- SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
-
- LED_D_ON();
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
+ memset(dest, 0x80, bufferlength);
- // Now start writting
+ LFSetupFPGAForADC(0, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
T55xxWriteBit(1); //Page 1
// Turn field on to read the response
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ TurnReadLFOn();
// Now do the acquisition
- i = 0;
for(;;) {
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) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
i++;
- if (i >= m) break;
- }
- }
+ LED_D_OFF();
+ if (i >= bufferlength) break;
+ }
+ }
+
+ cmd_send(CMD_ACK,0,0,0,0,0);
+ cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
- DbpString("DONE!");
+}
+
+void TurnReadLFOn(){
+ //FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ // Give it a bit of time for the resonant antenna to settle.
+ //SpinDelay(30);
+ SpinDelayUs(8*150);
}
/*-------------- Cloning routines -----------*/
#define max(x,y) ( x<y ? y:x)
int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256];
- uint8_t Blocks[8][16];
- uint8_t *GraphBuffer = BigBuf_get_addr();
- int GraphTraceLen = BigBuf_max_traceLen();
+
+ uint8_t bits[256] = {0x00};
+ uint8_t blocks[8][16];
+ uint8_t *dest = BigBuf_get_addr();
+
+ int GraphTraceLen = BigBuf_max_traceLen();
+ if ( GraphTraceLen > 18000 )
+ GraphTraceLen = 18000;
+
+
int i, j, lastval, bitidx, half_switch;
int clock = 64;
int tolerance = clock / 8;
uint8_t dir;
LFSetupFPGAForADC(95, true);
- DoAcquisition_default(0, 0);
-
+ DoAcquisition_default(0, true);
lmin = 64;
lmax = 192;
i = 2;
/* Find first local max/min */
- if(GraphBuffer[1] > GraphBuffer[0]) {
+ if(dest[1] > dest[0]) {
while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
+ if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
break;
i++;
}
}
else {
while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
+ if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
break;
i++;
}
for (bitidx = 0; i < GraphTraceLen; i++)
{
- if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
+ if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin))
{
lc = i - lastval;
lastval = i;
block_done = 1;
}
else if(half_switch == 1) {
- BitStream[bitidx++] = 0;
+ bits[bitidx++] = 0;
half_switch = 0;
}
else
half_switch++;
} else if (abs(lc-clock) < tolerance) {
// 64TO
- BitStream[bitidx++] = 1;
+ bits[bitidx++] = 1;
} else {
// Error
warnings++;
if(block_done == 1) {
if(bitidx == 128) {
for(j=0; j<16; j++) {
- Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
- 64*BitStream[j*8+6]+
- 32*BitStream[j*8+5]+
- 16*BitStream[j*8+4]+
- 8*BitStream[j*8+3]+
- 4*BitStream[j*8+2]+
- 2*BitStream[j*8+1]+
- BitStream[j*8];
+ blocks[num_blocks][j] = 128*bits[j*8+7]+
+ 64*bits[j*8+6]+
+ 32*bits[j*8+5]+
+ 16*bits[j*8+4]+
+ 8*bits[j*8+3]+
+ 4*bits[j*8+2]+
+ 2*bits[j*8+1]+
+ bits[j*8];
+
}
num_blocks++;
}
half_switch = 0;
}
if(i < GraphTraceLen)
- {
- if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
- else dir = 1;
- }
+ dir =(dest[i-1] > dest[i]) ? 0 : 1;
}
if(bitidx==255)
bitidx=0;
warnings = 0;
if(num_blocks == 4) break;
}
- memcpy(outBlocks, Blocks, 16*num_blocks);
+ memcpy(outBlocks, blocks, 16*num_blocks);
return num_blocks;
}
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
+ uint8_t *dest = BigBuf_get_addr();
+ uint16_t bufferlength = BigBuf_max_traceLen();
+ uint32_t i = 0;
+
+ // Clear destination buffer before sending the command 0x80 = average.
+ memset(dest, 0x80, bufferlength);
+
uint8_t fwd_bit_count;
- uint8_t *dest = BigBuf_get_addr();
- int m=0, i=0;
//If password mode do login
if (PwdMode == 1) EM4xLogin(Pwd);
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
fwd_bit_count += Prepare_Addr( Address );
- m = BigBuf_max_traceLen();
- // Clear destination buffer before sending the command
- memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path.
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- i++;
- if (i >= m) break;
- }
- }
+ ++i;
+ if (i >= bufferlength) break;
+ }
+ }
+
+ cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}