#include "protocols.h"
#include "usb_cdc.h" // for usb_poll_validate_length
+#ifndef SHORT_COIL
+# define SHORT_COIL() LOW(GPIO_SSC_DOUT)
+#endif
+#ifndef OPEN_COIL
+# define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
+#endif
+
/**
* Function to do a modulation and then get samples.
* @param delay_off
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);
+ WaitUS(period_0);
else
- SpinDelayUs(period_1);
+ WaitUS(period_1);
}
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);
// 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);
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1000);
+ 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);
- // modulate antenna
+ WaitUS(300);
+ // modulate antenna 1m
HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1700);
+ WaitUS(1700);
}
}
}
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
{
- int i;
+ int i = 0;
uint8_t *tab = BigBuf_get_addr();
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
- #define SHORT_COIL() LOW(GPIO_SSC_DOUT)
- #define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
-
- i = 0;
for(;;) {
+ WDT_HIT();
+
+ if (ledcontrol) LED_D_ON();
+
//wait until SSC_CLK goes HIGH
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS() || usb_poll_validate_length() ) {
- DbpString("Stopped");
- return;
- }
WDT_HIT();
+ if ( usb_poll_validate_length() || BUTTON_PRESS() ) {
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_D_OFF();
+ return;
+ }
}
- if (ledcontrol) LED_D_ON();
-
+
if(tab[i])
OPEN_COIL();
else
//wait until SSC_CLK goes LOW
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
- if( BUTTON_PRESS() || usb_poll_validate_length() ) {
- DbpString("Stopped");
- return;
- }
WDT_HIT();
+ if ( usb_poll_validate_length() || BUTTON_PRESS() ) {
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_D_OFF();
+ return;
+ }
}
i++;
if(i == period) {
-
i = 0;
if (gap) {
+ WDT_HIT();
SHORT_COIL();
- SpinDelayUs(gap);
+ WaitUS(gap);
}
}
}
// simulate a HID tag until the button is pressed
void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
{
- int n=0, i=0;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ set_tracing(FALSE);
+
+ 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
nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
*/
- if (hi>0xFFF) {
+ if (hi > 0xFFF) {
DbpString("Tags can only have 44 bits. - USE lf simfsk for larger tags");
return;
}
fc(8, &n); fc(10, &n); // high-low transition
}
}
-
+ WDT_HIT();
+
if (ledcontrol) LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol);
if (ledcontrol) LED_A_OFF();
// 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;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+ // free eventually allocated BigBuf memory
+ BigBuf_free(); BigBuf_Clear_ext(false);
+ clear_trace();
+ set_tracing(FALSE);
+
+ int ledcontrol = 1, n = 0, i = 0;
uint8_t fcHigh = arg1 >> 8;
uint8_t fcLow = arg1 & 0xFF;
uint16_t modCnt = 0;
uint8_t invert = (arg2 >> 8) & 1;
for (i=0; i<size; i++){
- if (BitStream[i] == invert){
+
+ if (BitStream[i] == invert)
fcAll(fcLow, &n, clk, &modCnt);
- } else {
+ else
fcAll(fcHigh, &n, clk, &modCnt);
- }
}
- Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, invert: %d, n: %d",fcHigh, fcLow, clk, invert, n);
+ WDT_HIT();
+
+ Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, invert: %d, n: %d", fcHigh, fcLow, clk, invert, n);
if (ledcontrol) LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol);
// 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;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ set_tracing(FALSE);
+
+ int ledcontrol = 1, 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;
- if (encoding==2){ //biphase
- uint8_t phase=0;
+ 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
+ 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 if (separator==1)
Dbprintf("sorry but separator option not yet available");
+ WDT_HIT();
+
Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n);
if (ledcontrol) LED_A_ON();
// 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;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ set_tracing(FALSE);
+
+ int ledcontrol = 1, n = 0, i = 0;
uint8_t clk = arg1 >> 8;
uint8_t carrier = arg1 & 0xFF;
uint8_t invert = arg2 & 0xFF;
pskSimBit(carrier, &n, clk, &curPhase, TRUE);
}
}
+
+ WDT_HIT();
+
Dbprintf("Simulating with Carrier: %d, clk: %d, invert: %d, n: %d",carrier, clk, invert, n);
if (ledcontrol) LED_A_ON();
* Q5 tags seems to have issues when these values changes.
*/
-#define START_GAP 31*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
+#define START_GAP 50*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
+#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
+#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
+#define WRITE_1 54*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550
#define READ_GAP 15*8
// VALUES TAKEN FROM EM4x function: SendForward
// 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);
+// WRITE_0 = 23*8 , 9*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
// T0 = TIMER_CLOCK1 / 125000 = 192
// 1 Cycle = 8 microseconds(us) == 1 field clock
-void TurnReadLFOn(int delay) {
+// new timer:
+// = 1us = 1.5ticks
+// 1fc = 8us = 12ticks
+void TurnReadLFOn(uint32_t 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
-
- SpinDelayUs(delay);
+
+ // 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);
- SpinDelayUs(WRITE_GAP);
+ 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);
- SpinDelayUs(START_GAP);
+ WaitUS(START_GAP);
// reset tag - op code 00
T55xxWriteBit(0);
// Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayUs(START_GAP);
+ WaitUS(START_GAP);
// Opcode 10
T55xxWriteBit(1);
// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
// so wait a little more)
TurnReadLFOn(20 * 1000);
- //could attempt to do a read to confirm write took
- // as the tag should repeat back the new block
- // until it is reset, but to confirm it we would
- // need to know the current block 0 config mode
+
+ //could attempt to do a read to confirm write took
+ // as the tag should repeat back the new block
+ // until it is reset, but to confirm it we would
+ // need to know the current block 0 config mode
// turn field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
bool RegReadMode = (Block == 0xFF);
//clear buffer now so it does not interfere with timing later
- BigBuf_Clear_ext(false);
+ BigBuf_Clear_keep_EM();
//make sure block is at max 7
Block &= 0x7;
// Set up FPGA, 125kHz to power up the tag
LFSetupFPGAForADC(95, true);
+ SpinDelay(3);
// Trigger T55x7 Direct Access Mode with start gap
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayUs(START_GAP);
+ WaitUS(START_GAP);
// Opcode 1[page]
T55xxWriteBit(1);
// Send Block number (if direct access mode)
if (!RegReadMode)
- for (i = 0x04; i != 0; i >>= 1)
- T55xxWriteBit(Block & i);
+ for (i = 0x04; i != 0; i >>= 1)
+ T55xxWriteBit(Block & i);
// Turn field on to read the response
TurnReadLFOn(READ_GAP);
// Trigger T55x7 Direct Access Mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayUs(START_GAP);
+ WaitUS(START_GAP);
// Opcode 10
T55xxWriteBit(1);
//-----------------------------------
// EM4469 / EM4305 routines
//-----------------------------------
-#define FWD_CMD_LOGIN 0xC //including the even parity, binary mirrored
-#define FWD_CMD_WRITE 0xA
-#define FWD_CMD_READ 0x9
+#define FWD_CMD_LOGIN 0xC //including the even parity, binary mirrored
+#define FWD_CMD_WRITE 0xA
+#define FWD_CMD_READ 0x9
#define FWD_CMD_DISABLE 0x5
uint8_t forwardLink_data[64]; //array of forwarded bits
// 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);
+// WRITE_0 = 23*8 , 9*8
uint8_t Prepare_Cmd( uint8_t cmd ) {
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
+ 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)
+ 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)
+ 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)
+ WaitUS(16*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)
+ WaitUS(16*8); //16 cycles on (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
}
}
}
void EM4xLogin(uint32_t Password) {
uint8_t fwd_bit_count;
-
forward_ptr = forwardLink_data;
fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 );
-
SendForward(fwd_bit_count);
//Wait for command to complete
- SpinDelay(20);
+ WaitMS(20);
}
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
uint8_t fwd_bit_count;
uint8_t *dest = BigBuf_get_addr();
- uint16_t bufsize = BigBuf_max_traceLen();
+ uint16_t bufsize = BigBuf_max_traceLen(); // ICEMAN: this tries to fill up all tracelog space
uint32_t i = 0;
// Clear destination buffer before sending the command
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
fwd_bit_count += Prepare_Addr( Address );
- // 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();
-
SendForward(fwd_bit_count);
// Now do the acquisition
+ // ICEMAN, change to the one in lfsampling.c
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
SendForward(fwd_bit_count);
//Wait for write to complete
- SpinDelay(20);
+ WaitMS(20);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}