mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-12 16:22:59 -07:00
send LF commands to TAG (locomread)
This commit is contained in:
parent
ac174b297a
commit
959baa89f7
5 changed files with 920 additions and 818 deletions
102
armsrc/appmain.c
102
armsrc/appmain.c
|
@ -91,12 +91,6 @@ void DbpIntegers(int x1, int x2, int x3)
|
|||
|
||||
void AcquireRawAdcSamples125k(BOOL at134khz)
|
||||
{
|
||||
BYTE *dest = (BYTE *)BigBuf;
|
||||
int n = sizeof(BigBuf);
|
||||
int i;
|
||||
|
||||
memset(dest,0,n);
|
||||
|
||||
if(at134khz) {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
|
||||
|
@ -114,6 +108,18 @@ void AcquireRawAdcSamples125k(BOOL at134khz)
|
|||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
|
||||
// Now call the acquisition routine
|
||||
DoAcquisition125k(at134khz);
|
||||
}
|
||||
|
||||
// split into two routines so we can avoid timing issues after sending commands //
|
||||
void DoAcquisition125k(BOOL at134khz)
|
||||
{
|
||||
BYTE *dest = (BYTE *)BigBuf;
|
||||
int n = sizeof(BigBuf);
|
||||
int i;
|
||||
|
||||
memset(dest,0,n);
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
|
||||
|
@ -132,6 +138,64 @@ void AcquireRawAdcSamples125k(BOOL at134khz)
|
|||
DbpIntegers(dest[0], dest[1], at134khz);
|
||||
}
|
||||
|
||||
void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYTE *command)
|
||||
{
|
||||
BOOL at134khz;
|
||||
|
||||
// see if 'h' was specified
|
||||
if(command[strlen(command) - 1] == 'h')
|
||||
at134khz= TRUE;
|
||||
else
|
||||
at134khz= FALSE;
|
||||
|
||||
if(at134khz) {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
|
||||
} else {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
// now modulate the reader field
|
||||
while(*command != '\0' && *command != ' ')
|
||||
{
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelayUs(delay_off);
|
||||
if(at134khz) {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
|
||||
} else {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
|
||||
}
|
||||
LED_D_ON();
|
||||
if(*(command++) == '0')
|
||||
SpinDelayUs(period_0);
|
||||
else
|
||||
SpinDelayUs(period_1);
|
||||
}
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelayUs(delay_off);
|
||||
if(at134khz) {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
|
||||
} else {
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
|
||||
}
|
||||
|
||||
// now do the read
|
||||
DoAcquisition125k(at134khz);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Read an ADC channel and block till it completes, then return the result
|
||||
// in ADC units (0 to 1023). Also a routine to average 32 samples and
|
||||
|
@ -607,6 +671,10 @@ void UsbPacketReceived(BYTE *packet, int len)
|
|||
AcquireRawAdcSamples125k(c->ext1);
|
||||
break;
|
||||
|
||||
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||
ModThenAcquireRawAdcSamples125k(c->ext1,c->ext2,c->ext3,c->d.asBytes);
|
||||
break;
|
||||
|
||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
|
||||
AcquireRawAdcSamplesIso15693();
|
||||
break;
|
||||
|
@ -793,6 +861,28 @@ void AppMain(void)
|
|||
}
|
||||
}
|
||||
|
||||
void SpinDelayUs(int us)
|
||||
{
|
||||
int ticks = (48*us) >> 10;
|
||||
|
||||
// Borrow a PWM unit for my real-time clock
|
||||
PWM_ENABLE = PWM_CHANNEL(0);
|
||||
// 48 MHz / 1024 gives 46.875 kHz
|
||||
PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
|
||||
PWM_CH_DUTY_CYCLE(0) = 0;
|
||||
PWM_CH_PERIOD(0) = 0xffff;
|
||||
|
||||
WORD start = (WORD)PWM_CH_COUNTER(0);
|
||||
|
||||
for(;;) {
|
||||
WORD now = (WORD)PWM_CH_COUNTER(0);
|
||||
if(now == (WORD)(start + ticks)) {
|
||||
return;
|
||||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
}
|
||||
|
||||
void SpinDelay(int ms)
|
||||
{
|
||||
int ticks = (48000*ms) >> 10;
|
||||
|
|
|
@ -12,8 +12,11 @@ void AppMain(void);
|
|||
void DbpIntegers(int a, int b, int c);
|
||||
void DbpString(char *str);
|
||||
void SpinDelay(int ms);
|
||||
void SpinDelayUs(int us);
|
||||
void ToSendStuffBit(int b);
|
||||
void ToSendReset(void);
|
||||
void AcquireRawAdcSamples125k(BOOL at134khz);
|
||||
void DoAcquisition125k(BOOL at134khz);
|
||||
extern int ToSendMax;
|
||||
extern BYTE ToSend[];
|
||||
extern DWORD BigBuf[];
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef struct {
|
|||
#define CMD_HID_SIM_TAG 0x0209 // ## New command: simulate HID tag by ID
|
||||
#define CMD_SET_LF_DIVISOR 0x020A
|
||||
#define CMD_SWEEP_LF 0x020B
|
||||
#define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x020C
|
||||
|
||||
// For the 13.56 MHz tags
|
||||
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "prox.h"
|
||||
#include "../common/iso14443_crc.c"
|
||||
|
@ -535,6 +536,21 @@ static void CmdLoread(char *str)
|
|||
SendCommand(&c, FALSE);
|
||||
}
|
||||
|
||||
/* send a command before reading */
|
||||
static void CmdLoCommandRead(char *str)
|
||||
{
|
||||
static char dummy[3];
|
||||
|
||||
dummy[0]= ' ';
|
||||
|
||||
UsbCommand c;
|
||||
c.cmd = CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K;
|
||||
sscanf(str, "%i %i %i %s %s", &c.ext1, &c.ext2, &c.ext3, &c.d.asBytes,&dummy+1);
|
||||
// in case they specified 'h'
|
||||
strcpy(&c.d.asBytes + strlen(c.d.asBytes),dummy);
|
||||
SendCommand(&c, FALSE);
|
||||
}
|
||||
|
||||
static void CmdLosamples(char *str)
|
||||
{
|
||||
int cnt = 0;
|
||||
|
@ -2065,7 +2081,7 @@ static void Cmdmanchestermod(char *str)
|
|||
* Typical values can be 64, 32, 128...
|
||||
*/
|
||||
static void Cmdmanchesterdemod(char *str) {
|
||||
int i, j, invert= 0;
|
||||
int i, j;
|
||||
int bit;
|
||||
int clock;
|
||||
int lastval;
|
||||
|
@ -2077,16 +2093,6 @@ static void Cmdmanchesterdemod(char *str) {
|
|||
int bit2idx = 0;
|
||||
int warnings = 0;
|
||||
|
||||
/* check if we're inverting output */
|
||||
if(*str == 'i')
|
||||
{
|
||||
PrintToScrollback("Inverting output");
|
||||
invert= 1;
|
||||
do
|
||||
++str;
|
||||
while(*str == ' '); // in case a 2nd argument was given
|
||||
}
|
||||
|
||||
/* Holds the decoded bitstream: each clock period contains 2 bits */
|
||||
/* later simplified to 1 bit after manchester decoding. */
|
||||
/* Add 10 bits to allow for noisy / uncertain traces without aborting */
|
||||
|
@ -2157,7 +2163,7 @@ static void Cmdmanchesterdemod(char *str) {
|
|||
if (!hithigh || !hitlow)
|
||||
bit ^= 1;
|
||||
|
||||
BitStream[bit2idx++] = bit ^ invert;
|
||||
BitStream[bit2idx++] = bit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2209,9 +2215,9 @@ static void Cmdmanchesterdemod(char *str) {
|
|||
// to stop output at the final bitidx2 value, not bitidx
|
||||
for (i = 0; i < bitidx; i += 2) {
|
||||
if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
|
||||
BitStream[bit2idx++] = 1 ^ invert;
|
||||
BitStream[bit2idx++] = 1;
|
||||
} else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
|
||||
BitStream[bit2idx++] = 0 ^ invert;
|
||||
BitStream[bit2idx++] = 0;
|
||||
} else {
|
||||
// We cannot end up in this state, this means we are unsynchronized,
|
||||
// move up 1 bit:
|
||||
|
@ -2450,11 +2456,12 @@ static struct {
|
|||
"lcd", CmdLcd,0, "<HEX command> <count> -- Send command/data to LCD",
|
||||
"lcdreset", CmdLcdReset,0, " Hardware reset LCD",
|
||||
"load", CmdLoad,1, "<filename> -- Load trace (to graph window",
|
||||
"locomread", CmdLoCommandRead,0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)",
|
||||
"loread", CmdLoread,0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)",
|
||||
"losamples", CmdLosamples,0, "[128 - 16000] -- Get raw samples for LF tag",
|
||||
"losim", CmdLosim,0, " Simulate LF tag",
|
||||
"ltrim", CmdLtrim,1, "<samples> -- Trim samples from left of trace",
|
||||
"mandemod", Cmdmanchesterdemod,1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)",
|
||||
"mandemod", Cmdmanchesterdemod,1, "[clock rate] -- Try a Manchester demodulation on a binary stream",
|
||||
"manmod", Cmdmanchestermod,1, "[clock rate] -- Manchester modulate a binary stream",
|
||||
"norm", CmdNorm,1, " Normalize max/min to +/-500",
|
||||
"plot", CmdPlot,1, " Show graph window",
|
||||
|
|
|
@ -51,6 +51,7 @@ int CmdClearGraph(int redraw);
|
|||
static void CmdAppendGraph(int redraw, int clock, int bit);
|
||||
static void CmdEM410xsim(char *str);
|
||||
static void CmdLosim(char *str);
|
||||
static void CmdLoCommandRead(char *str);
|
||||
static void CmdLoread(char *str);
|
||||
static void CmdLosamples(char *str);
|
||||
static void CmdBitsamples(char *str);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue