]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
rework iso14443b device functions including FPGA I/Q signal transfer (#669)
authorpwpiwi <pwpiwi@users.noreply.github.com>
Sat, 15 Sep 2018 22:53:28 +0000 (00:53 +0200)
committerGitHub <noreply@github.com>
Sat, 15 Sep 2018 22:53:28 +0000 (00:53 +0200)
* rework iso14443b device functions
* hf_read_rx_xcorr.v: transfer i/q pair in one 16bit frame
* hi_read_tx.v: invert ssp_dout. When nothing is transferred (ssp_dout=0), this results in no modulation (carrier on)
* adjust arm sources accordingly
* iso14443b.c: switch off carrier after hf 14b sri512read and hf 14b srix4kread
* iso14443b.c: fix DMA circular buffer handling

14 files changed:
armsrc/fpgaloader.c
armsrc/fpgaloader.h
armsrc/hfsnoop.c
armsrc/iclass.c
armsrc/iso14443a.c
armsrc/iso14443b.c
armsrc/iso15693.c
armsrc/legicrf.c
armsrc/legicrfsim.c
armsrc/lfops.c
armsrc/lfsampling.c
fpga/fpga_hf.bit
fpga/hi_read_rx_xcorr.v
fpga/hi_read_tx.v

index 77223bd06bcf8f9d8485fe5f496020b6d0db730a..a132b762e406e12a2018f0279ea61cc0dba417b0 100644 (file)
@@ -112,10 +112,10 @@ void SetupSpi(int mode)
 }
 
 //-----------------------------------------------------------------------------
-// Set up the synchronous serial port, with the one set of options that we
-// always use when we are talking to the FPGA. Both RX and TX are enabled.
+// Set up the synchronous serial port with the set of options that fits
+// the FPGA mode. Both RX and TX are always enabled.
 //-----------------------------------------------------------------------------
-void FpgaSetupSsc(void)
+void FpgaSetupSsc(uint8_t FPGA_mode)
 {
        // First configure the GPIOs, and get ourselves a clock.
        AT91C_BASE_PIOA->PIO_ASR =
@@ -134,11 +134,15 @@ void FpgaSetupSsc(void)
        // on RX clock rising edge, sampled on falling edge
        AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1);
 
-       // 8 bits per transfer, no loopback, MSB first, 1 transfer per sync
+       // 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync
        // pulse, no output sync
-       AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) |     AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
+       if ((FPGA_mode & 0xe0) == FPGA_MAJOR_MODE_HF_READER_RX_XCORR) {
+               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);
+       }               
 
-       // clock comes from TK pin, no clock output, outputs change on falling
+       // TX clock comes from TK pin, no clock output, outputs change on falling
        // edge of TK, sample on rising edge of TK, start on positive-going edge of sync
        AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) |   SSC_CLOCK_MODE_START(5);
 
@@ -154,16 +158,15 @@ void FpgaSetupSsc(void)
 // 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, int len)
+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
-       AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf;           // transfer to this memory address
-       AT91C_BASE_PDC_SSC->PDC_RCR = len;                                      // transfer this many bytes
-       AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf;          // next transfer to same memory address
-       AT91C_BASE_PDC_SSC->PDC_RNCR = len;                                     // ... with same number of bytes
-       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;         // go!
+       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;        // Disable DMA Transfer
+       AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf;           // transfer to this memory address
+       AT91C_BASE_PDC_SSC->PDC_RCR = sample_count;             // transfer this many samples
+       AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf;          // next transfer to same memory address
+       AT91C_BASE_PDC_SSC->PDC_RNCR = sample_count;            // ... with same number of samples      AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;         // go!
 
        return true;
 }
index fa16771d91cf6fd8deb0f647c47c11bf7b2cabed..f75dfc817f043998f9a138a3c93151b9384e3035 100644 (file)
@@ -19,7 +19,7 @@
 void FpgaSendCommand(uint16_t cmd, uint16_t v);
 void FpgaWriteConfWord(uint8_t v);
 void FpgaDownloadAndGo(int bitstream_version);
-void FpgaSetupSsc(void);
+void FpgaSetupSsc(uint8_t mode);
 void SetupSpi(int mode);
 bool FpgaSetupSscDma(uint8_t *buf, int len);
 void Fpga_print_status();
index d06af44383df8d4a451c7b8121536ee79f87e051..e492c47472cab53ce5baff06a6ac0698cfeecd94 100644 (file)
@@ -37,7 +37,7 @@ void HfSnoop(int samplesToSkip, int triggersToSkip)
        // Select correct configs
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        // Set up the synchronous serial port
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SNOOP);
        // connect Demodulated Signal to ADC:
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
index c587f8ea98b9708862b80c6430a4e67b4caa6ef5..1591a062126b8fab9d2a88cb9ee093aa2ae7aa84 100644 (file)
@@ -676,7 +676,7 @@ void RAMFUNC SnoopIClass(void)
     Demod.state = DEMOD_UNSYNCD;
 
     // Setup for the DMA.
-    FpgaSetupSsc();
+    FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
     upTo = dmaBuf;
     lastRxCounter = DMA_BUFFER_SIZE;
     FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
@@ -1163,7 +1163,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf)
        StartCountSspClk();
        // We need to listen to the high-frequency, peak-detected path.
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
 
        // To control where we are in the protocol
        int cmdsRecvd = 0;
@@ -1360,7 +1360,7 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K_8BIT);
 
        AT91C_BASE_SSC->SSC_THR = 0x00;
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
        while(!BUTTON_PRESS()) {
                if((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)){
                        b = AT91C_BASE_SSC->SSC_RHR; (void) b;
@@ -1398,7 +1398,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
   int c;
   FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
   AT91C_BASE_SSC->SSC_THR = 0x00;
-  FpgaSetupSsc();
+  FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
 
    if (wait)
    {
@@ -1586,7 +1586,7 @@ void setupIclassReader()
          clear_trace();
 
     // Setup SSC
-    FpgaSetupSsc();
+    FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
     // Start from off (no field generated)
     // Signal field is off with the appropriate LED
     LED_D_OFF();
index a8273e5e1bc1fda9d4ea358d15258ab49f070611..0cacaed9d94134d7669f5c75ebf98697aa61aff8 100644 (file)
@@ -1889,7 +1889,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
 void iso14443a_setup(uint8_t fpga_minor_mode) {
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        // Set up the synchronous serial port
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_ISO14443A);
        // connect Demodulated Signal to ADC:
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
index 75769859392c725453b4ede60ae9a5b3a60a3797..cb8567fa570533ae8cee27283ca0e37f22429b78 100644 (file)
@@ -1,5 +1,6 @@
 //-----------------------------------------------------------------------------
 // Jonathan Westhues, split Nov 2006
+// piwi 2018
 //
 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
 // at your option, any later version. See the LICENSE.txt file for the text of
@@ -16,8 +17,8 @@
 
 #include "iso14443crc.h"
 
-#define RECEIVE_SAMPLES_TIMEOUT 2000
-#define ISO14443B_DMA_BUFFER_SIZE 256
+#define RECEIVE_SAMPLES_TIMEOUT 1000 // TR0 max is 256/fs = 256/(848kHz) = 302us or 64 samples from FPGA. 1000 seems to be much too high?
+#define ISO14443B_DMA_BUFFER_SIZE 128
 
 // PCB Block number for APDUs
 static uint8_t pcb_blocknum = 0;
@@ -374,7 +375,7 @@ void SimulateIso14443bTag(void)
 
        // We need to listen to the high-frequency, peak-detected path.
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
 
        cmdsRecvd = 0;
 
@@ -440,7 +441,7 @@ void SimulateIso14443bTag(void)
                LED_D_OFF();
                FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK);
                AT91C_BASE_SSC->SSC_THR = 0xff;
-               FpgaSetupSsc();
+               FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
 
                // Transmit the response.
                uint16_t i = 0;
@@ -535,60 +536,11 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
 
 #define SUBCARRIER_DETECT_THRESHOLD    8
 
-// Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by abs(ci) + abs(cq)
-/* #define CHECK_FOR_SUBCARRIER() { \
-               v = ci; \
-               if(v < 0) v = -v; \
-               if(cq > 0) { \
-                       v += cq; \
-               } else { \
-                       v -= cq; \
-               } \
-       }
- */
 // Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq)))
-
-       //note: couldn't we just use MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2) from common.h - marshmellow
-#define CHECK_FOR_SUBCARRIER() { \
-               v = MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2); \
-       }
-               /*
-               if(ci < 0) { \
-                       if(cq < 0) { \ // ci < 0, cq < 0
-                               if (cq < ci) { \
-                                       v = -cq - (ci >> 1); \
-                               } else { \
-                                       v = -ci - (cq >> 1); \
-                               } \
-                       } else {        \ // ci < 0, cq >= 0
-                               if (cq < -ci) { \
-                                       v = -ci + (cq >> 1); \
-                               } else { \
-                                       v = cq - (ci >> 1); \
-                               } \
-                       } \
-               } else { \
-                       if(cq < 0) { \ // ci >= 0, cq < 0
-                               if (-cq < ci) { \
-                                       v = ci - (cq >> 1); \
-                               } else { \
-                                       v = -cq + (ci >> 1); \
-                               } \
-                       } else {        \ // ci >= 0, cq >= 0
-                               if (cq < ci) { \
-                                       v = ci + (cq >> 1); \
-                               } else { \
-                                       v = cq + (ci >> 1); \
-                               } \
-                       } \
-               } \
-       }
-               */
-
+#define AMPLITUDE(ci,cq) (MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2))
        switch(Demod.state) {
                case DEMOD_UNSYNCD:
-                       CHECK_FOR_SUBCARRIER();
-                       if(v > SUBCARRIER_DETECT_THRESHOLD) {   // subcarrier detected
+                       if(AMPLITUDE(ci,cq) > SUBCARRIER_DETECT_THRESHOLD) {    // subcarrier detected
                                Demod.state = DEMOD_PHASE_REF_TRAINING;
                                Demod.sumI = ci;
                                Demod.sumQ = cq;
@@ -598,8 +550,7 @@ static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq)
 
                case DEMOD_PHASE_REF_TRAINING:
                        if(Demod.posCount < 8) {
-                               CHECK_FOR_SUBCARRIER();
-                               if (v > SUBCARRIER_DETECT_THRESHOLD) {
+                               if (AMPLITUDE(ci,cq) > SUBCARRIER_DETECT_THRESHOLD) {
                                        // set the reference phase (will code a logic '1') by averaging over 32 1/fs.
                                        // note: synchronization time > 80 1/fs
                                        Demod.sumI += ci;
@@ -743,10 +694,11 @@ static void DemodInit(uint8_t *data)
  */
 static void GetSamplesFor14443bDemod(int n, bool quiet)
 {
-       int max = 0;
+       int maxBehindBy = 0;
        bool gotFrame = false;
-       int lastRxCounter, ci, cq, samples = 0;
-
+       int lastRxCounter, samples = 0;
+       int8_t ci, cq;
+       
        // Allocate memory from BigBuf for some buffers
        // free all previous allocations first
        BigBuf_free();
@@ -755,15 +707,19 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
        uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
 
        // The DMA buffer, used to stream samples from the FPGA
-       int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
+       uint16_t *dmaBuf = (uint16_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE * sizeof(uint16_t));
 
        // Set up the demodulator for tag -> reader responses.
        DemodInit(receivedResponse);
 
+       // wait for last transfer to complete
+       while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY))
+
        // Setup and start DMA.
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
 
-       int8_t *upTo = dmaBuf;
+       uint16_t *upTo = dmaBuf;
        lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
 
        // Signal field is ON with the appropriate LED:
@@ -772,39 +728,40 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ);
 
        for(;;) {
-               int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
-               if(behindBy > max) max = behindBy;
-
-               while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1)) > 2) {
-                       ci = upTo[0];
-                       cq = upTo[1];
-                       upTo += 2;
-                       if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
-                               upTo = dmaBuf;
-                               AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
-                               AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;
-                       }
-                       lastRxCounter -= 2;
-                       if(lastRxCounter <= 0) {
-                               lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
-                       }
+               int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1);
+               if(behindBy > maxBehindBy) {
+                       maxBehindBy = behindBy;
+               }
 
