+ int n=0, i=0;
+ /*
+ HID tag bitstream format
+ The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
+ A 1 bit is represented as 6 fc8 and 5 fc10 patterns
+ A 0 bit is represented as 5 fc10 and 6 fc8 patterns
+ A fc8 is inserted before every 4 bits
+ A special start of frame pattern is used consisting a0b0 where a and b are neither 0
+ nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
+ */
+
+ if (hi2>0x0FFFFFFF) {
+ DbpString("Tags can only have 44 or 84 bits. - USE lf simfsk for larger tags");
+ return;
+ }
+ // set LF so we don't kill the bigbuf we are setting with simulation data.
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+ fc(0,&n);
+ // special start of frame marker containing invalid bit sequences
+ fc(8, &n); fc(8, &n); // invalid
+ fc(8, &n); fc(10, &n); // logical 0
+ fc(10, &n); fc(10, &n); // invalid
+ fc(8, &n); fc(10, &n); // logical 0
+
+ WDT_HIT();
+ if (hi2 > 0 || hi > 0xFFF){
+ // manchester encode bits 91 to 64 (91-84 are part of the header)
+ for (i=27; i>=0; i--) {
+ if ((i%4)==3) fc(0,&n);
+ if ((hi2>>i)&1) {
+ fc(10, &n); fc(8, &n); // low-high transition
+ } else {
+ fc(8, &n); fc(10, &n); // high-low transition
+ }
+ }
+ WDT_HIT();
+ // manchester encode bits 63 to 32
+ for (i=31; i>=0; i--) {
+ if ((i%4)==3) fc(0,&n);
+ if ((hi>>i)&1) {
+ fc(10, &n); fc(8, &n); // low-high transition
+ } else {
+ fc(8, &n); fc(10, &n); // high-low transition
+ }
+ }
+ } else {
+ // manchester encode bits 43 to 32
+ for (i=11; i>=0; i--) {
+ if ((i%4)==3) fc(0,&n);
+ if ((hi>>i)&1) {
+ fc(10, &n); fc(8, &n); // low-high transition
+ } else {
+ fc(8, &n); fc(10, &n); // high-low transition
+ }
+ }
+ }
+
+ WDT_HIT();
+ // manchester encode bits 31 to 0
+ for (i=31; i>=0; i--) {
+ if ((i%4)==3) fc(0,&n);
+ if ((lo>>i)&1) {
+ fc(10, &n); fc(8, &n); // low-high transition
+ } else {
+ fc(8, &n); fc(10, &n); // high-low transition
+ }
+ }
+
+ if (ledcontrol)
+ LED_A_ON();
+ SimulateTagLowFrequency(n, 0, ledcontrol);
+
+ if (ledcontrol)
+ LED_A_OFF();
+}
+
+// prepare a waveform pattern in the buffer based on the ID given then
+// simulate a FSK tag until the button is pressed
+// arg1 contains fcHigh and fcLow, arg2 contains invert and clock
+void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
+{
+ int ledcontrol=1;
+ int n=0, i=0;
+ uint8_t fcHigh = arg1 >> 8;
+ uint8_t fcLow = arg1 & 0xFF;
+ uint16_t modCnt = 0;
+ uint8_t clk = arg2 & 0xFF;
+ uint8_t invert = (arg2 >> 8) & 1;
+
+ // set LF so we don't kill the bigbuf we are setting with simulation data.
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+ for (i=0; i<size; i++){
+ if (BitStream[i] == invert){
+ fcAll(fcLow, &n, clk, &modCnt);
+ } else {
+ fcAll(fcHigh, &n, clk, &modCnt);
+ }
+ }
+ Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, invert: %d, n: %d",fcHigh, fcLow, 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_OFF();
+}
+
+// compose ask waveform for one bit(ASK)
+static void askSimBit(uint8_t c, int *n, uint8_t clock, uint8_t manchester)
+{
+ uint8_t *dest = BigBuf_get_addr();
+ uint8_t halfClk = clock/2;
+ // c = current bit 1 or 0
+ if (manchester==1){
+ memset(dest+(*n), c, halfClk);
+ memset(dest+(*n) + halfClk, c^1, halfClk);
+ } else {
+ 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;
+ }
+ *n += clock;
+}
+
+static void stAskSimBit(int *n, uint8_t clock) {
+ uint8_t *dest = BigBuf_get_addr();
+ uint8_t halfClk = clock/2;
+ //ST = .5 high .5 low 1.5 high .5 low 1 high
+ memset(dest+(*n), 1, halfClk);
+ memset(dest+(*n) + halfClk, 0, halfClk);
+ memset(dest+(*n) + clock, 1, clock + halfClk);
+ memset(dest+(*n) + clock*2 + halfClk, 0, halfClk);
+ memset(dest+(*n) + clock*3, 1, clock);
+ *n += clock*4;
+}
+
+// args clock, ask/man or askraw, invert, transmission separator
+void CmdASKsimTag(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) & 0xFF;
+ uint8_t encoding = arg1 & 0xFF;
+ uint8_t separator = arg2 & 1;
+ uint8_t invert = (arg2 >> 8) & 1;
+
+ // set LF so we don't kill the bigbuf we are setting with simulation data.
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+ if (encoding==2){ //biphase
+ uint8_t phase=0;
+ for (i=0; i<size; i++){
+ biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
+ }
+ if (phase==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 ask/raw || biphase phase)
+ for (i=0; i<size; i++){
+ askSimBit(BitStream[i]^invert^1, &n, clk, encoding);
+ }
+ }
+ }
+ if (separator==1 && encoding == 1)
+ stAskSimBit(&n, clk);
+ else if (separator==1)
+ Dbprintf("sorry but separator option not yet available");
+
+ Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n);
+ //DEBUG
+ //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]);
+
+ 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;
+ // set LF so we don't kill the bigbuf we are setting with simulation data.
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+ 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_OFF();
+}
+
+// loop to get raw HID waveform then FSK demodulate the TAG ID from it
+void CmdHIDdemodFSK(int findone, int *high2, int *high, int *low, int ledcontrol)
+{
+ uint8_t *dest = BigBuf_get_addr();
+ //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
+ size_t size;
+ uint32_t hi2=0, hi=0, lo=0;
+ int idx=0;
+ int dummyIdx = 0;
+ // Configure to go in 125Khz listen mode
+ LFSetupFPGAForADC(95, true);
+
+ //clear read buffer
+ BigBuf_Clear_keep_EM();
+
+ 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 = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx);
+
+ if (idx>0 && lo>0 && (size==96 || size==192)){
+ uint8_t bitlen = 0;
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+ bool decoded = false;
+
+ // go over previously decoded manchester data and decode into usable tag ID
+ if ((hi2 & 0x000FFFF) != 0){ //extra large HID tags 88/192 bits
+ uint32_t bp = hi2 & 0x000FFFFF;
+ bitlen = 63;
+ while (bp > 0) {
+ bp = bp >> 1;
+ bitlen++;
+ }
+ } else if ((hi >> 6) > 0) {
+ uint32_t bp = hi;
+ bitlen = 31;
+ while (bp > 0) {
+ bp = bp >> 1;
+ bitlen++;
+ }
+ } else if (((hi >> 5) & 1) == 0) {
+ bitlen = 37;
+ } else if ((hi & 0x0000001F) > 0 ) {
+ uint32_t bp = (hi & 0x0000001F);
+ bitlen = 31;
+ while (bp > 0) {
+ bp = bp >> 1;
+ bitlen++;
+ }
+ } else {
+ uint32_t bp = lo;
+ bitlen = 0;
+ while (bp > 0) {
+ bp = bp >> 1;
+ bitlen++;
+ }
+ }
+ switch (bitlen){
+ case 26:
+ cardnum = (lo>>1)&0xFFFF;
+ fc = (lo>>17)&0xFF;
+ decoded = true;
+ break;
+ case 35:
+ cardnum = (lo>>1)&0xFFFFF;
+ fc = ((hi&1)<<11)|(lo>>21);
+ decoded = true;
+ break;
+ }
+
+ 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
+ Dbprintf("TAG ID: %x%08x (%d)",
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+
+ if (decoded)
+ Dbprintf("Format Len: %dbits - FC: %d - Card: %d",
+ (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum);
+
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ *high2 = hi2;
+ *high = hi;
+ *low = lo;
+ break;
+ }
+ // reset
+ }
+ hi2 = hi = lo = idx = 0;
+ WDT_HIT();
+ }
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();