#include "crc16.h"
#include "string.h"
- void DoAcquisition125k_internal(bool silent)
+// split into two routines so we can avoid timing issues after sending commands //
- i++;
++void DoAcquisition125k_internal(int trigger_threshold,bool silent)
+{
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int n = sizeof(BigBuf);
+ int i;
+
+ memset(dest, 0, n);
+ 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;
- if (i >= n) break;
+ LED_D_OFF();
- if( ! silent)
++ if (trigger_threshold != -1 && dest[i] < trigger_threshold)
++ continue;
++ else
++ trigger_threshold = -1;
++ if (++i >= n) break;
+ }
+ }
-
- void DoAcquisition125k(void)
++ if(!silent)
+ {
+ Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
++
+ }
+}
- DoAcquisition125k_internal(false);
++void DoAcquisition125k(int trigger_threshold)
+{
- void SetupToAcquireRawAdcSamples(int divisor)
++ DoAcquisition125k_internal(trigger_threshold, false);
+}
+
++//void SetupToAcquireRawAdcSamples(int divisor)
+ void LFSetupFPGAForADC(int divisor, bool lf_field)
{
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
else if (divisor == 0)
void AcquireRawAdcSamples125k(int divisor)
{
- SetupToAcquireRawAdcSamples(divisor);
+ LFSetupFPGAForADC(divisor, true);
- DoAcquisition125k(-1);
+ // Now call the acquisition routine
- DoAcquisition125k_internal(false);
++ DoAcquisition125k_internal(-1,false);
+ }
-
+ void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
+ {
+ LFSetupFPGAForADC(divisor, false);
- DoAcquisition125k(trigger_threshold);
++ DoAcquisition125k(trigger_threshold, false);
+ }
+
-// split into two routines so we can avoid timing issues after sending commands //
-void DoAcquisition125k(int trigger_threshold)
-{
- uint8_t *dest = (uint8_t *)BigBuf;
- int n = sizeof(BigBuf);
- int i;
+
- memset(dest, 0, n);
- 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;
- LED_D_OFF();
- if (trigger_threshold != -1 && dest[i] < trigger_threshold)
- continue;
- else
- trigger_threshold = -1;
- if (++i >= n) break;
- }
- }
- Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
- dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
LED_A_OFF();
}
-
-// loop to capture raw HID waveform then FSK demodulate the TAG ID from it
-void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
+size_t fsk_demod(uint8_t * dest, size_t size)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- int m=0, n=0, i=0, idx=0, found=0, lastval=0;
- uint32_t hi2=0, hi=0, lo=0;
+ uint32_t last_transition = 0;
+ uint32_t idx = 1;
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ // 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
+ uint8_t threshold_value = 127;
-
- // Connect the A/D to the peak-detected low-frequency path.
- SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+ // sync to first lo-hi transition, and threshold
- // Give it a bit of time for the resonant antenna to settle.
- SpinDelay(50);
+ //Need to threshold first sample
+ if(dest[0] < threshold_value) dest[0] = 0;
+ else dest[0] = 1;
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
+ size_t numBits = 0;
+ // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
+ // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
+ // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
+ for(idx = 1; idx < size; idx++) {
+ // threshold current value
+ if (dest[idx] < threshold_value) dest[idx] = 0;
+ else dest[idx] = 1;
- for(;;) {
- WDT_HIT();
- if (ledcontrol)
- LED_A_ON();
- if(BUTTON_PRESS()) {
- DbpString("Stopped");
- if (ledcontrol)
- LED_A_OFF();
- return;
- }
+ // Check for 0->1 transition
+ if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
- i = 0;
- m = sizeof(BigBuf);
- memset(dest,128,m);
- for(;;) {
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = 0x43;
- if (ledcontrol)
- 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 (ledcontrol)
- LED_D_OFF();
- if(i >= m) {
- break;
- }
+ if (idx-last_transition < 9) {
+ dest[numBits]=1;
+ } else {
+ dest[numBits]=0;
}
+ last_transition = idx;
+ numBits++;
}
+ }
+ return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0
+}
- // FSK demodulator
- // sync to first lo-hi transition
- for( idx=1; idx<m; idx++) {
- if (dest[idx-1]<dest[idx])
- lastval=idx;
- break;
+size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, uint8_t maxConsequtiveBits )
+{
+ uint8_t lastval=dest[0];
+ uint32_t idx=0;
+ size_t numBits=0;
+ uint32_t n=1;
+
+ for( idx=1; idx < size; idx++) {
+
+ if (dest[idx]==lastval) {
+ n++;
+ continue;
+ }
+ //if lastval was 1, we have a 1->0 crossing
+ if ( dest[idx-1] ) {
+ n=(n+1) / h2l_crossing_value;
+ } else {// 0->1 crossing
+ n=(n+1) / l2h_crossing_value;
+ }
+ if (n == 0) n = 1;
+
+ if(n < maxConsequtiveBits)
+ {
+ memset(dest+numBits, dest[idx-1] , n);
+ numBits += n;
}
- SetupToAcquireRawAdcSamples(0);
+ n=0;
+ lastval=dest[idx];
+ }//end for
+
+ return numBits;
+
+}
+// loop to capture raw HID waveform then FSK demodulate the TAG ID from it
+void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
+{
+ uint8_t *dest = (uint8_t *)BigBuf;
+
+ size_t size=0,idx=0; //, found=0;
+ uint32_t hi2=0, hi=0, lo=0;
+
+
+ while(!BUTTON_PRESS()) {
+
+ // Configure to go in 125Khz listen mode
++ LFSetupFPGAForADC(0, true)
+
WDT_HIT();
+ if (ledcontrol) LED_A_ON();
- // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
- // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
- // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
- for( i=0; idx<m; idx++) {
- if (dest[idx-1]<dest[idx]) {
- dest[i]=idx-lastval;
- if (dest[i] <= 8) {
- dest[i]=1;
- } else {
- dest[i]=0;
- }
+ DoAcquisition125k_internal(true);
+ size = sizeof(BigBuf);
- lastval=idx;
- i++;
- }
- }
- m=i;
+ // FSK demodulator
+ size = fsk_demod(dest, size);
WDT_HIT();
// we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = (uint8_t *)BigBuf;
- int m=0, n=0, i=0, idx=0, lastval=0;
- int found=0;
- uint32_t code=0, code2=0;
- //uint32_t hi2=0, hi=0, lo=0;
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ size_t size=0, idx=0;
+ uint32_t code=0, code2=0;
- // Connect the A/D to the peak-detected low-frequency path.
- SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
- // Give it a bit of time for the resonant antenna to settle.
- SpinDelay(50);
+ while(!BUTTON_PRESS()) {
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
+ // Configure to go in 125Khz listen mode
- SetupToAcquireRawAdcSamples(0);
++ LFSetupFPGAForADC(0, true);
- for(;;) {
WDT_HIT();
- if (ledcontrol)
- LED_A_ON();
- if(BUTTON_PRESS()) {
- DbpString("Stopped");
- if (ledcontrol)
- LED_A_OFF();
- return;
- }
+ if (ledcontrol) LED_A_ON();
- i = 0;
- m = sizeof(BigBuf);
- memset(dest,128,m);
- for(;;) {
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = 0x43;
- if (ledcontrol)
- 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 (ledcontrol)
- LED_D_OFF();
- if(i >= m) {
- break;
- }
- }
- }
+ DoAcquisition125k_internal(true);
+ size = sizeof(BigBuf);
// FSK demodulator
-
- // sync to first lo-hi transition
- for( idx=1; idx<m; idx++) {
- if (dest[idx-1]<dest[idx])
- lastval=idx;
- break;
- }
- WDT_HIT();
-
- // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
- // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
- // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
- for( i=0; idx<m; idx++) {
- if (dest[idx-1]<dest[idx]) {
- dest[i]=idx-lastval;
- if (dest[i] <= 8) {
- dest[i]=1;
- } else {
- dest[i]=0;
- }
-
- lastval=idx;
- i++;
- }
- }
- m=i;
+ size = fsk_demod(dest, size);
WDT_HIT();
// we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns