ADD: @pwpivi latest fixes.

ADD: @marshmellows fixes.
This commit is contained in:
iceman1001 2015-06-21 21:56:44 +02:00
parent c9216a92aa
commit 36f84d4748
3 changed files with 88 additions and 95 deletions

View file

@ -122,8 +122,7 @@ static struct {
STATE_UNSYNCD, STATE_UNSYNCD,
STATE_GOT_FALLING_EDGE_OF_SOF, STATE_GOT_FALLING_EDGE_OF_SOF,
STATE_AWAITING_START_BIT, STATE_AWAITING_START_BIT,
STATE_RECEIVING_DATA, STATE_RECEIVING_DATA
STATE_ERROR_WAIT
} state; } state;
uint16_t shiftReg; uint16_t shiftReg;
int bitCnt; int bitCnt;
@ -145,7 +144,7 @@ static struct {
* Returns: true if we received a EOF * Returns: true if we received a EOF
* false if we are still waiting for some more * false if we are still waiting for some more
*/ */
static int Handle14443bUartBit(int bit) static RAMFUNC int Handle14443bUartBit(uint8_t bit)
{ {
switch(Uart.state) { switch(Uart.state) {
case STATE_UNSYNCD: case STATE_UNSYNCD:
@ -172,7 +171,7 @@ static int Handle14443bUartBit(int bit)
} else { } else {
// didn't stay down long enough // didn't stay down long enough
// before going high, error // before going high, error
Uart.state = STATE_ERROR_WAIT; Uart.state = STATE_UNSYNCD;
} }
} else { } else {
// do nothing, keep waiting // do nothing, keep waiting
@ -183,7 +182,8 @@ static int Handle14443bUartBit(int bit)
if(Uart.bitCnt > 12) { if(Uart.bitCnt > 12) {
// Give up if we see too many zeros without // Give up if we see too many zeros without
// a one, too. // a one, too.
Uart.state = STATE_ERROR_WAIT; LED_A_OFF();
Uart.state = STATE_UNSYNCD;
} }
break; break;
@ -193,7 +193,7 @@ static int Handle14443bUartBit(int bit)
if(Uart.posCnt > 50/2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs if(Uart.posCnt > 50/2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs
// stayed high for too long between // stayed high for too long between
// characters, error // characters, error
Uart.state = STATE_ERROR_WAIT; Uart.state = STATE_UNSYNCD;
} }
} else { } else {
// falling edge, this starts the data byte // falling edge, this starts the data byte
@ -227,8 +227,8 @@ static int Handle14443bUartBit(int bit)
if(Uart.byteCnt >= Uart.byteCntMax) { if(Uart.byteCnt >= Uart.byteCntMax) {
// Buffer overflowed, give up // Buffer overflowed, give up
Uart.posCnt = 0; LED_A_OFF();
Uart.state = STATE_ERROR_WAIT; Uart.state = STATE_UNSYNCD;
} else { } else {
// so get the next byte now // so get the next byte now
Uart.posCnt = 0; Uart.posCnt = 0;
@ -237,31 +237,20 @@ static int Handle14443bUartBit(int bit)
} else if(Uart.shiftReg == 0x000) { } else if(Uart.shiftReg == 0x000) {
// this is an EOF byte // this is an EOF byte
LED_A_OFF(); // Finished receiving LED_A_OFF(); // Finished receiving
Uart.state = STATE_UNSYNCD;
if (Uart.byteCnt != 0) { if (Uart.byteCnt != 0) {
return TRUE; return TRUE;
} }
Uart.posCnt = 0;
Uart.state = STATE_ERROR_WAIT;
} else { } else {
// this is an error // this is an error
Uart.posCnt = 0; LED_A_OFF();
Uart.state = STATE_ERROR_WAIT; Uart.state = STATE_UNSYNCD;
} }
} }
break; break;
case STATE_ERROR_WAIT:
// We're all screwed up, so wait a little while
// for whatever went wrong to finish, and then
// start over.
Uart.posCnt++;
if(Uart.posCnt > 10) {
Uart.state = STATE_UNSYNCD;
LED_A_OFF();
}
break;
default: default:
LED_A_OFF();
Uart.state = STATE_UNSYNCD; Uart.state = STATE_UNSYNCD;
break; break;
} }
@ -269,6 +258,23 @@ static int Handle14443bUartBit(int bit)
return FALSE; return FALSE;
} }
static void UartReset()
{
Uart.byteCntMax = MAX_FRAME_SIZE;
Uart.state = STATE_UNSYNCD;
Uart.byteCnt = 0;
Uart.bitCnt = 0;
}
static void UartInit(uint8_t *data)
{
Uart.output = data;
UartReset();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Receive a command (from the reader to us, where we are the simulated tag), // Receive a command (from the reader to us, where we are the simulated tag),
// and store it in the given buffer, up to the given maximum length. Keeps // and store it in the given buffer, up to the given maximum length. Keeps
@ -278,44 +284,34 @@ static int Handle14443bUartBit(int bit)
// Assume that we're called with the SSC (to the FPGA) and ADC path set // Assume that we're called with the SSC (to the FPGA) and ADC path set
// correctly. // correctly.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int GetIso14443bCommandFromReader(uint8_t *received, int *len, int maxLen) static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len)
{ {
uint8_t mask;
int i, bit;
// Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen // Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen
// only, since we are receiving, not transmitting). // only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED // Signal field is off with the appropriate LED
LED_D_OFF(); LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
// Now run a `software UART' on the stream of incoming samples. // Now run a `software UART' on the stream of incoming samples.
Uart.output = received; UartInit(received);
Uart.byteCntMax = maxLen;
Uart.state = STATE_UNSYNCD;
for(;;) { for(;;) {
WDT_HIT(); WDT_HIT();
if(BUTTON_PRESS()) return FALSE; if(BUTTON_PRESS()) return FALSE;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00;
}
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
for(uint8_t mask = 0x80; mask != 0x00; mask >>= 1) {
mask = 0x80; if(Handle14443bUartBit(b & mask)) {
for(i = 0; i < 8; i++, mask >>= 1) {
bit = (b & mask);
if(Handle14443bUartBit(bit)) {
*len = Uart.byteCnt; *len = Uart.byteCnt;
return TRUE; return TRUE;
} }
} }
} }
} }
return FALSE;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -324,9 +320,12 @@ static int GetIso14443bCommandFromReader(uint8_t *received, int *len, int maxLen
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SimulateIso14443bTag(void) void SimulateIso14443bTag(void)
{ {
// the only command we understand is REQB, AFI=0, Select All, N=0: // the only commands we understand is REQB, AFI=0, Select All, N=0:
static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
// ... and we respond with ATQB, PUPI = 820de174, Application Data = 0x20381922, // ... and REQB, AFI=0, Normal Request, N=0:
static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF };
// ... and we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922,
// supports only 106kBit/s in both directions, max frame size = 32Bytes, // supports only 106kBit/s in both directions, max frame size = 32Bytes,
// supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported: // supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported:
static const uint8_t response1[] = { static const uint8_t response1[] = {
@ -334,25 +333,27 @@ void SimulateIso14443bTag(void)
0x00, 0x21, 0x85, 0x5e, 0xd7 0x00, 0x21, 0x85, 0x5e, 0xd7
}; };
uint8_t *resp; clear_trace();
int respLen; set_tracing(TRUE);
const uint8_t *resp;
uint8_t *respCode;
uint16_t respLen, respCodeLen;
// allocate command receive buffer // allocate command receive buffer
BigBuf_free(); BigBuf_free();
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
int len;
int i; uint16_t len;
uint16_t cmdsRecvd = 0;
int cmdsRecvd = 0;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// prepare the (only one) tag answer: // prepare the (only one) tag answer:
CodeIso14443bAsTag(response1, sizeof(response1)); CodeIso14443bAsTag(response1, sizeof(response1));
uint8_t *resp1 = BigBuf_malloc(ToSendMax); uint8_t *resp1Code = BigBuf_malloc(ToSendMax);
memcpy(resp1, ToSend, ToSendMax); memcpy(resp1Code, ToSend, ToSendMax);
uint16_t resp1Len = ToSendMax; uint16_t resp1CodeLen = ToSendMax;
// We need to listen to the high-frequency, peak-detected path. // We need to listen to the high-frequency, peak-detected path.
SetAdcMuxFor(GPIO_MUXSEL_HIPKD); SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
@ -361,20 +362,28 @@ void SimulateIso14443bTag(void)
cmdsRecvd = 0; cmdsRecvd = 0;
for(;;) { for(;;) {
uint8_t b1, b2;
if(!GetIso14443bCommandFromReader(receivedCmd, &len, 100)) { if(!GetIso14443bCommandFromReader(receivedCmd, &len)) {
Dbprintf("button pressed, received %d commands", cmdsRecvd); Dbprintf("button pressed, received %d commands", cmdsRecvd);
break; break;
} }
// Good, look at the command now. if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(receivedCmd, len, 0, 0, parity, TRUE);
}
if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) { // Good, look at the command now.
resp = resp1; respLen = resp1Len; if ( (len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len) == 0)
|| (len == sizeof(cmd2) && memcmp(receivedCmd, cmd2, len) == 0) ) {
resp = response1;
respLen = sizeof(response1);
respCode = resp1Code;
respCodeLen = resp1CodeLen;
} else { } else {
Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd); Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
// And print whether the CRC fails, just for good measure // And print whether the CRC fails, just for good measure
uint8_t b1, b2;
ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2); ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) { if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
// Not so good, try again. // Not so good, try again.
@ -392,7 +401,7 @@ void SimulateIso14443bTag(void)
break; break;
} }
if(respLen <= 0) continue; if(respCodeLen <= 0) continue;
// Modulate BPSK // Modulate BPSK
// Signal field is off with the appropriate LED // Signal field is off with the appropriate LED
@ -402,15 +411,15 @@ void SimulateIso14443bTag(void)
FpgaSetupSsc(); FpgaSetupSsc();
// Transmit the response. // Transmit the response.
i = 0; uint16_t i = 0;
for(;;) { for(;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
uint8_t b = resp[i]; uint8_t b = respCode[i];
AT91C_BASE_SSC->SSC_THR = b; AT91C_BASE_SSC->SSC_THR = b;
i++; i++;
if(i > respLen) { if(i > respCodeLen) {
break; break;
} }
} }
@ -419,6 +428,13 @@ void SimulateIso14443bTag(void)
(void)b; (void)b;
} }
} }
// trace the response:
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(resp, respLen, 0, 0, parity, FALSE);
}
} }
} }
@ -436,8 +452,7 @@ static struct {
DEMOD_AWAITING_FALLING_EDGE_OF_SOF, DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
DEMOD_GOT_FALLING_EDGE_OF_SOF, DEMOD_GOT_FALLING_EDGE_OF_SOF,
DEMOD_AWAITING_START_BIT, DEMOD_AWAITING_START_BIT,
DEMOD_RECEIVING_DATA, DEMOD_RECEIVING_DATA
DEMOD_ERROR_WAIT
} state; } state;
int bitCount; int bitCount;
int posCount; int posCount;
@ -684,22 +699,6 @@ static void DemodInit(uint8_t *data)
} }
static void UartReset()
{
Uart.byteCntMax = MAX_FRAME_SIZE;
Uart.state = STATE_UNSYNCD;
Uart.byteCnt = 0;
Uart.bitCnt = 0;
}
static void UartInit(uint8_t *data)
{
Uart.output = data;
UartReset();
}
/* /*
* Demodulate the samples we received from the tag, also log to tracebuffer * Demodulate the samples we received from the tag, also log to tracebuffer
* quiet: set to 'TRUE' to disable debug output * quiet: set to 'TRUE' to disable debug output
@ -1165,11 +1164,11 @@ void RAMFUNC SnoopIso14443b(void)
/* false-triggered by the commands from the reader. */ /* false-triggered by the commands from the reader. */
DemodReset(); DemodReset();
} }
ReaderIsActive = (Uart.state != STATE_UNSYNCD); ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
} }
if(!ReaderIsActive) { // no need to try decoding tag data if the reader is sending - and we cannot afford the time if(!ReaderIsActive) { // no need to try decoding tag data if the reader is sending - and we cannot afford the time
if(Handle14443bSamplesDemod(ci, cq)) { if(Handle14443bSamplesDemod(ci | 0x01, cq | 0x01)) {
//Use samples as a time measurement //Use samples as a time measurement
if(tracing) if(tracing)

Binary file not shown.

View file

@ -28,22 +28,12 @@ assign pwr_oe1 = 1'b0;
assign pwr_oe3 = 1'b0; assign pwr_oe3 = 1'b0;
assign pwr_oe4 = 1'b0; assign pwr_oe4 = 1'b0;
(* clock_signal = "yes" *) reg fc_div_2; wire adc_clk = ck_1356megb;
reg fc_div_2;
always @(negedge ck_1356megb) always @(negedge ck_1356megb)
fc_div_2 <= fc_div_2 + 1; fc_div_2 <= fc_div_2 + 1;
(* clock_signal = "yes" *) reg adc_clk;
always @(xcorr_is_848, ck_1356megb, fc_div_2)
if(xcorr_is_848)
// The subcarrier frequency is fc/16; we will sample at fc, so that
// means the subcarrier is 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 ...
adc_clk <= ck_1356megb;
else
// The subcarrier frequency is fc/32; we will sample at fc/2, and
// the subcarrier will look identical.
adc_clk <= fc_div_2;
// When we're a reader, we just need to do the BPSK demod; but when we're an // When we're a reader, we just need to do the BPSK demod; but when we're an
// eavesdropper, we also need to pick out the commands sent by the reader, // eavesdropper, we also need to pick out the commands sent by the reader,
// using AM. Do this the same way that we do it for the simulated tag. // using AM. Do this the same way that we do it for the simulated tag.
@ -85,12 +75,16 @@ reg ssp_clk;
reg ssp_frame; reg ssp_frame;
always @(negedge adc_clk)
begin
if (xcorr_is_848 | fc_div_2)
corr_i_cnt <= corr_i_cnt + 1;
end
// ADC data appears on the rising edge, so sample it on the falling edge // ADC data appears on the rising edge, so sample it on the falling edge
always @(negedge adc_clk) always @(negedge adc_clk)
begin begin
corr_i_cnt <= corr_i_cnt + 1;
// These are the correlators: we correlate against in-phase and quadrature // These are the correlators: we correlate against in-phase and quadrature
// versions of our reference signal, and keep the (signed) result to // versions of our reference signal, and keep the (signed) result to
// send out later over the SSP. // send out later over the SSP.
@ -98,7 +92,7 @@ begin
begin begin
if(snoop) if(snoop)
begin begin
// 7 most significant bits of tag signal (signed), 1 bit reader signal: // Send only 7 most significant bits of tag signal (signed), LSB is reader signal:
corr_i_out <= {corr_i_accum[13:7], after_hysteresis_prev_prev}; corr_i_out <= {corr_i_accum[13:7], after_hysteresis_prev_prev};
corr_q_out <= {corr_q_accum[13:7], after_hysteresis_prev}; corr_q_out <= {corr_q_accum[13:7], after_hysteresis_prev};
after_hysteresis_prev_prev <= after_hysteresis; after_hysteresis_prev_prev <= after_hysteresis;