//-----------------------------------------------------------------------------
+// Jonathan Westhues, split Nov 2006
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
// Routines to support ISO 14443. This includes both the reader software and
// the `fake tag' modes. At the moment only the Type B modulation is
// supported.
-// Jonathan Westhues, split Nov 2006
//-----------------------------------------------------------------------------
+
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#define DEMOD_TRACE_SIZE 4096
#define READER_TAG_BUFFER_SIZE 2048
#define TAG_READER_BUFFER_SIZE 2048
-#define DMA_BUFFER_SIZE 1024
+#define DEMOD_DMA_BUFFER_SIZE 1024
//=============================================================================
// An ISO 14443 Type B tag. We listen for commands from the reader, using
* false if we are still waiting for some more
*
*/
-static int Handle14443SamplesDemod(int ci, int cq)
+static RAMFUNC int Handle14443SamplesDemod(int ci, int cq)
{
int v;
// Setup for the DMA.
dmaBuf = (int8_t *)(BigBuf + 32);
upTo = dmaBuf;
- lastRxCounter = DMA_BUFFER_SIZE;
- FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+ lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
+ FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
// Signal field is ON with the appropriate LED:
if (weTx) LED_D_ON(); else LED_D_OFF();
int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR;
if(behindBy > max) max = behindBy;
- while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1))
+ while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1))
> 2)
{
ci = upTo[0];
cq = upTo[1];
upTo += 2;
- if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
- upTo -= DMA_BUFFER_SIZE;
+ if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
+ upTo -= DEMOD_DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
- AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
}
lastRxCounter -= 2;
if(lastRxCounter <= 0) {
- lastRxCounter += DMA_BUFFER_SIZE;
+ lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
}
samples += 2;
* 0-4095 : Demodulated samples receive (4096 bytes) - DEMOD_TRACE_SIZE
* 4096-6143 : Last Received command, 2048 bytes (reader->tag) - READER_TAG_BUFFER_SIZE
* 6144-8191 : Last Received command, 2048 bytes(tag->reader) - TAG_READER_BUFFER_SIZE
- * 8192-9215 : DMA Buffer, 1024 bytes (samples) - DMA_BUFFER_SIZE
+ * 8192-9215 : DMA Buffer, 1024 bytes (samples) - DEMOD_DMA_BUFFER_SIZE
*/
-void SnoopIso14443(void)
+void RAMFUNC SnoopIso14443(void)
{
// We won't start recording the frames that we acquire until we trigger;
// a good trigger condition to get started is probably when we see a
// response from the tag.
- int triggered = FALSE;
+ int triggered = TRUE;
// The command (reader -> tag) that we're working on receiving.
uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE;
Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE);
Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
- Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE);
+ Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
- // Use a counter for blinking the LED
- long ledCount=0;
- long ledFlashAt=200000;
// And put the FPGA in the appropriate mode
// Signal field is off with the appropriate LED
// Setup for the DMA.
FpgaSetupSsc();
upTo = dmaBuf;
- lastRxCounter = DMA_BUFFER_SIZE;
- FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+ lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
+ FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
+
+ LED_A_ON();
+
// And now we loop, receiving samples.
for(;;) {
- // Blink the LED while Snooping
- ledCount++;
- if (ledCount == ledFlashAt) {
- LED_D_ON();
- }
- if (ledCount >= 2*ledFlashAt) {
- LED_D_OFF();
- ledCount=0;
- }
-
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
- (DMA_BUFFER_SIZE-1);
+ (DEMOD_DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
- if(behindBy > (DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not?
- Dbprintf("blew circular buffer! behindBy=%x", behindBy);
+ if(behindBy > (DEMOD_DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not?
+ Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
goto done;
}
}
cq = upTo[1];
upTo += 2;
lastRxCounter -= 2;
- if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
- upTo -= DMA_BUFFER_SIZE;
- lastRxCounter += DMA_BUFFER_SIZE;
+ if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) {
+ upTo -= DEMOD_DMA_BUFFER_SIZE;
+ lastRxCounter += DEMOD_DMA_BUFFER_SIZE;
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
- AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE;
}
samples += 2;
#define HANDLE_BIT_IF_BODY \
if(triggered) { \
- ledFlashAt=30000; \
trace[traceLen++] = ((samples >> 0) & 0xff); \
trace[traceLen++] = ((samples >> 8) & 0xff); \
trace[traceLen++] = ((samples >> 16) & 0xff); \
}
triggered = TRUE;
+ LED_A_OFF();
+ LED_B_ON();
// And ready to receive another response.
memset(&Demod, 0, sizeof(Demod));
}
done:
- LED_D_OFF();
- AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+ LED_A_OFF();
+ LED_B_OFF();
+ LED_C_OFF();
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
DbpString("Snoop statistics:");
- Dbprintf(" Max behind by: %i", maxBehindBy);
+ Dbprintf(" Max behind by: %i", maxBehindBy);
Dbprintf(" Uart State: %x", Uart.state);
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);