mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-22 14:13:42 -07:00
Timing analysis now starts when first bit is received.
This commit is contained in:
parent
7a5acc71ac
commit
d4a97eb4c7
2 changed files with 50 additions and 19 deletions
|
@ -88,6 +88,9 @@ uint8_t trigger = 0;
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
static uint8_t iso14_pcb_blocknum = 0;
|
static uint8_t iso14_pcb_blocknum = 0;
|
||||||
|
|
||||||
|
int manchester_recv_started = 0;
|
||||||
|
int recorded = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
// ISO14443 timing:
|
// ISO14443 timing:
|
||||||
//
|
//
|
||||||
|
@ -292,12 +295,12 @@ static void UartInit(uint8_t *data, uint8_t *parity)
|
||||||
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
||||||
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||||
{
|
{
|
||||||
|
//Dbprintf("Miller decoding now!");
|
||||||
Uart.fourBits = (Uart.fourBits << 8) | bit;
|
Uart.fourBits = (Uart.fourBits << 8) | bit;
|
||||||
|
|
||||||
if (Uart.state == STATE_UNSYNCD) { // not yet synced
|
if (Uart.state == STATE_UNSYNCD) { // not yet synced
|
||||||
|
|
||||||
Uart.syncBit = 9999; // not set
|
Uart.syncBit = 9999; // not set
|
||||||
// The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
|
// The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
|
||||||
// Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
|
// Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
|
||||||
// we therefore look for a ...xx11111111111100x11111xxxxxx... pattern
|
// we therefore look for a ...xx11111111111100x11111xxxxxx... pattern
|
||||||
|
@ -463,6 +466,7 @@ static void DemodInit(uint8_t *data, uint8_t *parity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
||||||
|
// Input *bit* to the Manchester decoding is four bytes (32 bits) which are read from the RHR.
|
||||||
static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time)
|
static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -470,7 +474,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||||
|
|
||||||
if (Demod.state == DEMOD_UNSYNCD) {
|
if (Demod.state == DEMOD_UNSYNCD) {
|
||||||
|
|
||||||
if (Demod.highCnt < 2) { // wait for a stable unmodulated signal
|
if (Demod.highCnt < 2) { // wait for a stable unmodulated signal
|
||||||
if (Demod.twoBits == 0x0000) {
|
if (Demod.twoBits == 0x0000) {
|
||||||
Demod.highCnt++;
|
Demod.highCnt++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -494,14 +498,18 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else { //Demod.state == DEMOD_MANCHESTER_DATA
|
||||||
|
//Determine the modulation details for each nibble (4 bits) separately
|
||||||
if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half
|
if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // if modulation in first half
|
||||||
if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half = collision
|
if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // ... and in second half, that specifies collision
|
||||||
|
//Save the collision position and treat as Sequence D
|
||||||
if (!Demod.collisionPos) {
|
if (!Demod.collisionPos) {
|
||||||
Demod.collisionPos = (Demod.len << 3) + Demod.bitCount;
|
Demod.collisionPos = (Demod.len << 3) + Demod.bitCount;
|
||||||
}
|
}
|
||||||
} // modulation in first half only - Sequence D = 1
|
}
|
||||||
|
if(!recorded)
|
||||||
|
manchester_recv_started = 1; //specify that the data transfer has begun
|
||||||
|
// modulation in first half only - Sequence D = 1.
|
||||||
Demod.bitCount++;
|
Demod.bitCount++;
|
||||||
Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg
|
Demod.shiftReg = (Demod.shiftReg >> 1) | 0x100; // in both cases, add a 1 to the shiftreg
|
||||||
if(Demod.bitCount == 9) { // if we decoded a full byte (including parity)
|
if(Demod.bitCount == 9) { // if we decoded a full byte (including parity)
|
||||||
|
@ -516,7 +524,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1) - 4;
|
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1) - 4;
|
||||||
} else { // no modulation in first half
|
} else { // if no modulation in first half
|
||||||
if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0
|
if (IsManchesterModulationNibble2(Demod.twoBits >> Demod.syncBit)) { // and modulation in second half = Sequence E = 0
|
||||||
Demod.bitCount++;
|
Demod.bitCount++;
|
||||||
Demod.shiftReg = (Demod.shiftReg >> 1); // add a 0 to the shiftreg
|
Demod.shiftReg = (Demod.shiftReg >> 1); // add a 0 to the shiftreg
|
||||||
|
@ -532,7 +540,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1);
|
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1);
|
||||||
} else { // no modulation in both halves - End of communication
|
} else { // no modulation in both halves - End of communication
|
||||||
if(Demod.bitCount > 0) { // there are some remaining data bits
|
if(Demod.bitCount > 0) { // there are some remaining data bits
|
||||||
Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits
|
Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits
|
||||||
Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output
|
Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output
|
||||||
|
@ -1289,6 +1297,8 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
|
||||||
// clear TXRDY
|
// clear TXRDY
|
||||||
AT91C_BASE_SSC->SSC_THR = SEC_Y;
|
AT91C_BASE_SSC->SSC_THR = SEC_Y;
|
||||||
|
|
||||||
|
Dbprintf("Sending bytes to the PICC.");
|
||||||
|
|
||||||
uint16_t c = 0;
|
uint16_t c = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||||
|
@ -1579,6 +1589,10 @@ int EmSendPrecompiledCmd(tag_response_info_t *response_info) {
|
||||||
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
|
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
|
||||||
{
|
{
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
|
uint32_t start_ts = GetCountSspClk();
|
||||||
|
uint32_t end_ts = 0;
|
||||||
|
manchester_recv_started = 0;
|
||||||
|
recorded = 0;
|
||||||
|
|
||||||
// Set FPGA mode to "reader listen mode", no modulation (listen
|
// Set FPGA mode to "reader listen mode", no modulation (listen
|
||||||
// only, since we are receiving, not transmitting).
|
// only, since we are receiving, not transmitting).
|
||||||
|
@ -1586,22 +1600,39 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
// Now get the answer from the card
|
/* Now, get the answer from the card.
|
||||||
|
32-bit registers used on the AT91:
|
||||||
|
SSC_RHR = Receive Holding Register
|
||||||
|
SSC_SR = Status Register (contains RXRDY, which is one bit. 0 is RHR is empty, or 1 if RHR has 32 bits of data in it)
|
||||||
|
*/
|
||||||
|
|
||||||
DemodInit(receivedResponse, receivedResponsePar);
|
DemodInit(receivedResponse, receivedResponsePar);
|
||||||
|
|
||||||
// clear RXRDY:
|
|
||||||
|
// clear RXRDY by reading the contents of RHR.
|
||||||
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
WDT_HIT();
|
WDT_HIT(); //Watchdog Timer
|
||||||
|
|
||||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; //read in 4 bytes of data from the RHR
|
||||||
|
if(manchester_recv_started){
|
||||||
|
end_ts = GetCountSspClk();
|
||||||
|
manchester_recv_started = 0;
|
||||||
|
recorded = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Perform the manchester decoding on the 4 bytes just received.
|
||||||
if(ManchesterDecoding(b, offset, 0)) {
|
if(ManchesterDecoding(b, offset, 0)) {
|
||||||
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
|
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
|
||||||
|
uint32_t cycle_count = end_ts - start_ts;
|
||||||
|
Dbprintf("Finished decoding (Manchester). Value of c=%d. Cycle count (for one bit) = %d", c, cycle_count);
|
||||||
return true;
|
return true;
|
||||||
} else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) {
|
} else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) {
|
||||||
|
//we reach here only if we time out (i.e. receiving the data from the PICC takes too long)
|
||||||
|
Dbprintf("Timed out while waiting for PICC response (c = %d)!", c);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2095,8 +2126,8 @@ void ReaderIso14443a(UsbCommand *c)
|
||||||
start_ts = GetCountSspClk(); //started just after we send all our bytes to the PICC
|
start_ts = GetCountSspClk(); //started just after we send all our bytes to the PICC
|
||||||
arg0 = ReaderReceive(buf, par);
|
arg0 = ReaderReceive(buf, par);
|
||||||
end_ts = GetCountSspClk(); //ended just after we have received all the response bytes from the PICC.
|
end_ts = GetCountSspClk(); //ended just after we have received all the response bytes from the PICC.
|
||||||
uint32_t cycles_taken = end_ts - start_ts;
|
uint32_t cycle_count = end_ts - start_ts;
|
||||||
Dbprintf("Cycles taken to receive response from sending those bytes = %d", cycles_taken);
|
Dbprintf("Cycle count (all bytes) = %d", cycle_count);
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
|
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
|
||||||
|
|
|
@ -255,7 +255,7 @@ function main(args)
|
||||||
|
|
||||||
--writePerso()
|
--writePerso()
|
||||||
--commitPerso()
|
--commitPerso()
|
||||||
--getVersion()
|
getVersion()
|
||||||
proximityCheck()
|
proximityCheck()
|
||||||
|
|
||||||
--commandString = VERIFYPC .. "186EFDE8DDC7D30B"
|
--commandString = VERIFYPC .. "186EFDE8DDC7D30B"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue