I've added a precise timer in the new files ticks.c and moved some older stuff from util.c to have a solid base for this.
UNTESTED, and the timings measured for t55x7 in lfops.c and other parts has not been adjusted to this "correct" timer.
while(*command != '\0' && *command != ' ') {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
- SpinDelayUs(delay_off);
+ WaitUS(delay_off);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
LED_D_ON();
if(*(command++) == '0')
- SpinDelayUs(period_0); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(period_0);
else
- SpinDelayUs(period_1); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(period_1);
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
- SpinDelayUs(delay_off); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(delay_off);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// modulate 8 bits out to the antenna
for (i=0; i<8; i++)
{
- if (b&(1<<i)) {
- // stop modulating antenna
+ if ( b & ( 1 << i ) ) {
+ // stop modulating antenna 1ms
LOW(GPIO_SSC_DOUT);
- SpinDelayUs(1000); // ICEMAN: problem with (us) clock is 21.3us increments
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1000); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(1000);
+ // modulate antenna 1ms
+ HIGH(GPIO_SSC_DOUT);
+ WaitUS(1000);
} else {
- // stop modulating antenna
+ // stop modulating antenna 1ms
LOW(GPIO_SSC_DOUT);
- SpinDelayUs(300); // ICEMAN: problem with (us) clock is 21.3us increments
- // modulate antenna
+ WaitUS(300);
+ // modulate antenna 1m
HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1700); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(1700);
}
}
}
if (gap) {
WDT_HIT();
SHORT_COIL();
- SpinDelayUs(gap); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(gap);
}
}
}
void TurnReadLFOn(int delay) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- // Give it a bit of time for the resonant antenna to settle.
// measure antenna strength.
//int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
- // where to save it
-
- SpinDelayCountUs(delay); // ICEMAN: problem with (us) clock is 21.3us increments
+
+ // Give it a bit of time for the resonant antenna to settle.
+ WaitUS(delay);
}
// Write one bit to card
else
TurnReadLFOn(WRITE_1);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayCountUs(WRITE_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(WRITE_GAP);
}
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
// Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayCountUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(START_GAP);
// reset tag - op code 00
T55xxWriteBit(0);
// Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayCountUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(START_GAP);
// Opcode 10
T55xxWriteBit(1);
// Trigger T55x7 Direct Access Mode with start gap
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayCountUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(START_GAP);
// Opcode 1[page]
T55xxWriteBit(1);
// Trigger T55x7 Direct Access Mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayCountUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(START_GAP);
// Opcode 10
T55xxWriteBit(1);
fwd_bit_sz--; //prepare next bit modulation
fwd_write_ptr++;
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(55*8); //55 cycles off (8us each)for 4305 // ICEMAN: problem with (us) clock is 21.3us increments
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
- SpinDelayUs(16*8); //16 cycles on (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(16*8); //16 cycles on (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
// now start writting
while(fwd_bit_sz-- > 0) { //prepare next bit modulation
if(((*fwd_write_ptr++) & 1) == 1)
- SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(32*8); //32 cycles at 125Khz (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
else {
//These timings work for 4469/4269/4305 (with the 55*8 above)
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- SpinDelayUs(23*8); //16-4 cycles off (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(23*8); //16-4 cycles off (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
- SpinDelayUs(9*8); //16 cycles on (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
+ WaitUS(9*8); //16 cycles on (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
}
}
}
// Miscellaneous routines for low frequency sampling.
//-----------------------------------------------------------------------------
-#include "proxmark3.h"
-#include "apps.h"
-#include "util.h"
-#include "string.h"
-#include "usb_cdc.h" // for usb_poll_validate_length
#include "lfsampling.h"
sample_config config = { 1, 8, 1, 95, 0 } ;
-void printConfig()
-{
+void printConfig() {
Dbprintf("LF Sampling config: ");
Dbprintf(" [q] divisor: %d ", config.divisor);
Dbprintf(" [b] bps: %d ", config.bits_per_sample);
* @brief setSamplingConfig
* @param sc
*/
-void setSamplingConfig(sample_config *sc)
-{
+void setSamplingConfig(sample_config *sc) {
if(sc->divisor != 0) config.divisor = sc->divisor;
if(sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample;
if(sc->decimation != 0) config.decimation = sc->decimation;
printConfig();
}
-sample_config* getSamplingConfig()
-{
+sample_config* getSamplingConfig() {
return &config;
}
* @param stream
* @param bit
*/
-void pushBit( BitstreamOut* stream, uint8_t bit)
-{
+void pushBit( BitstreamOut* stream, uint8_t bit) {
int bytepos = stream->position >> 3; // divide by 8
int bitpos = stream->position & 7;
*(stream->buffer+bytepos) |= (bit > 0) << (7 - bitpos);
* 0 or 95 ==> 125 KHz
*
**/
-void LFSetupFPGAForADC(int divisor, bool lf_field)
-{
+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
SpinDelay(50);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
+
+ // start a 1.5ticks is 1us
+ StartTicks();
}
/**
* @param silent - is true, now outputs are made. If false, dbprints the status
* @return the number of bits occupied by the samples.
*/
-uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent)
-{
+uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent) {
//bigbuf, to hold the aquired raw data signal
uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = BigBuf_max_traceLen();
* @param silent
* @return number of bits sampled
*/
-uint32_t DoAcquisition_default(int trigger_threshold, bool silent)
-{
+uint32_t DoAcquisition_default(int trigger_threshold, bool silent) {
return DoAcquisition(1,8,0,trigger_threshold,silent);
}
-uint32_t DoAcquisition_config( bool silent)
-{
+uint32_t DoAcquisition_config( bool silent) {
return DoAcquisition(config.decimation
,config.bits_per_sample
,config.averaging
,silent);
}
-uint32_t ReadLF(bool activeField, bool silent)
-{
- if (!silent) printConfig();
+uint32_t ReadLF(bool activeField, bool silent) {
+ if (!silent)
+ printConfig();
LFSetupFPGAForADC(config.divisor, activeField);
- // Now call the acquisition routine
return DoAcquisition_config(silent);
}
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
**/
-uint32_t SampleLF(bool printCfg)
-{
+uint32_t SampleLF(bool printCfg) {
return ReadLF(true, printCfg);
}
/**
**/
void doT55x7Acquisition(size_t sample_size) {
- #define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph
- #define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph
- #define T55xx_READ_TOL 5
-
+ #define T55xx_READ_UPPER_THRESHOLD 128+40 // 60 grph
+ #define T55xx_READ_LOWER_THRESHOLD 128-40 // -60 grph
+ #define T55xx_READ_TOL 2
+
uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = BigBuf_max_traceLen();
if ( bufsize > sample_size )
bufsize = sample_size;
- uint16_t i = 0;
+ uint8_t curSample = 0, lastSample = 0;
+ uint16_t i = 0, skipCnt = 0;
bool startFound = false;
bool highFound = false;
bool lowFound = false;
- uint8_t curSample = 0;
- uint8_t lastSample = 0;
- uint16_t skipCnt = 0;
+
while(!BUTTON_PRESS() && !usb_poll_validate_length() && skipCnt < 1000 && (i < bufsize) ) {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
// skip until first high samples begin to change
- if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD+T55xx_READ_TOL){
+ if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){
// if just found start - recover last sample
if (!startFound) {
dest[i++] = lastSample;
#ifndef LFSAMPLING_H
#define LFSAMPLING_H
+#include "proxmark3.h"
+#include "apps.h"
+#include "util.h"
+#include "string.h"
+#include "usb_cdc.h" // for usb_poll_validate_length
+#include "ticks.h" // for StartTicks
+
/**
* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
* the data is collected in BigBuf.
// SpinDelay(1000);
// ti = GetTickCount() - ti;
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
-
void StartTickCount() {
// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TCB->TCB_BCR = 1;
- while (AT91C_BASE_TC1->TC_CV >= 1);
+ while (AT91C_BASE_TC1->TC_CV > 1);
}
uint32_t RAMFUNC GetCountUS(){
//enable clock of timer and software trigger
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
- while (AT91C_BASE_TC1->TC_CV >= 1);
+ while (AT91C_BASE_TC1->TC_CV > 1);
}
-// attempt at high resolution microsecond timer
-// beware: timer counts in 21.3uS increments (1024/48Mhz)
-void SpinDelayCountUs(uint32_t us) {
- if (us < 8) return;
- us += GetCountUS();
- while ( GetCountUS() < us ){}
-}
-// static uint32_t GlobalUsCounter = 0;
-// uint32_t RAMFUNC GetDeltaCountUS(){
- // uint32_t g_cnt = GetCountUS();
- // uint32_t g_res = g_cnt - GlobalUsCounter;
- // GlobalUsCounter = g_cnt;
- // return g_res;
-// }
+
// -------------------------------------------------------------------------
// Timer for iso14443 commands. Uses ssp_clk from FPGA
// -------------------------------------------------------------------------
// The high word of the counter (TC2) will not reset until the low word (TC0) overflows.
// Therefore need to wait quite some time before we can use the counter.
- while (AT91C_BASE_TC2->TC_CV >= 1);
+ while (AT91C_BASE_TC2->TC_CV > 1);
}
void ResetSspClk(void) {
//enable clock of timer and software trigger
}
+// -------------------------------------------------------------------------
+// Timer for bitbanging, or LF stuff when you need a very precis timer
+// 1us = 1.5ticks
+// -------------------------------------------------------------------------
void StartTicks(void){
//initialization of the timer
AT91C_BASE_PMC->PMC_PCER |= (1 << 12) | (1 << 13) | (1 << 14);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
-
- // fast clock TC0
- // tick=1.5mks
- AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
+ AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
-
- // Enable and reset timer
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TCB->TCB_BCR = 1;
// wait until timer becomes zero.