-                       samples += 2;
+               if(behindBy < 1) continue;
 
-                       if(Handle14443bSamplesDemod(ci, cq)) {
-                               gotFrame = true;
-                               break;
-                       }
+               ci = *upTo >> 8;
+               cq = *upTo;
+               upTo++;
+               lastRxCounter--;
+               if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {               // we have read all of the DMA buffer content.
+                       upTo = dmaBuf;                                             // start reading the circular buffer from the beginning
+                       lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
+               }
+               if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) {              // DMA Counter Register had reached 0, already rotated.
+                       AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;          // refresh the DMA Next Buffer and
+                       AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;  // DMA Next Counter registers
+               }
+               samples++;
+
+               if(Handle14443bSamplesDemod(ci, cq)) {
+                       gotFrame = true;
+                       break;
                }
 
-               if(samples > n || gotFrame) {
+               if(samples > n) {
                        break;
                }
        }
 
-       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+       FpgaDisableSscDma();
 
-       if (!quiet) Dbprintf("max behindby = %d, samples = %d, gotFrame = %d, Demod.len = %d, Demod.sumI = %d, Demod.sumQ = %d", max, samples, gotFrame, Demod.len, Demod.sumI, Demod.sumQ);
+       if (!quiet) Dbprintf("max behindby = %d, samples = %d, gotFrame = %d, Demod.len = %d, Demod.sumI = %d, Demod.sumQ = %d", maxBehindBy, samples, gotFrame, Demod.len, Demod.sumI, Demod.sumQ);
        //Tracing
        if (tracing && Demod.len > 0) {
                uint8_t parity[MAX_PARITY_SIZE];
@@ -820,11 +777,7 @@ static void TransmitFor14443b(void)
 {
        int c;
 
-       FpgaSetupSsc();
-
-       while(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-               AT91C_BASE_SSC->SSC_THR = 0xff;
-       }
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
 
        // Signal field is ON with the appropriate Red LED
        LED_D_ON();
@@ -832,31 +785,15 @@ static void TransmitFor14443b(void)
        LED_B_ON();
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
 
-       for(c = 0; c < 10;) {
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = 0xff;
-                       c++;
-               }
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-                       (void)r;
-               }
-               WDT_HIT();
-       }
-
        c = 0;
        for(;;) {
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = ToSend[c];
+                       AT91C_BASE_SSC->SSC_THR = ~ToSend[c];
                        c++;
                        if(c >= ToSendMax) {
                                break;
                        }
                }
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-                       (void)r;
-               }
                WDT_HIT();
        }
        LED_B_OFF(); // Finished sending
@@ -874,19 +811,14 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
 
        ToSendReset();
 
-       // Establish initial reference level
-       for(i = 0; i < 40; i++) {
-               ToSendStuffBit(1);
-       }
        // Send SOF
        for(i = 0; i < 10; i++) {
                ToSendStuffBit(0);
        }
+       ToSendStuffBit(1);
+       ToSendStuffBit(1);
 
        for(i = 0; i < len; i++) {
-               // Stop bits/EGT
-               ToSendStuffBit(1);
-               ToSendStuffBit(1);
                // Start bit
                ToSendStuffBit(0);
                // Data bits
@@ -899,19 +831,18 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
                        }
                        b >>= 1;
                }
+               // Stop bit
+               ToSendStuffBit(1);
        }
+
        // Send EOF
-       ToSendStuffBit(1);
        for(i = 0; i < 10; i++) {
                ToSendStuffBit(0);
        }
-       for(i = 0; i < 8; i++) {
-               ToSendStuffBit(1);
-       }
+       ToSendStuffBit(1);
 
-       // And then a little more, to make sure that the last character makes
-       // it out before we switch to rx mode.
-       for(i = 0; i < 24; i++) {
+       // ensure that last byte is filled up
+       for(i = 0; i < 8; i++) {
                ToSendStuffBit(1);
        }
 
@@ -951,7 +882,7 @@ int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *respo
        // send
        CodeAndTransmit14443bAsReader(message_frame, message_length + 4);
        // get response
-       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT*100, true);
+       GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, true);
        if(Demod.len < 3)
        {
                return 0;
@@ -1011,7 +942,7 @@ int iso14443b_select_card()
 void iso14443b_setup() {
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        // Set up the synchronous serial port
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
        // connect Demodulated Signal to ADC:
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
@@ -1019,9 +950,6 @@ void iso14443b_setup() {
     LED_D_ON();
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
 
-       // Start the timer
-       StartCountSspClk();
-
        DemodReset();
        UartReset();
 }
@@ -1047,7 +975,7 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
        SpinDelay(200);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Now give it time to spin up.
        // Signal field is on with the appropriate LED
@@ -1065,6 +993,8 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
 
        if (Demod.len == 0) {
                DbpString("No response from tag");
+               LED_D_OFF();
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                return;
        } else {
                Dbprintf("Randomly generated Chip ID (+ 2 byte CRC): %02x %02x %02x",
@@ -1080,17 +1010,23 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, true);
        if (Demod.len != 3) {
                Dbprintf("Expected 3 bytes from tag, got %d", Demod.len);
+               LED_D_OFF();
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                return;
        }
        // Check the CRC of the answer:
        ComputeCrc14443(CRC_14443_B, Demod.output, 1 , &cmd1[2], &cmd1[3]);
        if(cmd1[2] != Demod.output[1] || cmd1[3] != Demod.output[2]) {
                DbpString("CRC Error reading select response.");
+               LED_D_OFF();
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                return;
        }
        // Check response from the tag: should be the same UID as the command we just sent:
        if (cmd1[1] != Demod.output[0]) {
                Dbprintf("Bad response to SELECT from Tag, aborting: %02x %02x", cmd1[1], Demod.output[0]);
+               LED_D_OFF();
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                return;
        }
 
@@ -1102,6 +1038,8 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
        GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, true);
        if (Demod.len != 10) {
                Dbprintf("Expected 10 bytes from tag, got %d", Demod.len);
+               LED_D_OFF();
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                return;
        }
        // The check the CRC of the answer (use cmd1 as temporary variable):
@@ -1131,6 +1069,8 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
                GetSamplesFor14443bDemod(RECEIVE_SAMPLES_TIMEOUT, true);
                if (Demod.len != 6) { // Check if we got an answer from the tag
                        DbpString("Expected 6 bytes from tag, got less...");
+                       LED_D_OFF();
+                       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                        return;
                }
                // The check the CRC of the answer (use cmd1 as temporary variable):
@@ -1149,6 +1089,9 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
                }
                i++;
        }
+       
+       LED_D_OFF();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 }
 
 
@@ -1171,11 +1114,6 @@ void ReadSTMemoryIso14443b(uint32_t dwLast)
  */
 void RAMFUNC SnoopIso14443b(void)
 {
-       // We won't start recording the frames that we acquire until we trigger;
-       // a good trigger condition to get started is probably when we see a
-       // response from the tag.
-       int triggered = true;                   // TODO: set and evaluate trigger condition
-
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        BigBuf_free();
 
@@ -1183,10 +1121,10 @@ void RAMFUNC SnoopIso14443b(void)
        set_tracing(true);
 
        // The DMA buffer, used to stream samples from the FPGA
-       int8_t *dmaBuf = (int8_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE);
+       uint16_t *dmaBuf = (uint16_t*) BigBuf_malloc(ISO14443B_DMA_BUFFER_SIZE * sizeof(uint16_t));
        int lastRxCounter;
-       int8_t *upTo;
-       int ci, cq;
+       uint16_t *upTo;
+       int8_t ci, cq;
        int maxBehindBy = 0;
 
        // Count of samples received so far, so that we can include timing
@@ -1211,7 +1149,7 @@ void RAMFUNC SnoopIso14443b(void)
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
        // Setup for the DMA.
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        upTo = dmaBuf;
        lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
        FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
@@ -1219,46 +1157,48 @@ void RAMFUNC SnoopIso14443b(void)
 
        bool TagIsActive = false;
        bool ReaderIsActive = false;
+       // We won't start recording the frames that we acquire until we trigger.
+       // A good trigger condition to get started is probably when we see a
+       // reader command
+       bool triggered = false;
 
        // And now we loop, receiving samples.
        for(;;) {
-               int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
-                                                               (ISO14443B_DMA_BUFFER_SIZE-1);
+               int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & (ISO14443B_DMA_BUFFER_SIZE-1);
                if(behindBy > maxBehindBy) {
                        maxBehindBy = behindBy;
                }
 
-               if(behindBy < 2) continue;
+               if(behindBy < 1) continue;
 
-               ci = upTo[0];
-               cq = upTo[1];
-               upTo += 2;
-               lastRxCounter -= 2;
-               if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {
-                       upTo = dmaBuf;
+               ci = *upTo>>8;
+               cq = *upTo;
+               upTo++;
+               lastRxCounter--;
+               if(upTo >= dmaBuf + ISO14443B_DMA_BUFFER_SIZE) {               // we have read all of the DMA buffer content.
+                       upTo = dmaBuf;                                             // start reading the circular buffer from the beginning again
                        lastRxCounter += ISO14443B_DMA_BUFFER_SIZE;
-                       AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
-                       AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;
-                       WDT_HIT();
-                       if(behindBy > (9*ISO14443B_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
-                               Dbprintf("blew circular buffer! behindBy=%d", behindBy);
-                               break;
-                       }
-                       if(!tracing) {
-                               DbpString("Reached trace limit");
+                       if(behindBy > (9*ISO14443B_DMA_BUFFER_SIZE/10)) { 
+                               Dbprintf("About to blow circular buffer - aborted! behindBy=%d", behindBy);
                                break;
                        }
+               }
+               if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX)) {              // DMA Counter Register had reached 0, already rotated.
+                       AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;          // refresh the DMA Next Buffer and
+                       AT91C_BASE_PDC_SSC->PDC_RNCR = ISO14443B_DMA_BUFFER_SIZE;  // DMA Next Counter registers
+                       WDT_HIT();
                        if(BUTTON_PRESS()) {
                                DbpString("cancelled");
                                break;
                        }
                }
 
-               samples += 2;
+               samples++;
 
                if (!TagIsActive) {                                                     // no need to try decoding reader data if the tag is sending
                        if(Handle14443bUartBit(ci & 0x01)) {
-                               if(triggered && tracing) {
+                               triggered = true;
+                               if(tracing) {
                                        LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, true);
                                }
                                /* And ready to receive another command. */
@@ -1268,7 +1208,8 @@ void RAMFUNC SnoopIso14443b(void)
                                DemodReset();
                        }
                        if(Handle14443bUartBit(cq & 0x01)) {
-                               if(triggered && tracing) {
+                               triggered = true;
+                               if(tracing) {
                                        LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, true);
                                }
                                /* And ready to receive another command. */
@@ -1280,8 +1221,8 @@ void RAMFUNC SnoopIso14443b(void)
                        ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
                }
 
-               if(!ReaderIsActive) {                                           // no need to try decoding tag data if the reader is sending - and we cannot afford the time
-                       if(Handle14443bSamplesDemod(ci | 0x01, cq | 0x01)) {
+               if(!ReaderIsActive && triggered) {                                              // no need to try decoding tag data if the reader is sending or not yet triggered
+                       if(Handle14443bSamplesDemod(ci/2, cq/2)) {
 
                                //Use samples as a time measurement
                                if(tracing)
@@ -1289,8 +1230,6 @@ void RAMFUNC SnoopIso14443b(void)
                                        uint8_t parity[MAX_PARITY_SIZE];
                                        LogTrace(Demod.output, Demod.len, samples, samples, parity, false);
                                }
-                               triggered = true;
-
                                // And ready to receive another response.
                                DemodReset();
                        }
@@ -1301,7 +1240,6 @@ void RAMFUNC SnoopIso14443b(void)
 
        FpgaDisableSscDma();
        LEDsoff();
-       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
        DbpString("Snoop statistics:");
        Dbprintf("  Max behind by: %i", maxBehindBy);
        Dbprintf("  Uart State: %x", Uart.state);
@@ -1327,7 +1265,11 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv, uint8_t powerfield, u
 {
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+
+       // switch field on and give tag some time to power up
+       LED_D_ON();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
+       SpinDelay(10);
 
        if (datalen){
                set_tracing(true);
index ad6f5cfc0e6b684d2b186e498aab06f85642702b..c092b3834ccfbd112091edad498ea26383e116e7 100644 (file)
@@ -227,26 +227,14 @@ static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *w
 {
     int c;
 
-//    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
        if(*wait < 10) { *wait = 10; }
 
-//    for(c = 0; c < *wait;) {
-//        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-//            AT91C_BASE_SSC->SSC_THR = 0x00;          // For exact timing!
-//            c++;
-//        }
-//        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-//            volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-//            (void)r;
-//        }
-//        WDT_HIT();
-//    }
-
     c = 0;
     for(;;) {
         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-            AT91C_BASE_SSC->SSC_THR = cmd[c];
+            AT91C_BASE_SSC->SSC_THR = ~cmd[c];
             c++;
             if(c >= len) {
                 break;
@@ -300,36 +288,25 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
 {
        int c = 0;
        uint8_t *dest = BigBuf_get_addr();
-       int getNext = 0;
-
-       int8_t prev = 0;
 
 // NOW READ RESPONSE
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        c = 0;
-       getNext = false;
        for(;;) {
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b;
-                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               uint8_t r = AMPLITUDE(b, prev);
+                       // tone that the tag AM-modulates. We just want power. 
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               dest[c++] = r;
-
-                               if(c >= 4000) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       dest[c++] = r;
+                       
+                       if(c >= 4000) {
+                               break;
                        }
-
-                       getNext = !getNext;
                }
        }
 
@@ -441,36 +418,26 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
 {
        int c = 0;
        uint8_t *dest = BigBuf_get_addr();
-       int getNext = 0;
-
-       int8_t prev = 0;
 
 // NOW READ RESPONSE
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        //spindelay(60);        // greg - experiment to get rid of some of the 0 byte/failed reads
        c = 0;
-       getNext = false;
        for(;;) {
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               uint8_t r = AMPLITUDE(b, prev);
+                       // tone that the tag AM-modulates. We just want power, 
+                       // so abs(I) + abs(Q) is close to what we want.
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               dest[c++] = r;
+                       dest[c++] = r;
 
-                               if(c >= BIGBUF_SIZE) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       if(c >= BIGBUF_SIZE) {
+                               break;
                        }
-
-                       getNext = !getNext;
                }
        }
 
@@ -585,8 +552,6 @@ void AcquireRawAdcSamplesIso15693(void)
        uint8_t *dest = BigBuf_get_addr();
 
        int c = 0;
-       int getNext = 0;
-       int8_t prev = 0;
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        BuildIdentifyRequest();
@@ -598,13 +563,13 @@ void AcquireRawAdcSamplesIso15693(void)
        SpinDelay(100);
 
        // Now send the command
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
 
        c = 0;
        for(;;) {
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = ToSend[c];
+                       AT91C_BASE_SSC->SSC_THR = ~ToSend[c];
                        c++;
                        if(c == ToSendMax+3) {
                                break;
@@ -613,32 +578,25 @@ void AcquireRawAdcSamplesIso15693(void)
                WDT_HIT();
        }
 
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        c = 0;
-       getNext = false;
        for(;;) {
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b;
-                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               uint8_t r = AMPLITUDE(b, prev);
+                       // tone that the tag AM-modulates. We just want power, 
+                       // so abs(I) + abs(Q) is close to what we want.
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               dest[c++] = r;
+                       dest[c++] = r;
 
-                               if(c >= 4000) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       if(c >= 4000) {
+                               break;
                        }
-
-                       getNext = !getNext;
                }
        }
 }
@@ -649,16 +607,14 @@ void RecordRawAdcSamplesIso15693(void)
        uint8_t *dest = BigBuf_get_addr();
 
        int c = 0;
-       int getNext = 0;
-       int8_t prev = 0;
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        // Setup SSC
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Start from off (no field generated)
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelay(200);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       SpinDelay(200);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
@@ -667,33 +623,24 @@ void RecordRawAdcSamplesIso15693(void)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        c = 0;
-       getNext = false;
        for(;;) {
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b;
-                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               uint8_t r = AMPLITUDE(b, prev);
+                       // tone that the tag AM-modulates. We just want power, 
+                       // so abs(I) + abs(Q) is close to what we want.
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               dest[c++] = r;
+                       dest[c++] = r;
 
-                               if(c >= 14000) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       if(c >= 14000) {
+                               break;
                        }
-
-                       getNext = !getNext;
-                       WDT_HIT();
                }
        }
-       Dbprintf("fin record");
+       Dbprintf("finished recording");
 }
 
 
@@ -714,7 +661,7 @@ void Iso15693InitReader() {
        SpinDelay(10);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Give the tags time to energize
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
@@ -973,7 +920,7 @@ void ReaderIso15693(uint32_t parameter)
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        // Setup SSC
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Start from off (no field generated)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1075,7 +1022,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
        memset(buf, 0x00, 100);
        
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Start from off (no field generated)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
index c8a4829f7d51c8b4abf658a9839d9c200211bb56..d3fd35d104e0ba590801a6442eb96d9dcefd022e 100644 (file)
@@ -63,11 +63,11 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
 // I/O interface abstraction (FPGA -> ARM)
 //-----------------------------------------------------------------------------
 
-static inline uint8_t rx_byte_from_fpga() {
+static inline uint16_t rx_frame_from_fpga() {
   for(;;) {
     WDT_HIT();
 
-    // wait for byte be become available in rx holding register
+    // wait for frame be become available in rx holding register
     if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
       return AT91C_BASE_SSC->SSC_RHR;
     }
@@ -88,33 +88,32 @@ static inline uint8_t rx_byte_from_fpga() {
 // To reduce CPU time the amplitude is approximated by using linear functions:
 //   am = MAX(ABS(i),ABS(q)) + 1/2*MIN(ABS(i),ABSq))
 //
-// Note: The SSC receiver is never synchronized the calculation my be performed
-// on a I/Q pair from two subsequent correlations, but does not matter.
-//
 // The bit time is 99.1us (21 I/Q pairs). The receiver skips the first 5 samples
 // and averages the next (most stable) 8 samples. The final 8 samples are dropped
 // also.
 //
-// The demedulated should be alligned to the bit periode by the caller. This is
+// The demodulated should be alligned to the bit period by the caller. This is
 // done in rx_bit and rx_ack.
 static inline bool rx_bit() {
-  int32_t cq = 0;
-  int32_t ci = 0;
+  int32_t sum_cq = 0;
+  int32_t sum_ci = 0;
 
   // skip first 5 I/Q pairs
   for(size_t i = 0; i<5; ++i) {
-    (int8_t)rx_byte_from_fpga();
-    (int8_t)rx_byte_from_fpga();
+    (void)rx_frame_from_fpga();
   }
 
   // sample next 8 I/Q pairs
   for(size_t i = 0; i<8; ++i) {
-    cq += (int8_t)rx_byte_from_fpga();
-    ci += (int8_t)rx_byte_from_fpga();
+    uint16_t iq = rx_frame_from_fpga();
+    int8_t ci = (int8_t)(iq >> 8);
+    int8_t cq = (int8_t)(iq & 0xff);
+    sum_ci += ci;
+    sum_cq += cq;
   }
 
   // calculate power
-  int32_t power = (MAX(ABS(ci), ABS(cq)) + (MIN(ABS(ci), ABS(cq)) >> 1));
+  int32_t power = (MAX(ABS(sum_ci), ABS(sum_cq)) + MIN(ABS(sum_ci), ABS(sum_cq))/2);
 
   // compare average (power / 8) to threshold
   return ((power >> 3) > INPUT_THRESHOLD);
@@ -131,12 +130,12 @@ static inline bool rx_bit() {
 
 static inline void tx_bit(bool bit) {
   // insert pause
-  LOW(GPIO_SSC_DOUT);
+  HIGH(GPIO_SSC_DOUT);
   last_frame_end += RWD_TIME_PAUSE;
   while(GET_TICKS < last_frame_end) { };
-  HIGH(GPIO_SSC_DOUT);
 
-  // return to high, wait for bit periode to end
+  // return to carrier on, wait for bit periode to end
+  LOW(GPIO_SSC_DOUT);
   last_frame_end += (bit ? RWD_TIME_1 : RWD_TIME_0) - RWD_TIME_PAUSE;
   while(GET_TICKS < last_frame_end) { };
 }
@@ -166,10 +165,10 @@ static void tx_frame(uint32_t frame, uint8_t len) {
   };
 
   // add pause to mark end of the frame
-  LOW(GPIO_SSC_DOUT);
+  HIGH(GPIO_SSC_DOUT);
   last_frame_end += RWD_TIME_PAUSE;
   while(GET_TICKS < last_frame_end) { };
-  HIGH(GPIO_SSC_DOUT);
+  LOW(GPIO_SSC_DOUT);
 }
 
 static uint32_t rx_frame(uint8_t len) {
@@ -265,12 +264,12 @@ static void init_reader(bool clear_mem) {
   LED_D_ON();
 
   // configure SSC with defaults
-  FpgaSetupSsc();
+  FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
   // re-claim GPIO_SSC_DOUT as GPIO and enable output
   AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
   AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
-  HIGH(GPIO_SSC_DOUT);
+  LOW(GPIO_SSC_DOUT);
 
   // init crc calculator
   crc_init(&legic_crc, 4, 0x19 >> 1, 0x05, 0);
index 34633f367cf7b939c7f3007ba536c8bbbc05ce87..a149e0f9e381d20bd4615d10d31de174bafa33e4 100644 (file)
@@ -284,7 +284,7 @@ static void init_tag() {
   SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
   // configure SSC with defaults
-  FpgaSetupSsc();
+  FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
 
   // first pull output to low to prevent glitches then re-claim GPIO_SSC_DOUT
   LOW(GPIO_SSC_DOUT);
index 911ba8da1c62e81d8fc7973928e931bf87cede3e..2fe49a8078e67c43705a84e1e489ff7860c3419a 100644 (file)
@@ -1818,7 +1818,7 @@ void Cotag(uint32_t arg0) {
        SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
 
        // Now set up the SSC to get the ADC samples that are now streaming at us.
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_LF_ADC);
 
        // start clock - 1.5ticks is 1us
        StartTicks();
index 3b0762653b7ea99ea2e1b2dcc1d01632e3dd08db..ffbc0da875ebe11e683fe9426b9c0630e39335ee 100644 (file)
@@ -101,7 +101,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
        // Give it a bit of time for the resonant antenna to settle.
        SpinDelay(50);
        // Now set up the SSC to get the ADC samples that are now streaming at us.
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_LF_ADC);
 }
 
 /**
index 179e87eed22bc326f37e33f6925116916701c6bf..bd296174f0978d3214bae003d25a7063bff60021 100644 (file)
Binary files a/fpga/fpga_hf.bit and b/fpga/fpga_hf.bit differ
index f637abf2012350f364e15d2606428bf6aca89311..8233960f5df3ff6cd65cddff1cb403f032340d5a 100644 (file)
@@ -197,9 +197,9 @@ begin
         end
     end
 
-       // set ssp_frame signal for corr_i_cnt = 0..3 and corr_i_cnt = 32..35
-       // (send two frames with 8 Bits each)
-    if(corr_i_cnt[5:2] == 4'b0000 || corr_i_cnt[5:2] == 4'b1000)
+    // set ssp_frame signal for corr_i_cnt = 0..3
+    // (send one frame with 16 Bits)
+    if(corr_i_cnt[5:2] == 4'b0000)
         ssp_frame = 1'b1;
     else
         ssp_frame = 1'b0;
index 756683cdde7d906336935073bbfa1bf29745612e..819f1697ed7d4f74a47e8aa51e62dbf283c2e9b7 100644 (file)
@@ -42,11 +42,11 @@ begin
         pwr_hi <= ck_1356megb;
         pwr_oe1 <= 1'b0;
         pwr_oe3 <= 1'b0;
-        pwr_oe4 <= ~ssp_dout;
+        pwr_oe4 <= ssp_dout;
     end
     else
     begin
-        pwr_hi <= ck_1356megb & ssp_dout;
+        pwr_hi <= ck_1356megb & ~ssp_dout;
         pwr_oe1 <= 1'b0;
         pwr_oe3 <= 1'b0;
         pwr_oe4 <= 1'b0;
Impressum, Datenschutz