// when we read a TI tag we sample the zerocross line at 2Mhz
// TI tags modulate a 1 as 16 cycles of 123.2Khz
// TI tags modulate a 0 as 16 cycles of 134.2Khz
- #define FSAMPLE 2000000
- #define FREQLO 123200
- #define FREQHI 134200
+ #define FSAMPLE 2000000
+ #define FREQLO 123200
+ #define FREQHI 134200
signed char *dest = (signed char *)BigBuf_get_addr();
uint16_t n = BigBuf_max_traceLen();
AcquireTiType();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- DbpString("Now use tiread to check");
+ DbpString("Now use 'lf ti read' to check");
}
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
for(;;) {
//wait until SSC_CLK goes HIGH
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS() || usb_poll()) {
+ if(BUTTON_PRESS() || (usb_poll_validate_length() )) {
DbpString("Stopped");
return;
}
int ledcontrol = 1;
int n=0, i=0;
uint8_t clk = (arg1 >> 8) & 0xFF;
- uint8_t encoding = arg1 & 1;
+ uint8_t encoding = arg1 & 0xFF;
uint8_t separator = arg2 & 1;
uint8_t invert = (arg2 >> 8) & 1;
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr();
- const size_t sizeOfBigBuff = BigBuf_max_traceLen();
+ //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
size_t size = 0;
uint32_t hi2=0, hi=0, lo=0;
int idx=0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
// FSK demodulator
- size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
+ //size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
+ size = 50*128*2; //big enough to catch 2 sequences of largest format
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
- if (idx>0 && lo>0){
- // final loop, go over previously decoded manchester data and decode into usable tag ID
- // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
- if (hi2 != 0){ //extra large HID tags
+ if (idx>0 && lo>0 && (size==96 || size==192)){
+ // go over previously decoded manchester data and decode into usable tag ID
+ if (hi2 != 0){ //extra large HID tags 88/192 bits
Dbprintf("TAG ID: %x%08x%08x (%d)",
(unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }else { //standard HID tags <38 bits
+ }else { //standard HID tags 44/96 bits
//Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
uint8_t bitlen = 0;
uint32_t fc = 0;
return;
}
// reset
- hi2 = hi = lo = 0;
}
+ hi2 = hi = lo = idx = 0;
+ WDT_HIT();
+ }
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();
+}
+
+// loop to get raw HID waveform then FSK demodulate the TAG ID from it
+void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
+{
+ uint8_t *dest = BigBuf_get_addr();
+ //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
+ size_t size;
+ int idx=0;
+ // Configure to go in 125Khz listen mode
+ LFSetupFPGAForADC(95, true);
+
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
+
+ WDT_HIT();
+ if (ledcontrol) LED_A_ON();
+
+ DoAcquisition_default(-1,true);
+ // FSK demodulator
+ //size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
+ size = 50*128*2; //big enough to catch 2 sequences of largest format
+ idx = AWIDdemodFSK(dest, &size);
+
+ if (idx>0 && size==96){
+ // Index map
+ // 0 10 20 30 40 50 60
+ // | | | | | | |
+ // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
+ // -----------------------------------------------------------------------------
+ // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
+ // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
+ // |---26 bit---| |-----117----||-------------142-------------|
+ // b = format bit len, o = odd parity of last 3 bits
+ // f = facility code, c = card number
+ // w = wiegand parity
+ // (26 bit format shown)
+
+ //get raw ID before removing parities
+ uint32_t rawLo = bytebits_to_byte(dest+idx+64,32);
+ uint32_t rawHi = bytebits_to_byte(dest+idx+32,32);
+ uint32_t rawHi2 = bytebits_to_byte(dest+idx,32);
+
+ size = removeParity(dest, idx+8, 4, 1, 88);
+ // ok valid card found!
+
+ // Index map
+ // 0 10 20 30 40 50 60
+ // | | | | | | |
+ // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
+ // -----------------------------------------------------------------------------
+ // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
+ // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ // |26 bit| |-117--| |-----142------|
+ // b = format bit len, o = odd parity of last 3 bits
+ // f = facility code, c = card number
+ // w = wiegand parity
+ // (26 bit format shown)
+
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+ uint32_t code1 = 0;
+ uint32_t code2 = 0;
+ uint8_t fmtLen = bytebits_to_byte(dest,8);
+ if (fmtLen==26){
+ fc = bytebits_to_byte(dest+9, 8);
+ cardnum = bytebits_to_byte(dest+17, 16);
+ code1 = bytebits_to_byte(dest+8,fmtLen);
+ Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
+ } else {
+ cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16);
+ if (fmtLen>32){
+ code1 = bytebits_to_byte(dest+8,fmtLen-32);
+ code2 = bytebits_to_byte(dest+8+(fmtLen-32),32);
+ Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
+ } else{
+ code1 = bytebits_to_byte(dest+8,fmtLen);
+ Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
+ }
+ }
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ return;
+ }
+ // reset
+ }
+ idx = 0;
WDT_HIT();
}
DbpString("Stopped");
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
size = BigBuf_max_traceLen();
- //Dbprintf("DEBUG: Buffer got");
//askdemod and manchester decode
- errCnt = askmandemod(dest, &size, &clk, &invert, maxErr);
- //Dbprintf("DEBUG: ASK Got");
+ if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format
+ errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
WDT_HIT();
- if (errCnt>=0){
+ if (errCnt<0) continue;
+
errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
- //Dbprintf("DEBUG: EM GOT");
if (errCnt){
if (size>64){
Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
(uint32_t)((lo>>16LL) & 0xFF),
(uint32_t)(lo & 0xFFFFFF));
}
- }
+
if (findone){
if (ledcontrol) LED_A_OFF();
*high=lo>>32;
*low=lo & 0xFFFFFFFF;
return;
}
- } else{
- //Dbprintf("DEBUG: No Tag");
}
WDT_HIT();
- hi = 0;
- lo = 0;
- clk=0;
- invert=0;
- errCnt=0;
- size=0;
+ hi = lo = size = idx = 0;
+ clk = invert = errCnt = 0;
}
DbpString("Stopped");
if (ledcontrol) LED_A_OFF();
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);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
//fskdemod and get start index
WDT_HIT();
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
- if (idx>0){
+ if (idx<0) continue;
//valid tag found
//Index map
//| | | | | | |
//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
code = bytebits_to_byte(dest+idx,32);
code2 = bytebits_to_byte(dest+idx+32,32);
version = bytebits_to_byte(dest+idx+27,8); //14,4
- facilitycode = bytebits_to_byte(dest+idx+18,8) ;
+ 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();
version=facilitycode=0;
number=0;
idx=0;
- }
+
WDT_HIT();
}
DbpString("Stopped");
*/
/* T55x7 configuration register definitions */
-#define T55x7_POR_DELAY 0x00000001
-#define T55x7_ST_TERMINATOR 0x00000008
-#define T55x7_PWD 0x00000010
+#define T55x7_POR_DELAY 0x00000001
+#define T55x7_ST_TERMINATOR 0x00000008
+#define T55x7_PWD 0x00000010
#define T55x7_MAXBLOCK_SHIFT 5
-#define T55x7_AOR 0x00000200
-#define T55x7_PSKCF_RF_2 0
-#define T55x7_PSKCF_RF_4 0x00000400
-#define T55x7_PSKCF_RF_8 0x00000800
+#define T55x7_AOR 0x00000200
+#define T55x7_PSKCF_RF_2 0
+#define T55x7_PSKCF_RF_4 0x00000400
+#define T55x7_PSKCF_RF_8 0x00000800
#define T55x7_MODULATION_DIRECT 0
#define T55x7_MODULATION_PSK1 0x00001000
#define T55x7_MODULATION_PSK2 0x00002000
#define T55x7_MODULATION_FSK2a 0x00007000
#define T55x7_MODULATION_MANCHESTER 0x00008000
#define T55x7_MODULATION_BIPHASE 0x00010000
-#define T55x7_BITRATE_RF_8 0
-#define T55x7_BITRATE_RF_16 0x00040000
-#define T55x7_BITRATE_RF_32 0x00080000
-#define T55x7_BITRATE_RF_40 0x000C0000
-#define T55x7_BITRATE_RF_50 0x00100000
-#define T55x7_BITRATE_RF_64 0x00140000
+//#define T55x7_MODULATION_BIPHASE57 0x00011000
+#define T55x7_BITRATE_RF_8 0
+#define T55x7_BITRATE_RF_16 0x00040000
+#define T55x7_BITRATE_RF_32 0x00080000
+#define T55x7_BITRATE_RF_40 0x000C0000
+#define T55x7_BITRATE_RF_50 0x00100000
+#define T55x7_BITRATE_RF_64 0x00140000
#define T55x7_BITRATE_RF_100 0x00180000
#define T55x7_BITRATE_RF_128 0x001C0000
/* T5555 (Q5) configuration register definitions */
-#define T5555_ST_TERMINATOR 0x00000001
+#define T5555_ST_TERMINATOR 0x00000001
#define T5555_MAXBLOCK_SHIFT 0x00000001
#define T5555_MODULATION_MANCHESTER 0
#define T5555_MODULATION_PSK1 0x00000010
#define T5555_MODULATION_FSK2 0x00000050
#define T5555_MODULATION_BIPHASE 0x00000060
#define T5555_MODULATION_DIRECT 0x00000070
-#define T5555_INVERT_OUTPUT 0x00000080
-#define T5555_PSK_RF_2 0
-#define T5555_PSK_RF_4 0x00000100
-#define T5555_PSK_RF_8 0x00000200
-#define T5555_USE_PWD 0x00000400
-#define T5555_USE_AOR 0x00000800
-#define T5555_BITRATE_SHIFT 12
-#define T5555_FAST_WRITE 0x00004000
-#define T5555_PAGE_SELECT 0x00008000
+#define T5555_INVERT_OUTPUT 0x00000080
+#define T5555_PSK_RF_2 0
+#define T5555_PSK_RF_4 0x00000100
+#define T5555_PSK_RF_8 0x00000200
+#define T5555_USE_PWD 0x00000400
+#define T5555_USE_AOR 0x00000800
+#define T5555_BITRATE_SHIFT 12
+#define T5555_FAST_WRITE 0x00004000
+#define T5555_PAGE_SELECT 0x00008000
/*
* Relevant times in microsecond
* To compensate antenna falling times shorten the write times
* and enlarge the gap ones.
*/
-#define START_GAP 50*8 // 10 - 50fc 250
-#define WRITE_GAP 20*8 // - 30fc 160
-#define WRITE_0 24*8 // 16 - 63fc 54fc 144
-#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 //400
+
+#define START_GAP 50*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
+#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
+#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
+#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 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);
+ //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);
// Set up FPGA, 125kHz
// Wait for config.. (192+8190xPOW)x8 == 67ms
LFSetupFPGAForADC(0, true);
-
+
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
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);
+ SpinDelayUs(300);
}
// Set up FPGA, 125kHz
// Wait for config.. (192+8190xPOW)x8 == 67ms
- LFSetupFPGAForADC(0, true);
+ //LFSetupFPGAForADC(0, true);
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // 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();
+
+ // Give it a bit of time for the resonant antenna to settle.
+ //SpinDelayUs(8*200); //192FC
+ SpinDelay(50);
+
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
#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();
+
+ 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 fwd_bit_count;
uint8_t *dest = BigBuf_get_addr();
- int m=0, i=0;
+ 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;
//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();
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
+void CopyViKingtoT55x7(uint32_t block1,uint32_t block2)
+{
+ LED_D_ON();
+ T55xxWriteBlock(block1,1,0,0);
+ T55xxWriteBlock(block2,2,0,0);
+
+ T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1);
+ LED_D_OFF();
+ DbpString("DONE!");
+}
+
+
+#define T0_PCF 8 //period for the pcf7931 in us
+
+/* Write on a byte of a PCF7931 tag
+ * @param address : address of the block to write
+ @param byte : address of the byte to write
+ @param data : data to write
+ */
+void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data)
+{
+
+ uint32_t tab[1024]={0}; // data times frame
+ uint32_t u = 0;
+ uint8_t parity = 0;
+ bool comp = 0;
+
+
+ //BUILD OF THE DATA FRAME
+
+ //alimentation of the tag (time for initializing)
+ AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab);
+
+ //PMC
+ Dbprintf("Initialization delay : %d us", init_delay);
+ AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab);
+
+ Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
+
+ //password indication bit
+ AddBitPCF7931(1, tab, l, p);
+
+
+ //password (on 56 bits)
+ Dbprintf("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", pass1,pass2,pass3,pass4,pass5,pass6,pass7);
+ AddBytePCF7931(pass1, tab, l, p);
+ AddBytePCF7931(pass2, tab, l, p);
+ AddBytePCF7931(pass3, tab, l, p);
+ AddBytePCF7931(pass4, tab, l, p);
+ AddBytePCF7931(pass5, tab, l, p);
+ AddBytePCF7931(pass6, tab, l, p);
+ AddBytePCF7931(pass7, tab, l, p);
+
+
+ //programming mode (0 or 1)
+ AddBitPCF7931(0, tab, l, p);
+
+ //block adress on 6 bits
+ Dbprintf("Block address : %02x", address);
+ for (u=0; u<6; u++)
+ {
+ if (address&(1<<u)) { // bit 1
+ parity++;
+ AddBitPCF7931(1, tab, l, p);
+ } else{ // bit 0
+ AddBitPCF7931(0, tab, l, p);
+ }
+ }
+
+ //byte address on 4 bits
+ Dbprintf("Byte address : %02x", byte);
+ for (u=0; u<4; u++)
+ {
+ if (byte&(1<<u)) { // bit 1
+ parity++;
+ AddBitPCF7931(1, tab, l, p);
+ } else{ // bit 0
+ AddBitPCF7931(0, tab, l, p);
+ }
+ }
+
+ //data on 8 bits
+ Dbprintf("Data : %02x", data);
+ for (u=0; u<8; u++)
+ {
+ if (data&(1<<u)) { // bit 1
+ parity++;
+ AddBitPCF7931(1, tab, l, p);
+ } else{ //bit 0
+ AddBitPCF7931(0, tab, l, p);
+ }
+ }
+
+
+ //parity bit
+ if((parity%2)==0){
+ AddBitPCF7931(0, tab, l, p); //even parity
+ }else{
+ AddBitPCF7931(1, tab, l, p);//odd parity
+ }
+
+ //time access memory
+ AddPatternPCF7931(5120+2680, 0, 0, tab);
+
+ //conversion of the scale time
+ for(u=0;u<500;u++){
+ tab[u]=(tab[u] * 3)/2;
+ }
+
+
+ //compennsation of the counter reload
+ while (!comp){
+ comp = 1;
+ for(u=0;tab[u]!=0;u++){
+ if(tab[u] > 0xFFFF){
+ tab[u] -= 0xFFFF;
+ comp = 0;
+ }
+ }
+ }
+
+ SendCmdPCF7931(tab);
+}
+
+
+
+/* Send a trame to a PCF7931 tags
+ * @param tab : array of the data frame
+ */
+
+void SendCmdPCF7931(uint32_t * tab){
+ uint16_t u=0;
+ uint16_t tempo=0;
+
+ Dbprintf("SENDING DATA FRAME...");
+
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU );
+
+ LED_A_ON();
+
+ // steal this pin from the SSP and use it to control the modulation
+ AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
+ AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
+
+ //initialization of the timer
+ AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14);
+ AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
+ AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
+ AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
+ AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
+ AT91C_BASE_TCB->TCB_BCR = 1;
+
+
+ tempo = AT91C_BASE_TC0->TC_CV;
+ for(u=0;tab[u]!= 0;u+=3){
+
+
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+ while(tempo != tab[u]){
+ tempo = AT91C_BASE_TC0->TC_CV;
+ }
+
+ // stop modulating antenna
+ LOW(GPIO_SSC_DOUT);
+ while(tempo != tab[u+1]){
+ tempo = AT91C_BASE_TC0->TC_CV;
+ }
+
+
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+ while(tempo != tab[u+2]){
+ tempo = AT91C_BASE_TC0->TC_CV;
+ }
+
+
+ }
+
+ LED_A_OFF();
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelay(200);
+
+
+ AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
+ DbpString("FINISH !");
+ DbpString("(Could be usefull to send the same trame many times)");
+ LED(0xFFFF, 1000);
+}
+
+
+/* Add a byte for building the data frame of PCF7931 tags
+ * @param b : byte to add
+ * @param tab : array of the data frame
+ * @param l : offset on low pulse width
+ * @param p : offset on low pulse positioning
+ */
+
+bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
+
+ uint32_t u;
+ for (u=0; u<8; u++)
+ {
+ if (byte&(1<<u)) { //bit à 1
+ if(AddBitPCF7931(1, tab, l, p)==1)return 1;
+ } else { //bit à 0
+ if(AddBitPCF7931(0, tab, l, p)==1)return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Add a bits for building the data frame of PCF7931 tags
+ * @param b : bit to add
+ * @param tab : array of the data frame
+ * @param l : offset on low pulse width
+ * @param p : offset on low pulse positioning
+ */
+bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
+ uint8_t u = 0;
+
+ for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
+
+
+ if(b==1){ //add a bit 1
+ if(u==0) tab[u] = 34*T0_PCF+p;
+ else tab[u] = 34*T0_PCF+tab[u-1]+p;
+
+ tab[u+1] = 6*T0_PCF+tab[u]+l;
+ tab[u+2] = 88*T0_PCF+tab[u+1]-l-p;
+ return 0;
+ }else{ //add a bit 0
+
+ if(u==0) tab[u] = 98*T0_PCF+p;
+ else tab[u] = 98*T0_PCF+tab[u-1]+p;
+
+ tab[u+1] = 6*T0_PCF+tab[u]+l;
+ tab[u+2] = 24*T0_PCF+tab[u+1]-l-p;
+ return 0;
+ }
+
+
+ return 1;
+}
+
+/* Add a custom pattern in the data frame
+ * @param a : delay of the first high pulse
+ * @param b : delay of the low pulse
+ * @param c : delay of the last high pulse
+ * @param tab : array of the data frame
+ */
+bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){
+ uint32_t u = 0;
+ for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
+
+ if(u==0) tab[u] = a;
+ else tab[u] = a + tab[u-1];
+
+ tab[u+1] = b+tab[u];
+ tab[u+2] = c+tab[u+1];
+
+ return 0;
+}
\ No newline at end of file