mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
CHG: FeliCa implemenation by @satsuoni
This commit is contained in:
parent
530c046060
commit
4b63f940f1
20 changed files with 705 additions and 232 deletions
|
@ -21,6 +21,7 @@ APP_CFLAGS = -DWITH_CRC \
|
|||
-DWITH_ISO14443b \
|
||||
-DWITH_ISO14443a \
|
||||
-DWITH_ICLASS \
|
||||
-DWITH_FELICA \
|
||||
-DWITH_HFSNOOP \
|
||||
-DWITH_HF_YOUNG \
|
||||
-fno-strict-aliasing -ffunction-sections -fdata-sections
|
||||
|
@ -45,6 +46,7 @@ SRC_LF = lfops.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c
|
|||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c epa.c
|
||||
SRC_ISO14443b = iso14443b.c
|
||||
SRC_FELICA = felica.c
|
||||
SRC_CRAPTO1 = crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c
|
||||
SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
|
||||
SRC_EMV = tlv.c emvdataels.c emvutil.c emvcmd.c
|
||||
|
@ -93,6 +95,7 @@ ARMSRC = fpgaloader.c \
|
|||
$(SRC_ICLASS) \
|
||||
$(SRC_EMV) \
|
||||
$(SRC_CRC) \
|
||||
$(SRC_FELICA) \
|
||||
parity.c \
|
||||
usb_cdc.c \
|
||||
cmd.c \
|
||||
|
|
|
@ -766,6 +766,18 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
|||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_FELICA
|
||||
case CMD_FELICA_LITE_SIM:
|
||||
HfSimLite(c->arg[0]);
|
||||
break;
|
||||
case CMD_FELICA_SNOOP:
|
||||
HfSnoopISO18(c->arg[0], c->arg[1]);
|
||||
break;
|
||||
case CMD_FELICA_LITE_DUMP:
|
||||
HfDumpFelicaLiteS();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ISO14443a
|
||||
case CMD_SNOOP_ISO_14443a:
|
||||
SniffIso14443a(c->arg[0]);
|
||||
|
|
|
@ -233,6 +233,11 @@ bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* d
|
|||
// util.h
|
||||
void HfSnoop(int , int);
|
||||
|
||||
//felica.c
|
||||
extern void HfSnoopISO18(uint32_t samples, uint32_t triggers);
|
||||
extern void HfSimLite(uint64_t uid);
|
||||
extern void HfDumpFelicaLiteS();
|
||||
|
||||
//EMV functions
|
||||
// emvcmd.h
|
||||
extern void EMVTransaction(void);
|
||||
|
|
|
@ -85,4 +85,14 @@ extern void switch_off();
|
|||
#define FPGA_HF_ISO14443A_READER_LISTEN (3<<0)
|
||||
#define FPGA_HF_ISO14443A_READER_MOD (4<<0)
|
||||
|
||||
|
||||
//options for Felica.
|
||||
#define FPGA_MAJOR_MODE_ISO18092 (5<<5)
|
||||
#define FPGA_HF_ISO18092_FLAG_NOMOD (1<<0) //disable modulation module
|
||||
#define FPGA_HF_ISO18092_FLAG_424K (2<<0) // should enable 414k mode (untested). No autodetect
|
||||
#define FPGA_HF_ISO18092_FLAG_READER (4<<0) // enables antenna power, to act as a reader instead of tag
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
116
client/cmdhf.c
116
client/cmdhf.c
|
@ -745,6 +745,114 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
|||
return tracepos;
|
||||
}
|
||||
|
||||
void printFelica(uint16_t traceLen, uint8_t *trace)
|
||||
{
|
||||
PrintAndLog(" Gap | Src | Data | CRC | Annotation |");
|
||||
PrintAndLog("--------|-----|---------------------------------|----------|-------------------|");
|
||||
uint16_t tracepos=0;
|
||||
//I am stripping SYNC
|
||||
while(tracepos<traceLen)
|
||||
{
|
||||
if(tracepos+3>=traceLen) break;
|
||||
uint16_t gap= (uint16_t)trace[tracepos+1]+((uint16_t)trace[tracepos]>>8);
|
||||
uint16_t crc_ok=trace[tracepos+2];
|
||||
tracepos+=3;
|
||||
if(tracepos+3>=traceLen) break;
|
||||
uint16_t len=trace[tracepos+2];
|
||||
//printf("!!! %02x %02x %02x %02x %02x %02x %d",trace[tracepos+0],trace[tracepos+1],trace[tracepos+2],trace[tracepos+3],trace[tracepos+4],trace[tracepos+5],len);
|
||||
tracepos+=3; //skip SYNC
|
||||
if(tracepos+len+1>=traceLen) break;
|
||||
uint8_t cmd=trace[tracepos];
|
||||
uint8_t isResponse=cmd&1;
|
||||
char line[32][110];
|
||||
for (int j = 0; j < len+1 && j/8 < 32; j++)
|
||||
{
|
||||
snprintf(line[j/8]+(( j % 8) * 4), 110, " %02x ", trace[tracepos+j]);
|
||||
}
|
||||
char expbuf[50];
|
||||
switch(cmd)
|
||||
{
|
||||
case FELICA_POLL_REQ:snprintf(expbuf,49,"Poll Req");break;
|
||||
case FELICA_POLL_ACK :snprintf(expbuf,49,"Poll Resp");break;
|
||||
|
||||
case FELICA_REQSRV_REQ :snprintf(expbuf,49,"Request Srvc Req");break;
|
||||
case FELICA_REQSRV_ACK :snprintf(expbuf,49,"Request Srv Resp");break;
|
||||
|
||||
case FELICA_RDBLK_REQ :snprintf(expbuf,49,"Read block(s) Req");break;
|
||||
case FELICA_RDBLK_ACK :snprintf(expbuf,49,"Read block(s) Resp");break;
|
||||
|
||||
case FELICA_WRTBLK_REQ :snprintf(expbuf,49,"Write block(s) Req");break;
|
||||
case FELICA_WRTBLK_ACK :snprintf(expbuf,49,"Write block(s) Resp");break;
|
||||
case FELICA_SRCHSYSCODE_REQ :snprintf(expbuf,49,"Search syscode Req");break;
|
||||
case FELICA_SRCHSYSCODE_ACK :snprintf(expbuf,49,"Search syscode Resp");break;
|
||||
|
||||
case FELICA_REQSYSCODE_REQ :snprintf(expbuf,49,"Request syscode Req");break;
|
||||
case FELICA_REQSYSCODE_ACK :snprintf(expbuf,49,"Request syscode Resp");break;
|
||||
|
||||
case FELICA_AUTH1_REQ :snprintf(expbuf,49,"Auth1 Req");break;
|
||||
case FELICA_AUTH1_ACK :snprintf(expbuf,49,"Auth1 Resp");break;
|
||||
|
||||
case FELICA_AUTH2_REQ :snprintf(expbuf,49,"Auth2 Req");break;
|
||||
case FELICA_AUTH2_ACK :snprintf(expbuf,49,"Auth2 Resp");break;
|
||||
|
||||
case FELICA_RDSEC_REQ :snprintf(expbuf,49,"Secure read Req");break;
|
||||
case FELICA_RDSEC_ACK :snprintf(expbuf,49,"Secure read Resp");break;
|
||||
|
||||
case FELICA_WRTSEC_REQ :snprintf(expbuf,49,"Secure write Req");break;
|
||||
case FELICA_WRTSEC_ACK :snprintf(expbuf,49,"Secure write Resp");break;
|
||||
|
||||
case FELICA_REQSRV2_REQ :snprintf(expbuf,49,"Request Srvc v2 Req");break;
|
||||
case FELICA_REQSRV2_ACK :snprintf(expbuf,49,"Request Srvc v2 Resp");break;
|
||||
|
||||
case FELICA_GETSTATUS_REQ :snprintf(expbuf,49,"Get status Req");break;
|
||||
case FELICA_GETSTATUS_ACK :snprintf(expbuf,49,"Get status Resp");break;
|
||||
|
||||
case FELICA_OSVER_REQ :snprintf(expbuf,49,"Get OS Version Req");break;
|
||||
case FELICA_OSVER_ACK :snprintf(expbuf,49,"Get OS Version Resp");break;
|
||||
|
||||
case FELICA_RESET_MODE_REQ :snprintf(expbuf,49,"Reset mode Req");break;
|
||||
case FELICA_RESET_MODE_ACK :snprintf(expbuf,49,"Reset mode Resp");break;
|
||||
|
||||
case FELICA_AUTH1V2_REQ :snprintf(expbuf,49,"Auth1 v2 Req");break;
|
||||
case FELICA_AUTH1V2_ACK :snprintf(expbuf,49,"Auth1 v2 Resp");break;
|
||||
|
||||
case FELICA_AUTH2V2_REQ :snprintf(expbuf,49,"Auth2 v2 Req");break;
|
||||
case FELICA_AUTH2V2_ACK :snprintf(expbuf,49,"Auth2 v2 Resp");break;
|
||||
|
||||
case FELICA_RDSECV2_REQ :snprintf(expbuf,49,"Secure read v2 Req");break;
|
||||
case FELICA_RDSECV2_ACK :snprintf(expbuf,49,"Secure read v2 Resp");break;
|
||||
case FELICA_WRTSECV2_REQ :snprintf(expbuf,49,"Secure write v2 Req");break;
|
||||
case FELICA_WRTSECV2_ACK :snprintf(expbuf,49,"Secure write v2 Resp");break;
|
||||
|
||||
case FELICA_UPDATE_RNDID_REQ :snprintf(expbuf,49,"Update IDr Req");break;
|
||||
case FELICA_UPDATE_RNDID_ACK :snprintf(expbuf,49,"Update IDr Resp");break;
|
||||
default: snprintf(expbuf,49,"Unknown");break;
|
||||
}
|
||||
|
||||
int num_lines = MIN((len )/16 + 1, 16);
|
||||
for (int j = 0; j < num_lines ; j++)
|
||||
{
|
||||
if (j == 0) {
|
||||
PrintAndLog("%7d | %s |%-32s |%02x %02x %s| %s",
|
||||
gap,
|
||||
(isResponse ? "Tag" : "Rdr"),
|
||||
line[j],
|
||||
trace[tracepos+len],
|
||||
trace[tracepos+len+1],
|
||||
(crc_ok) ? "OK" : "NG",
|
||||
expbuf);
|
||||
} else {
|
||||
PrintAndLog(" | |%-32s | | ",
|
||||
line[j]);
|
||||
}
|
||||
}
|
||||
tracepos+=len+1;
|
||||
}
|
||||
PrintAndLog("");
|
||||
|
||||
}
|
||||
|
||||
|
||||
int usage_hf_list(){
|
||||
PrintAndLog("List protocol data in trace buffer.");
|
||||
PrintAndLog("Usage: hf list <protocol> [f][c]");
|
||||
|
@ -863,6 +971,12 @@ int CmdHFList(const char *Cmd) {
|
|||
|
||||
PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen);
|
||||
PrintAndLog("");
|
||||
if(protocol==FELICA)
|
||||
{
|
||||
printFelica(traceLen,trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
||||
if ( protocol == ISO_14443A )
|
||||
PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
|
||||
|
@ -882,7 +996,7 @@ int CmdHFList(const char *Cmd) {
|
|||
while(tracepos < traceLen) {
|
||||
tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles, markCRCBytes);
|
||||
}
|
||||
|
||||
}
|
||||
free(trace);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -13,23 +13,44 @@ static int CmdHelp(const char *Cmd);
|
|||
|
||||
int usage_hf_felica_sim(void) {
|
||||
PrintAndLog("\n Emulating ISO/18092 FeliCa tag \n");
|
||||
PrintAndLog("usage: hf felica sim [h] t <type> u <uid> [v]");
|
||||
PrintAndLog("usage: hf felica sim [h] t <type> [v]");
|
||||
PrintAndLog("options: ");
|
||||
PrintAndLog(" h : This help");
|
||||
PrintAndLog(" t : 1 = FeliCa");
|
||||
PrintAndLog(" : 2 = FeliCaS");
|
||||
PrintAndLog(" : 2 = FeliCaLiteS");
|
||||
PrintAndLog(" v : (Optional) Verbose");
|
||||
PrintAndLog("samples:");
|
||||
PrintAndLog(" hf felica sim t 1 u 11223344556677");
|
||||
PrintAndLog(" hf felica sim t 1 ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usage_hf_felica_sniff(void){
|
||||
PrintAndLog("It get data from the field and saves it into command buffer.");
|
||||
PrintAndLog("Buffer accessible from command 'hf list felica'");
|
||||
PrintAndLog("Usage: hf felica sniff [c][r]");
|
||||
PrintAndLog("c - triggered by first data from card");
|
||||
PrintAndLog("r - triggered by first 7-bit request from reader (REQ,WUP,...)");
|
||||
PrintAndLog("sample: hf felica sniff c r");
|
||||
PrintAndLog("Usage: hf felica sniff <s > <t>");
|
||||
PrintAndLog(" s samples to skip (decimal)");
|
||||
PrintAndLog(" t triggers to skip (decimal)");
|
||||
PrintAndLog("samples:");
|
||||
PrintAndLog(" hf felica sniff s 1000");
|
||||
return 0;
|
||||
}
|
||||
int usage_hf_felica_simlite(void) {
|
||||
PrintAndLog("\n Emulating ISO/18092 FeliCa Lite tag \n");
|
||||
PrintAndLog("usage: hf felica litesim [h] u <uid>");
|
||||
PrintAndLog("options: ");
|
||||
PrintAndLog(" h : This help");
|
||||
PrintAndLog(" uid : UID in hexsymbol");
|
||||
PrintAndLog("samples:");
|
||||
PrintAndLog(" hf felica litesim 11223344556677");
|
||||
return 0;
|
||||
}
|
||||
int usage_hf_felica_dumplite(void) {
|
||||
PrintAndLog("\n Dump ISO/18092 FeliCa Lite tag \n");
|
||||
PrintAndLog("usage: hf felica litedump [h]");
|
||||
PrintAndLog("options: ");
|
||||
PrintAndLog(" h : This help");
|
||||
PrintAndLog("samples:");
|
||||
PrintAndLog(" hf felica litedump");
|
||||
return 0;
|
||||
}
|
||||
int usage_hf_felica_raw(void){
|
||||
|
@ -66,13 +87,6 @@ int CmdHFFelicaReader(const char *Cmd) {
|
|||
|
||||
iso14a_card_select_t card;
|
||||
memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
|
||||
|
||||
/*
|
||||
0: couldn't read
|
||||
1: OK, with ATS
|
||||
2: OK, no ATS
|
||||
3: proprietary Anticollision
|
||||
*/
|
||||
uint64_t select_status = resp.arg[0];
|
||||
|
||||
if (select_status == 0) {
|
||||
|
@ -81,10 +95,6 @@ int CmdHFFelicaReader(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
|
||||
|
||||
return select_status;
|
||||
}
|
||||
|
||||
|
@ -98,8 +108,8 @@ int CmdHFFelicaSim(const char *Cmd) {
|
|||
int uidlen = 0;
|
||||
bool verbose = false;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (param_getchar(Cmd, cmdp)) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_hf_felica_sim();
|
||||
|
@ -155,22 +165,211 @@ int CmdHFFelicaSim(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFFelicaSniff(const char *Cmd) {
|
||||
int param = 0;
|
||||
uint8_t ctmp;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ctmp = param_getchar(Cmd, i);
|
||||
if (ctmp == 'h' || ctmp == 'H') return usage_hf_felica_sniff();
|
||||
if (ctmp == 'c' || ctmp == 'C') param |= 0x01;
|
||||
if (ctmp == 'r' || ctmp == 'R') param |= 0x02;
|
||||
}
|
||||
int CmdHFFelicaSniff(const char *Cmd) {
|
||||
|
||||
UsbCommand c = {CMD_FELICA_SNOOP, {param, 0, 0}};
|
||||
uint8_t cmdp = 0;
|
||||
uint64_t samples2skip = 0;
|
||||
uint64_t triggers2skip = 0;
|
||||
bool errors = false;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_hf_felica_sniff();
|
||||
case 's':
|
||||
case 'S':
|
||||
samples2skip = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 't':
|
||||
case 'T':
|
||||
triggers2skip = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Validations
|
||||
if (errors || cmdp == 0) return usage_hf_felica_sniff();
|
||||
|
||||
UsbCommand c = {CMD_FELICA_SNOOP, {samples2skip, triggers2skip, 0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// uid hex
|
||||
int CmdHFFelicaSimLite(const char *Cmd) {
|
||||
|
||||
uint64_t uid = param_get64ex(Cmd, 0, 0, 16);
|
||||
|
||||
if (!uid)
|
||||
return usage_hf_felica_simlite();
|
||||
|
||||
UsbCommand c = {CMD_FELICA_LITE_SIM, {uid, 0, 0} };
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace,uint16_t tracelen) {
|
||||
if (tracepos+19 >= tracelen)
|
||||
return tracelen;
|
||||
|
||||
trace += tracepos;
|
||||
uint8_t blocknum = trace[0];
|
||||
uint8_t status1 = trace[1];
|
||||
uint8_t status2 = trace[2];
|
||||
|
||||
char line[110] = {0};
|
||||
for (int j = 0; j < 16; j++) {
|
||||
snprintf(line+( j * 4),110, "%02x ", trace[j+3]);
|
||||
}
|
||||
|
||||
PrintAndLog( "Block number %02x, status: %02x %02x",blocknum,status1, status2);
|
||||
switch (blocknum) {
|
||||
case 0x00: PrintAndLog( "S_PAD0: %s",line);break;
|
||||
case 0x01: PrintAndLog( "S_PAD1: %s",line);break;
|
||||
case 0x02: PrintAndLog( "S_PAD2: %s",line);break;
|
||||
case 0x03: PrintAndLog( "S_PAD3: %s",line);break;
|
||||
case 0x04: PrintAndLog( "S_PAD4: %s",line);break;
|
||||
case 0x05: PrintAndLog( "S_PAD5: %s",line);break;
|
||||
case 0x06: PrintAndLog( "S_PAD6: %s",line);break;
|
||||
case 0x07: PrintAndLog( "S_PAD7: %s",line);break;
|
||||
case 0x08: PrintAndLog( "S_PAD8: %s",line);break;
|
||||
case 0x09: PrintAndLog( "S_PAD9: %s",line);break;
|
||||
case 0x0a: PrintAndLog( "S_PAD10: %s",line);break;
|
||||
case 0x0b: PrintAndLog( "S_PAD11: %s",line);break;
|
||||
case 0x0c: PrintAndLog( "S_PAD12: %s",line);break;
|
||||
case 0x0d: PrintAndLog( "S_PAD13: %s",line);break;
|
||||
case 0x0E: {
|
||||
uint32_t regA = trace[3] + (trace[4]>>8) + (trace[5]>>16) + (trace[6]>>24);
|
||||
uint32_t regB = trace[7] + (trace[8]>>8) + (trace[9]>>16) + (trace[10]>>24);
|
||||
line[0] = 0;
|
||||
for (int j = 0; j < 8; j++)
|
||||
snprintf(line+( j * 2),110, "%02x", trace[j+11]);
|
||||
PrintAndLog( "REG: regA: %d regB: %d regC: %s ", regA, regB, line);
|
||||
}
|
||||
break;
|
||||
case 0x80: PrintAndLog( "Random Challenge, WO: %s ", line); break;
|
||||
case 0x81: PrintAndLog( "MAC, only set on dual read: %s ", line); break;
|
||||
case 0x82: {
|
||||
char idd[20];
|
||||
char idm[20];
|
||||
for (int j = 0; j < 8; j++)
|
||||
snprintf(idd+( j * 2),20, "%02x", trace[j+3]);
|
||||
|
||||
for (int j = 0; j < 6; j++)
|
||||
snprintf(idm+( j * 2),20, "%02x", trace[j+13]);
|
||||
|
||||
PrintAndLog( "ID Block, IDd: 0x%s DFC: 0x%02x%02x Arb: %s ", idd, trace[11], trace [12], idm);
|
||||
}
|
||||
break;
|
||||
case 0x83: {
|
||||
char idm[20];
|
||||
char pmm[20];
|
||||
for (int j = 0; j < 8; j++)
|
||||
snprintf(idm+( j * 2),20, "%02x", trace[j+3]);
|
||||
|
||||
for (int j = 0; j < 8; j++)
|
||||
snprintf(pmm+( j * 2),20, "%02x", trace[j+11]);
|
||||
|
||||
PrintAndLog( "DeviceId: IDm: 0x%s PMm: 0x%s ", idm, pmm);
|
||||
}
|
||||
break;
|
||||
case 0x84: PrintAndLog( "SER_C: 0x%02x%02x ", trace[3], trace[4]); break;
|
||||
case 0x85: PrintAndLog( "SYS_Cl 0x%02x%02x ", trace[3], trace[4]); break;
|
||||
case 0x86: PrintAndLog( "CKV (key version): 0x%02x%02x ", trace[3], trace[4]); break;
|
||||
case 0x87: PrintAndLog( "CK (card key), WO: %s ", line); break;
|
||||
case 0x88: {
|
||||
PrintAndLog( "Memory Configuration (MC):");
|
||||
PrintAndLog( "MAC needed to write state: %s", trace[3+12]? "on" : "off");
|
||||
//order might be off here...
|
||||
PrintAndLog("Write with MAC for S_PAD : %s ", sprint_bin(trace+3+10, 2) );
|
||||
PrintAndLog("Write with AUTH for S_PAD : %s ", sprint_bin(trace+3+8, 2) );
|
||||
PrintAndLog("Read after AUTH for S_PAD : %s ", sprint_bin(trace+3+6, 2) );
|
||||
PrintAndLog( "MAC needed to write CK and CKV: %s", trace[3+5] ? "on" : "off");
|
||||
PrintAndLog( "RF parameter: %02x", (trace[3+4] & 0x7) );
|
||||
PrintAndLog( "Compatible with NDEF: %s", trace[3+3] ? "yes" : "no");
|
||||
PrintAndLog( "Memory config writable : %s", (trace[3+2] == 0xff) ? "yes" : "no");
|
||||
PrintAndLog("RW access for S_PAD : %s ", sprint_bin(trace+3, 2) );
|
||||
}
|
||||
break;
|
||||
case 0x90: {
|
||||
PrintAndLog( "Write count, RO: %02x %02x %02x ", trace[3], trace[4], trace[5]);
|
||||
}
|
||||
break;
|
||||
case 0x91: {
|
||||
PrintAndLog( "MAC_A, RW (auth): %s ", line);
|
||||
}
|
||||
break;
|
||||
case 0x92: {
|
||||
PrintAndLog( "State:");
|
||||
PrintAndLog( "Polling disabled: %s", trace[3+8] ? "yes" : "no");
|
||||
PrintAndLog( "Authenticated: %s", trace[3] ? "yes" : "no");
|
||||
}
|
||||
break;
|
||||
case 0xa0: {
|
||||
PrintAndLog( "CRC of all bloacks match : %s", (trace[3+2]==0xff) ? "no" : "yes");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PrintAndLog( "INVALID %d: %s", blocknum, line);
|
||||
break;
|
||||
}
|
||||
return tracepos+19;
|
||||
}
|
||||
|
||||
int CmdHFFelicaDumpLite(const char *Cmd) {
|
||||
|
||||
//usage_hf_felica_dumplite();
|
||||
|
||||
UsbCommand c = {CMD_FELICA_LITE_DUMP, {0,0,0}};
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
|
||||
uint16_t tracepos = 0;
|
||||
uint8_t *trace;
|
||||
|
||||
trace = malloc(USB_CMD_DATA_SIZE);
|
||||
if ( trace == NULL ) {
|
||||
PrintAndLog("Cannot allocate memory for trace");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Query for the size of the trace
|
||||
UsbCommand response;
|
||||
GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0);
|
||||
if ( !WaitForResponseTimeout(CMD_ACK, &response, 4000) ) {
|
||||
PrintAndLog("timeout while waiting for reply.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t traceLen = response.arg[2];
|
||||
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||
uint8_t *p = realloc(trace, traceLen);
|
||||
if (p == NULL) {
|
||||
PrintAndLog("Cannot allocate memory for trace");
|
||||
free(trace);
|
||||
return 2;
|
||||
}
|
||||
trace = p;
|
||||
GetFromBigBuf(trace, traceLen, 0);
|
||||
WaitForResponse(CMD_ACK, NULL);
|
||||
}
|
||||
|
||||
PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen);
|
||||
while (tracepos < traceLen) {
|
||||
tracepos = PrintFliteBlock(tracepos, trace, traceLen);
|
||||
}
|
||||
free(trace);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFFelicaCmdRaw(const char *cmd) {
|
||||
UsbCommand c = {CMD_FELICA_COMMAND, {0, 0, 0}};
|
||||
bool reply = 1;
|
||||
|
@ -323,12 +522,15 @@ void waitCmdFelica(uint8_t iSelect) {
|
|||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"list", CmdHFFelicaList, 0, "[Deprecated] List ISO 18092/FeliCa history"},
|
||||
{"reader", CmdHFFelicaReader, 0, "Act like an ISO18092/FeliCa reader"},
|
||||
{"sim", CmdHFFelicaSim, 0, "<UID> -- Simulate ISO 18092/FeliCa tag"},
|
||||
{"sniff", CmdHFFelicaSniff, 0, "sniff ISO 18092/Felica traffic"},
|
||||
{"raw", CmdHFFelicaCmdRaw, 0, "Send raw hex data to tag"},
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"list", CmdHFFelicaList, 0, "[Deprecated] List ISO 18092/FeliCa history"},
|
||||
{"reader", CmdHFFelicaReader, 0, "Act like an ISO18092/FeliCa reader"},
|
||||
{"sim", CmdHFFelicaSim, 0, "<UID> -- Simulate ISO 18092/FeliCa tag"},
|
||||
{"sniff", CmdHFFelicaSniff, 0, "sniff ISO 18092/Felica traffic"},
|
||||
{"raw", CmdHFFelicaCmdRaw, 0, "Send raw hex data to tag"},
|
||||
|
||||
{"litesim", CmdHFFelicaSimLite, 0, "<NDEF2> - only reply to poll request"},
|
||||
{"litedump", CmdHFFelicaDumpLite, 0, "Wait for and try dumping FelicaLite"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -38,4 +38,9 @@ extern int usage_hf_felica_sniff(void);
|
|||
extern int usage_hf_fFelica_raw(void);
|
||||
|
||||
void waitCmdFelica(uint8_t iSelect);
|
||||
|
||||
//temp
|
||||
extern int CmdHFFelicaSimLite(const char *Cmd);
|
||||
extern int CmdHFFelicaDumpLite(const char *Cmd);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -436,6 +436,67 @@ uint32_t GetT55xxClockBit(uint32_t clock);
|
|||
#define EM4x05_DISABLE_ALLOWED 1<<23
|
||||
#define EM4x05_READER_TALK_FIRST 1<<24
|
||||
|
||||
|
||||
|
||||
#define FLITE_SERVICE_RO 0x000B
|
||||
#define FLITE_SERVICE_RW 0x0009
|
||||
|
||||
#define FELICA_POLL_REQ 0x00
|
||||
#define FELICA_POLL_ACK 0x01
|
||||
|
||||
#define FELICA_REQSRV_REQ 0x02
|
||||
#define FELICA_REQSRV_ACK 0x03
|
||||
|
||||
#define FELICA_RDBLK_REQ 0x06
|
||||
#define FELICA_RDBLK_ACK 0x07
|
||||
|
||||
#define FELICA_WRTBLK_REQ 0x08
|
||||
#define FELICA_WRTBLK_ACK 0x09
|
||||
|
||||
#define FELICA_SRCHSYSCODE_REQ 0x0a
|
||||
#define FELICA_SRCHSYSCODE_ACK 0x0b
|
||||
|
||||
#define FELICA_REQSYSCODE_REQ 0x0c
|
||||
#define FELICA_REQSYSCODE_ACK 0x0d
|
||||
|
||||
#define FELICA_AUTH1_REQ 0x10
|
||||
#define FELICA_AUTH1_ACK 0x11
|
||||
|
||||
#define FELICA_AUTH2_REQ 0x12
|
||||
#define FELICA_AUTH2_ACK 0x13
|
||||
|
||||
#define FELICA_RDSEC_REQ 0x14
|
||||
#define FELICA_RDSEC_ACK 0x15
|
||||
|
||||
#define FELICA_WRTSEC_REQ 0x16
|
||||
#define FELICA_WRTSEC_ACK 0x17
|
||||
|
||||
#define FELICA_REQSRV2_REQ 0x32
|
||||
#define FELICA_REQSRV2_ACK 0x33
|
||||
|
||||
#define FELICA_GETSTATUS_REQ 0x38
|
||||
#define FELICA_GETSTATUS_ACK 0x39
|
||||
|
||||
#define FELICA_OSVER_REQ 0x3c
|
||||
#define FELICA_OSVER_ACK 0x3d
|
||||
|
||||
#define FELICA_RESET_MODE_REQ 0x3e
|
||||
#define FELICA_RESET_MODE_ACK 0x3f
|
||||
|
||||
#define FELICA_AUTH1V2_REQ 0x40
|
||||
#define FELICA_AUTH1V2_ACK 0x41
|
||||
|
||||
#define FELICA_AUTH2V2_REQ 0x42
|
||||
#define FELICA_AUTH2V2_ACK 0x43
|
||||
|
||||
#define FELICA_RDSECV2_REQ 0x44
|
||||
#define FELICA_RDSECV2_ACK 0x45
|
||||
#define FELICA_WRTSECV2_REQ 0x46
|
||||
#define FELICA_WRTSECV2_ACK 0x47
|
||||
|
||||
#define FELICA_UPDATE_RNDID_REQ 0x4C
|
||||
#define FELICA_UPDATE_RNDID_ACK 0x4D
|
||||
|
||||
// iclass / picopass chip config structures and shared routines
|
||||
typedef struct {
|
||||
uint8_t app_limit; //[8]
|
||||
|
|
BIN
fpga/fpga_hf.bit
BIN
fpga/fpga_hf.bit
Binary file not shown.
|
@ -18,6 +18,8 @@
|
|||
`include "hi_simulate.v"
|
||||
`include "hi_iso14443a.v"
|
||||
`include "hi_sniffer.v"
|
||||
`include "hi_flite.v"
|
||||
//`include "hf_fmod.v"
|
||||
`include "util.v"
|
||||
|
||||
module fpga_hf(
|
||||
|
@ -73,7 +75,10 @@ wire hi_read_tx_shallow_modulation = conf_word[0];
|
|||
wire hi_read_rx_xcorr_848 = conf_word[0];
|
||||
// and whether to drive the coil (reader) or just short it (snooper)
|
||||
wire hi_read_rx_xcorr_snoop = conf_word[1];
|
||||
// divide subcarrier frequency by 4
|
||||
wire hi_read_rx_xcorr_quarter = conf_word[2];
|
||||
|
||||
wire [1:0] hi_read_tx_speed= conf_word [2:1];
|
||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||
wire [2:0] hi_simulate_mod_type = conf_word[2:0];
|
||||
|
||||
|
@ -90,8 +95,19 @@ hi_read_tx ht(
|
|||
ht_ssp_frame, ht_ssp_din, ssp_dout, ht_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
ht_dbg,
|
||||
hi_read_tx_shallow_modulation
|
||||
hi_read_tx_shallow_modulation,hi_read_tx_speed, 1'b1
|
||||
);
|
||||
|
||||
/*hi_fmod hmf(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hmf_pwr_lo, hmf_pwr_hi, hmf_pwr_oe1, hmf_pwr_oe2, hmf_pwr_oe3, hmf_pwr_oe4,
|
||||
adc_d, ht_adc_clk,
|
||||
hmf_ssp_frame, hmf_ssp_din, ssp_dout, hmf_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hmf_dbg,
|
||||
hi_simulate_mod_type
|
||||
);*/
|
||||
|
||||
|
||||
hi_read_rx_xcorr hrxc(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
|
@ -100,7 +116,7 @@ hi_read_rx_xcorr hrxc(
|
|||
hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hrxc_dbg,
|
||||
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop
|
||||
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
|
||||
);
|
||||
|
||||
hi_simulate hs(
|
||||
|
@ -133,6 +149,16 @@ hi_sniffer he(
|
|||
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
|
||||
);
|
||||
|
||||
hi_flite hfl(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
hfl_pwr_lo, hfl_pwr_hi, hfl_pwr_oe1, hfl_pwr_oe2, hfl_pwr_oe3, hfl_pwr_oe4,
|
||||
adc_d, hfl_adc_clk,
|
||||
hfl_ssp_frame, hfl_ssp_din, ssp_dout, hfl_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
hfl_dbg,
|
||||
hi_simulate_mod_type
|
||||
);
|
||||
|
||||
// Major modes:
|
||||
|
||||
// 000 -- HF reader, transmitting to tag; modulation depth selectable
|
||||
|
@ -140,19 +166,34 @@ hi_sniffer he(
|
|||
// 010 -- HF simulated tag
|
||||
// 011 -- HF ISO14443-A
|
||||
// 100 -- HF Snoop
|
||||
// 101 -- HF demod test
|
||||
// 110 -- Felica modulation, reusing HF reader
|
||||
// 111 -- everything off
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, 1'b0, 1'b0, 1'b0);
|
||||
//mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, hmf_ssp_clk, 1'b0);
|
||||
//mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, hmf_ssp_din, 1'b0);
|
||||
//mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, hmf_ssp_frame, 1'b0);
|
||||
//mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, hmf_pwr_oe1, 1'b0);
|
||||
//mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, hmf_pwr_oe2, 1'b0);
|
||||
//mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, hmf_pwr_oe3, 1'b0);
|
||||
//mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, hmf_pwr_oe4, 1'b0);
|
||||
//mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, hmf_pwr_lo, 1'b0);
|
||||
//mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, hmf_pwr_hi, 1'b0);
|
||||
//mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, hmf_adc_clk, 1'b0);
|
||||
//mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, hmf_dbg, 1'b0);
|
||||
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, hfl_dbg, 1'b0, 1'b0);
|
||||
|
||||
// In all modes, let the ADC's outputs be enabled.
|
||||
assign adc_noe = 1'b0;
|
||||
|
|
BIN
fpga/fpga_lf.bit
BIN
fpga/fpga_lf.bit
Binary file not shown.
|
@ -103,7 +103,7 @@ lo_edge_detect le(
|
|||
// Major modes:
|
||||
// 000 -- LF reader (generic)
|
||||
// 001 -- LF edge detect (generic)
|
||||
// 010 -- LF passthru
|
||||
// 010 -- LF passthrough
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, lr_ssp_clk, le_ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, lr_ssp_din, 1'b0, lp_ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0);
|
||||
|
|
Binary file not shown.
|
@ -16,6 +16,7 @@
|
|||
|
||||
`include "hi_flite.v"
|
||||
`include "util.v"
|
||||
`include "hi_sniffer.v"
|
||||
|
||||
module fpga_nfc(
|
||||
input spck, output miso, input mosi, input ncs,
|
||||
|
@ -67,11 +68,11 @@ assign major_mode = conf_word[7:5];
|
|||
|
||||
// For the high-frequency receive correlator: frequency against which to
|
||||
// correlate.
|
||||
//wire hi_read_rx_xcorr_848 = conf_word[0];
|
||||
wire hi_read_rx_xcorr_848 = conf_word[0];
|
||||
// and whether to drive the coil (reader) or just short it (snooper)
|
||||
//wire hi_read_rx_xcorr_snoop = conf_word[1];
|
||||
wire hi_read_rx_xcorr_snoop = conf_word[1];
|
||||
// divide subcarrier frequency by 4
|
||||
//wire hi_read_rx_xcorr_quarter = conf_word[2];
|
||||
wire hi_read_rx_xcorr_quarter = conf_word[2];
|
||||
|
||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||
wire [2:0] hi_simulate_mod_type = conf_word[2:0];
|
||||
|
@ -81,6 +82,15 @@ wire [2:0] hi_simulate_mod_type = conf_word[2:0];
|
|||
// major modes, and use muxes to connect the outputs of the active mode to
|
||||
// the output pins.
|
||||
//-----------------------------------------------------------------------------
|
||||
hi_sniffer he(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
he_pwr_lo, he_pwr_hi, he_pwr_oe1, he_pwr_oe2, he_pwr_oe3, he_pwr_oe4,
|
||||
adc_d, he_adc_clk,
|
||||
he_ssp_frame, he_ssp_din, ssp_dout, he_ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
he_dbg,
|
||||
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
|
||||
);
|
||||
|
||||
|
||||
hi_flite hfl(
|
||||
|
@ -103,17 +113,17 @@ hi_flite hfl(
|
|||
// 101 -- HF NFC demod, just to copy it for now
|
||||
// 111 -- everything off
|
||||
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_ssp_clk, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_ssp_din, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_ssp_frame, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe1, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe2, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe3, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_oe4, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_lo, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_pwr_hi, 1'b0, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_adc_clk, 1'b0, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, hfl_dbg, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_clk (major_mode, ssp_clk, 1'b0, 1'b0, 1'b0, 1'b0, he_ssp_clk, hfl_ssp_clk, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_din (major_mode, ssp_din, 1'b0, 1'b0, 1'b0, 1'b0, he_ssp_din, hfl_ssp_din, 1'b0, 1'b0);
|
||||
mux8 mux_ssp_frame (major_mode, ssp_frame, 1'b0, 1'b0, 1'b0, 1'b0, he_ssp_frame, hfl_ssp_frame, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe1 (major_mode, pwr_oe1, 1'b0, 1'b0, 1'b0, 1'b0, he_pwr_oe1, hfl_pwr_oe1, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe2 (major_mode, pwr_oe2, 1'b0, 1'b0, 1'b0, 1'b0, he_pwr_oe2, hfl_pwr_oe2, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe3 (major_mode, pwr_oe3, 1'b0, 1'b0, 1'b0, 1'b0, he_pwr_oe3, hfl_pwr_oe3, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_oe4 (major_mode, pwr_oe4, 1'b0, 1'b0, 1'b0, 1'b0, he_pwr_oe4, hfl_pwr_oe4, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_lo (major_mode, pwr_lo, 1'b0, 1'b0, 1'b0, 1'b0, he_pwr_lo, hfl_pwr_lo, 1'b0, 1'b0);
|
||||
mux8 mux_pwr_hi (major_mode, pwr_hi, 1'b0, 1'b0, 1'b0, 1'b0, he_pwr_hi, hfl_pwr_hi, 1'b0, 1'b0);
|
||||
mux8 mux_adc_clk (major_mode, adc_clk, 1'b0, 1'b0, 1'b0, 1'b0, he_adc_clk, hfl_adc_clk, 1'b0, 1'b0);
|
||||
mux8 mux_dbg (major_mode, dbg, 1'b0, 1'b0, 1'b0, 1'b0, hfl_dbg, hfl_dbg, 1'b0, 1'b0);
|
||||
|
||||
// In all modes, let the ADC's outputs be enabled.
|
||||
assign adc_noe = 1'b0;
|
||||
|
|
269
fpga/hi_flite.v
269
fpga/hi_flite.v
|
@ -1,15 +1,11 @@
|
|||
// Satsuoni, October 2017, Added FeliCa support
|
||||
//
|
||||
|
||||
//this code demodulates and modulates signal as described in ISO/IEC 18092. That includes packets used for Felica, NFC Tag 3, etc. (which do overlap)
|
||||
//simple envelope following algorithm is used (modification of fail0verflow LF one) is used to combat some nasty aliasing effect with testing phone (envelope looked like sine wave)
|
||||
// only 212 kbps (fc/64) for now 414 is relatively straightforward...
|
||||
// only 212 kbps (fc/64) for now 414 is relatively straightforward... though for reader, the selection has to come from ARM
|
||||
// modulation waits for
|
||||
|
||||
//market sprocket -doesn't really mean anything ;)
|
||||
`define SNIFFER 3'b000
|
||||
`define TAGSIM_LISTEN 3'b001 //same as SNIFFER, really. demod does not distinguish tag from reader
|
||||
`define TAGSIM_MODULATE 3'b010
|
||||
`define TAGSIM_MOD_NODELAY 3'b011 //not implemented yet. for use with commands other than polling, which might require different timing, as per Felica standard
|
||||
//redefining mod_type: bits 210: bit 2 - reader drive/power on/off, bit 1 - speed bit, 0:212, 1 -424 bit 0: listen or modulate
|
||||
|
||||
|
||||
module hi_flite(
|
||||
pck0, ck_1356meg, ck_1356megb,
|
||||
|
@ -18,7 +14,8 @@ module hi_flite(
|
|||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg,
|
||||
mod_type // maybe used
|
||||
mod_type // used
|
||||
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
|
@ -28,15 +25,18 @@ module hi_flite(
|
|||
output ssp_frame, ssp_din, ssp_clk;
|
||||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input [2:0] mod_type; // maybe used.
|
||||
input [2:0] mod_type; // used.
|
||||
assign dbg=0;
|
||||
|
||||
// Most off, oe4 for modulation; No reader emulation (would presumably just require switching power on, but I am not sure)
|
||||
assign pwr_hi = 1'b0;
|
||||
wire power= mod_type[2];
|
||||
wire speed= mod_type[1];
|
||||
wire disabl= mod_type[0];
|
||||
|
||||
// Most off, oe4 for modulation;
|
||||
// Trying reader emulation (would presumably just require switching power on, but I am not sure)
|
||||
//;// 1'b0;
|
||||
assign pwr_lo = 1'b0;
|
||||
assign pwr_oe1 = 1'b0;
|
||||
assign pwr_oe2 = 1'b0;
|
||||
assign pwr_oe3 = 1'b0;
|
||||
|
||||
|
||||
|
||||
//512x64/fc -wait before ts0, 32768 ticks
|
||||
|
@ -51,7 +51,7 @@ assign adc_clk = ck_1356meg;
|
|||
`define ithrmin 91//-13'd8
|
||||
`define ithrmax 160// 13'd8
|
||||
|
||||
|
||||
`define min_bitdelay_212 8
|
||||
//minimum values and corresponding thresholds
|
||||
reg [8:0] curmin=`imin;
|
||||
|
||||
|
@ -76,9 +76,13 @@ reg did_sync=0;
|
|||
|
||||
|
||||
`define bithalf_212 32 //half-bit length for 212 kbit
|
||||
`define bitlen_212 64 //full-bit length for 212 kbit
|
||||
`define bitmlen_212 63 //bit transition edge
|
||||
`define bitmhalf_212 31 //mod flip
|
||||
|
||||
`define bithalf_424 16 //half-bit length for 212 kbit
|
||||
`define bitmlen_424 31 //bit transition edge
|
||||
|
||||
wire [7:0]bithalf= speed ? `bithalf_424 : `bithalf_212;
|
||||
wire [7:0]bitmlen= speed ? `bitmlen_424 : `bitmlen_212;
|
||||
|
||||
|
||||
//ssp clock and current values
|
||||
|
@ -98,57 +102,36 @@ reg [8:0] ssp_cnt=9'd0;
|
|||
always @(posedge adc_clk)
|
||||
ssp_cnt <= (ssp_cnt + 1);
|
||||
|
||||
|
||||
reg getting_arm_data=1'b0;
|
||||
|
||||
|
||||
reg [47:0] delayline=48'd0; //48-bit preamble delay line. Just push the data into it starting from first SYNC (1) bit coming from ARM Made this long to keep all ARM data received during preamble
|
||||
reg [5:0] delay_read_ptr=6'd0; // this is supposed to count ARM delay in the buffer.
|
||||
reg preamble=0; // whether we are sending preamble
|
||||
|
||||
|
||||
//maybe change it so that ARM sends preamble as well.
|
||||
//then: ready bits sent to ARM, 8 bits sent from ARM (all ones), then preamble (all zeros, presumably) - which starts modulation
|
||||
|
||||
always @(negedge adc_clk)
|
||||
begin
|
||||
//count fc/64 - transfer bits to ARM at the rate they are received
|
||||
if(ssp_cnt[5:0] == 6'b000000)
|
||||
if( ((~speed) && (ssp_cnt[5:0] == 6'b000000)) || (speed &&(ssp_cnt[4:0] == 5'b00000)))
|
||||
begin
|
||||
ssp_clk <= 1'b1;
|
||||
// if(mod_type[2])
|
||||
// begin
|
||||
// ssp_din<=outp[0];//after_hysteresis;
|
||||
|
||||
//outp<={1'b0,outp[7:1]};
|
||||
// end
|
||||
// else
|
||||
ssp_din <= curbit;
|
||||
|
||||
//sample ssp_dout?
|
||||
if(mod_type==`TAGSIM_MODULATE||mod_type==`TAGSIM_MOD_NODELAY)
|
||||
begin
|
||||
delayline<={delayline[46:0],ssp_dout};
|
||||
if ((~getting_arm_data) && ssp_dout)
|
||||
begin
|
||||
getting_arm_data <=1'b1;
|
||||
delay_read_ptr<=delay_read_ptr+1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (getting_arm_data & preamble)
|
||||
begin
|
||||
delay_read_ptr<=delay_read_ptr+1;
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
getting_arm_data <=1'b0;
|
||||
delay_read_ptr<=6'd0;
|
||||
end
|
||||
//sample ssp_dout
|
||||
|
||||
end
|
||||
if(ssp_cnt[5:0] == 6'b100000)
|
||||
if( ( (~speed) && (ssp_cnt[5:0] == 6'b100000)) ||(speed && ssp_cnt[4:0] == 5'b10000))
|
||||
ssp_clk <= 1'b0;
|
||||
//create frame pulses. TBH, I still don't know what they do exactly, but they are crucial for ARM->FPGA transfer. If the frame is in the beginning of the byte, transfer slows to a crawl for some reason
|
||||
// took me a day to figure THAT out.
|
||||
if(ssp_cnt[8:0] == 9'd31)
|
||||
if(( (~speed) && (ssp_cnt[8:0] == 9'd31))||(speed && ssp_cnt[7:0] == 8'd15))
|
||||
begin
|
||||
ssp_frame <= 1'b1;
|
||||
end
|
||||
if(ssp_cnt[8:0] == 9'b1011111)
|
||||
if(( (~speed) && (ssp_cnt[8:0] == 9'b1011111))||(speed &&ssp_cnt[7:0] == 8'b101111) )
|
||||
begin
|
||||
ssp_frame <= 1'b0;
|
||||
end
|
||||
|
@ -158,7 +141,7 @@ end
|
|||
|
||||
|
||||
//send current bit (detected in SNIFF mode or the one being modulated in MOD mode, 0 otherwise)
|
||||
reg ssp_din;
|
||||
reg ssp_din;//= outp[0];
|
||||
|
||||
|
||||
|
||||
|
@ -168,28 +151,74 @@ reg prv =1'b1;
|
|||
|
||||
reg[7:0] mid=8'd128; //for simple error correction in mod/demod detection, use maximum of modded/demodded in given interval. Maybe 1 bit is extra? but better safe than sorry.
|
||||
|
||||
//modulated coil. set to 1 to modulate low, 0 to keep signal high
|
||||
reg mod_sig_coil=1'b0;
|
||||
|
||||
// set TAGSIM__MODULATE on ARM if we want to write... (frame would get lost if done mid-frame...)
|
||||
// start sending over 1s on ssp->arm when we start sending preamble
|
||||
|
||||
reg counting_desync=1'b0; // are we counting bits since last frame?
|
||||
reg sending=1'b0; // are we actively modulating?
|
||||
reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes.
|
||||
reg [11:0] bit_counts=12'd0;///for timeslots... only support ts=0 for now, at 212 speed -512 fullbits from end of frame. One hopes. might remove those?
|
||||
|
||||
|
||||
//reg [2:0]old_mod;
|
||||
|
||||
//always @(mod_type) //when moving from modulate_mode
|
||||
//begin
|
||||
//if (mod_type[2]==1&&old_mod[2]==0)
|
||||
// bit_counts=0;
|
||||
//old_mod=mod_type;
|
||||
//end
|
||||
//we need some way to flush bit_counts triggers on mod_type changes don't compile
|
||||
reg dlay;
|
||||
always @(negedge adc_clk) //every data ping?
|
||||
begin
|
||||
//envelope follow code...
|
||||
////////////
|
||||
if ((mod_type==`SNIFFER )||(mod_type==`TAGSIM_LISTEN))
|
||||
|
||||
//move the counter to the outside...
|
||||
// if (adc_d>=curminthres||try_sync)
|
||||
if(fccount==bitmlen)
|
||||
begin
|
||||
if((~try_sync)&&(adc_d<curminthres)&&disabl )
|
||||
begin
|
||||
fccount<=1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
fccount<=0;
|
||||
end
|
||||
// if (counting_desync)
|
||||
// begin
|
||||
dlay<=ssp_dout;
|
||||
if(bit_counts>768) // should be over ts0 now, without ARM interference... stop counting...
|
||||
begin
|
||||
bit_counts<=0;
|
||||
// counting_desync<=0;
|
||||
end
|
||||
else
|
||||
if((power))
|
||||
bit_counts<=0;
|
||||
else
|
||||
bit_counts<=bit_counts+1;
|
||||
// end
|
||||
end
|
||||
else
|
||||
begin
|
||||
if((~try_sync)&&(adc_d<curminthres) &&disabl)
|
||||
begin
|
||||
fccount<=1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
fccount<=fccount+1;
|
||||
end
|
||||
end
|
||||
|
||||
if (adc_d>curmaxthres) //rising edge
|
||||
begin
|
||||
case (state)
|
||||
0: begin
|
||||
curmax <= adc_d>155? adc_d :155;
|
||||
curmax <= adc_d>`imax? adc_d :`imax;
|
||||
state <= 2;
|
||||
end
|
||||
1: begin
|
||||
|
@ -214,7 +243,7 @@ begin
|
|||
begin
|
||||
case (state)
|
||||
0: begin
|
||||
curmin <=adc_d<96? adc_d :96;
|
||||
curmin <=adc_d<`imin? adc_d :`imin;
|
||||
state <=1;
|
||||
end
|
||||
1: begin
|
||||
|
@ -224,7 +253,7 @@ begin
|
|||
2: begin
|
||||
curminthres <= ( (curmin>>1)+(curmin>>2)+(curmin>>4)+(curmax>>3)+(curmax>>4));
|
||||
curmaxthres <= ( (curmax>>1)+(curmax>>2)+(curmax>>4)+(curmin>>3)+(curmin>>4));
|
||||
curmin <=adc_d<96? adc_d :96;
|
||||
curmin <=adc_d<`imin? adc_d :`imin;
|
||||
state <=1;
|
||||
end
|
||||
default:
|
||||
|
@ -235,7 +264,7 @@ begin
|
|||
if (~try_sync ) //begin modulation, lower edge...
|
||||
begin
|
||||
try_sync <=1;
|
||||
counting_desync<=1'b0;
|
||||
//counting_desync<=1'b0;
|
||||
fccount <= 1;
|
||||
did_sync<=0;
|
||||
curbit<=0;
|
||||
|
@ -259,7 +288,7 @@ begin
|
|||
if (tsinceedge>=(128))
|
||||
begin
|
||||
//we might need to start counting... assuming ARM wants to reply to the frame.
|
||||
counting_desync<=1'b1;
|
||||
// counting_desync<=1'b1;
|
||||
bit_counts<=1;// i think? 128 is about 2 bits passed... but 1 also works
|
||||
try_sync<=0;
|
||||
did_sync<=0;//desync
|
||||
|
@ -278,32 +307,13 @@ begin
|
|||
end
|
||||
end
|
||||
|
||||
//move the counter to the outside...
|
||||
if (adc_d>=curminthres||try_sync)
|
||||
if(fccount==`bitmlen_212)
|
||||
begin
|
||||
fccount<=0;
|
||||
if (counting_desync)
|
||||
begin
|
||||
|
||||
if(bit_counts>768) // should be over ts0 now, without ARM interference... stop counting...
|
||||
begin
|
||||
bit_counts<=0;
|
||||
counting_desync<=0;
|
||||
end
|
||||
else
|
||||
bit_counts<=bit_counts+1;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
fccount<=fccount+1;
|
||||
end
|
||||
|
||||
|
||||
|
||||
if (try_sync && tsinceedge<128)
|
||||
begin
|
||||
//detect bits in their middle ssp sampling is in sync, so it would sample all bits in order
|
||||
if (fccount==`bithalf_212)
|
||||
if (fccount==bithalf)
|
||||
begin
|
||||
if ((~did_sync) && ((prv==1&&(mid>128))||(prv==0&&(mid<=128))))
|
||||
begin
|
||||
|
@ -336,7 +346,7 @@ begin
|
|||
end
|
||||
else
|
||||
begin
|
||||
if (fccount==`bitmlen_212)
|
||||
if (fccount==bitmlen)
|
||||
begin
|
||||
// fccount <=0;
|
||||
prv <=(mid>128)?1:0;
|
||||
|
@ -367,61 +377,40 @@ begin
|
|||
begin
|
||||
end
|
||||
sending <=0;
|
||||
|
||||
end //listen mode end
|
||||
else
|
||||
begin //sim mode start
|
||||
//not sure how precise do the time slots have to be... is anything within Ts ok?
|
||||
//keep counting until 576, just in case
|
||||
if(fccount==`bitmlen_212)
|
||||
begin
|
||||
if (bit_counts==512) //
|
||||
curbit<=1;
|
||||
else
|
||||
begin
|
||||
if(bit_counts>512)
|
||||
curbit<=mod_sig_coil;//delayline[delay_read_ptr];//bit_counts[0];
|
||||
else
|
||||
curbit<=0;
|
||||
end
|
||||
|
||||
fccount<=0;
|
||||
if (bit_counts<=576) //we don't need to count after that...
|
||||
begin
|
||||
bit_counts<=bit_counts+1;
|
||||
if (bit_counts== 512) //should start sending from next tick... i think?
|
||||
begin
|
||||
sending <=1;
|
||||
mod_sig_coil <=1;//modulate... down?
|
||||
preamble<=1;
|
||||
end
|
||||
else
|
||||
if (bit_counts== 559)
|
||||
begin
|
||||
preamble<=0;
|
||||
end
|
||||
end
|
||||
if (sending)
|
||||
begin //need next bit
|
||||
if(preamble)
|
||||
mod_sig_coil<=1;
|
||||
else
|
||||
mod_sig_coil<=~delayline[delay_read_ptr];
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
fccount<=fccount+1;
|
||||
|
||||
if ((fccount==`bitmhalf_212)&&(sending)) //flip modulation mid-bit
|
||||
begin
|
||||
mod_sig_coil<=~mod_sig_coil;//flip
|
||||
end
|
||||
end
|
||||
end //sim mode end
|
||||
|
||||
end
|
||||
//put modulation here to maintain the correct clock. Seems that some readers are sensitive to that
|
||||
reg pwr_hi;
|
||||
reg pwr_oe1;
|
||||
reg pwr_oe2;
|
||||
reg pwr_oe3;
|
||||
reg pwr_oe4;
|
||||
|
||||
assign pwr_oe4 = mod_sig_coil & (mod_type == `TAGSIM_MODULATE)&sending;
|
||||
wire mod=((fccount>=bithalf)^dlay)&(~disabl);
|
||||
|
||||
always @(ck_1356megb or ssp_dout or power or disabl or mod)
|
||||
begin
|
||||
if (power)
|
||||
begin
|
||||
pwr_hi <= ck_1356megb;
|
||||
pwr_oe1 <= mod;
|
||||
pwr_oe2 <= mod;
|
||||
pwr_oe3 <= mod;
|
||||
pwr_oe4 <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
pwr_hi <= 1'b0;
|
||||
pwr_oe1 <= 1'b0;
|
||||
pwr_oe2 <= 1'b0;
|
||||
pwr_oe3 <= 1'b0;
|
||||
pwr_oe4 <= mod;
|
||||
end
|
||||
end
|
||||
//assign pwr_oe4 = 1'b0;// mod_sig_coil & (modulate_mode)&sending & (~mod_type[2]);
|
||||
//try shallow mod for reader?
|
||||
//assign pwr_hi= (mod_type[2]) & ck_1356megb;
|
||||
//assign pwr_oe1= 1'b0; //mod_sig_coil & (modulate_mode)&sending & (mod_type[2]);
|
||||
//assign pwr_oe2 = 1'b0;// mod_sig_coil & (modulate_mode)&sending & (mod_type[2]);
|
||||
//assign pwr_oe3 = 1'b0; //mod_sig_coil & (modulate_mode)&sending & (mod_type[2]);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -10,7 +10,7 @@ module hi_read_rx_xcorr(
|
|||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg,
|
||||
xcorr_is_848, snoop
|
||||
xcorr_is_848, snoop, xcorr_quarter_freq
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
|
@ -20,7 +20,7 @@ module hi_read_rx_xcorr(
|
|||
output ssp_frame, ssp_din, ssp_clk;
|
||||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input xcorr_is_848, snoop;
|
||||
input xcorr_is_848, snoop, xcorr_quarter_freq;
|
||||
|
||||
// Carrier is steady on through this, unless we're snooping.
|
||||
assign pwr_hi = ck_1356megb & (~snoop);
|
||||
|
@ -28,18 +28,20 @@ assign pwr_oe1 = 1'b0;
|
|||
assign pwr_oe3 = 1'b0;
|
||||
assign pwr_oe4 = 1'b0;
|
||||
|
||||
// Clock divider
|
||||
reg [0:0] fc_divider;
|
||||
reg [2:0] fc_div;
|
||||
always @(negedge ck_1356megb)
|
||||
fc_divider <= fc_divider + 1;
|
||||
wire fc_div2 = fc_divider[0];
|
||||
fc_div <= fc_div + 1;
|
||||
|
||||
reg adc_clk;
|
||||
always @(ck_1356megb)
|
||||
if (xcorr_is_848)
|
||||
(* clock_signal = "yes" *) reg adc_clk; // sample frequency, always 16 * fc
|
||||
always @(ck_1356megb, xcorr_is_848, xcorr_quarter_freq, fc_div)
|
||||
if (xcorr_is_848 & ~xcorr_quarter_freq) // fc = 847.5 kHz
|
||||
adc_clk <= ck_1356megb;
|
||||
else
|
||||
adc_clk <= fc_div2;
|
||||
else if (~xcorr_is_848 & ~xcorr_quarter_freq) // fc = 424.25 kHz
|
||||
adc_clk <= fc_div[0];
|
||||
else if (xcorr_is_848 & xcorr_quarter_freq) // fc = 212.125 kHz
|
||||
adc_clk <= fc_div[1];
|
||||
else // fc = 106.0625 kHz
|
||||
adc_clk <= fc_div[2];
|
||||
|
||||
// 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,
|
||||
|
@ -71,8 +73,7 @@ end
|
|||
// so we need a 6-bit counter.
|
||||
reg [5:0] corr_i_cnt;
|
||||
// And a couple of registers in which to accumulate the correlations.
|
||||
// we would add at most 32 times adc_d, the result can be held in 13 bits.
|
||||
// Need one additional bit because it can be negative as well
|
||||
// we would add/sub at most 32 times adc_d, the signed result can be held in 14 bits.
|
||||
reg signed [13:0] corr_i_accum;
|
||||
reg signed [13:0] corr_q_accum;
|
||||
reg signed [7:0] corr_i_out;
|
||||
|
|
|
@ -12,7 +12,7 @@ module hi_read_tx(
|
|||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||
cross_hi, cross_lo,
|
||||
dbg,
|
||||
shallow_modulation
|
||||
shallow_modulation, speed, power
|
||||
);
|
||||
input pck0, ck_1356meg, ck_1356megb;
|
||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||
|
@ -23,6 +23,8 @@ module hi_read_tx(
|
|||
input cross_hi, cross_lo;
|
||||
output dbg;
|
||||
input shallow_modulation;
|
||||
input [1:0] speed;
|
||||
input power;
|
||||
|
||||
// The high-frequency stuff. For now, for testing, just bring out the carrier,
|
||||
// and allow the ARM to modulate it over the SSP.
|
||||
|
@ -32,6 +34,8 @@ reg pwr_oe2;
|
|||
reg pwr_oe3;
|
||||
reg pwr_oe4;
|
||||
always @(ck_1356megb or ssp_dout or shallow_modulation)
|
||||
begin
|
||||
if (power)
|
||||
begin
|
||||
if(shallow_modulation)
|
||||
begin
|
||||
|
@ -50,6 +54,15 @@ begin
|
|||
pwr_oe4 <= 1'b0;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
pwr_hi <= 1'b0;
|
||||
pwr_oe1 <= 1'b0;
|
||||
pwr_oe2 <= 1'b0;
|
||||
pwr_oe3 <= 1'b0;
|
||||
pwr_oe4 <= ~ssp_dout;
|
||||
end
|
||||
end
|
||||
|
||||
// Then just divide the 13.56 MHz clock down to produce appropriate clocks
|
||||
// for the synchronous serial port.
|
||||
|
@ -59,7 +72,7 @@ reg [6:0] hi_div_by_128;
|
|||
always @(posedge ck_1356meg)
|
||||
hi_div_by_128 <= hi_div_by_128 + 1;
|
||||
|
||||
assign ssp_clk = hi_div_by_128[6];
|
||||
assign ssp_clk = speed[1]? (speed[0]? hi_div_by_128[3]: hi_div_by_128[4]) : (speed[0]? hi_div_by_128[5]: hi_div_by_128[6]);
|
||||
|
||||
reg [2:0] hi_byte_div;
|
||||
|
||||
|
@ -76,7 +89,7 @@ assign adc_clk = ck_1356meg;
|
|||
reg after_hysteresis;
|
||||
always @(negedge adc_clk)
|
||||
begin
|
||||
if(& adc_d[7:0]) after_hysteresis <= 1'b1;
|
||||
if(& adc_d[7:4]) after_hysteresis <= 1'b1;
|
||||
else if(~(| adc_d[7:0])) after_hysteresis <= 1'b0;
|
||||
end
|
||||
|
||||
|
|
|
@ -53,11 +53,6 @@ end
|
|||
|
||||
// Divide 13.56 MHz by 32 to produce the SSP_CLK
|
||||
// The register is bigger to allow higher division factors of up to /128
|
||||
// FPGA_HF_SIMULATOR_NO_MODULATION (0<<0) // 0000
|
||||
// FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0) // 0001
|
||||
// FPGA_HF_SIMULATOR_MODULATE_212K (2<<0) // 0010
|
||||
// FPGA_HF_SIMULATOR_MODULATE_424K (4<<0) // 0100
|
||||
// FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101
|
||||
reg [10:0] ssp_clk_divider;
|
||||
|
||||
always @(posedge adc_clk)
|
||||
|
@ -91,8 +86,8 @@ end
|
|||
// Divide SSP_CLK by 8 to produce the byte framing signal; the phase of
|
||||
// this is arbitrary, because it's just a bitstream.
|
||||
// One nasty issue, though: I can't make it work with both rx and tx at
|
||||
// once. The phase wrt ssp_clk must be changed.
|
||||
// TODO to find out why that is and make a better fix.
|
||||
// once. The phase wrt ssp_clk must be changed. TODO to find out why
|
||||
// that is and make a better fix.
|
||||
reg [2:0] ssp_frame_divider_to_arm;
|
||||
always @(posedge ssp_clk)
|
||||
ssp_frame_divider_to_arm <= (ssp_frame_divider_to_arm + 1);
|
||||
|
|
|
@ -17,8 +17,11 @@ module hi_sniffer(
|
|||
output dbg;
|
||||
input xcorr_is_848, snoop, xcorr_quarter_freq; // not used.
|
||||
|
||||
|
||||
// let's try hi-pass
|
||||
|
||||
// We are only snooping, all off.
|
||||
assign pwr_hi = 1'b0;
|
||||
assign pwr_hi = ck_1356megb & xcorr_quarter_freq;//1'b0;
|
||||
assign pwr_lo = 1'b0;
|
||||
assign pwr_oe1 = 1'b0;
|
||||
assign pwr_oe2 = 1'b0;
|
||||
|
@ -29,8 +32,12 @@ reg ssp_frame;
|
|||
reg [7:0] adc_d_out = 8'd0;
|
||||
reg [2:0] ssp_cnt = 3'd0;
|
||||
|
||||
assign adc_clk = ck_1356meg;
|
||||
assign ssp_clk = ~ck_1356meg;
|
||||
|
||||
reg [12:0] avg=13'd0;
|
||||
|
||||
assign adc_clk = ck_1356megb;
|
||||
assign ssp_clk = ~ck_1356megb;
|
||||
|
||||
|
||||
always @(posedge ssp_clk)
|
||||
begin
|
||||
|
@ -41,7 +48,9 @@ begin
|
|||
|
||||
if(ssp_cnt[2:0] == 3'b000) // set frame length
|
||||
begin
|
||||
adc_d_out[7:0] <= adc_d;
|
||||
// adc_d_out[7:0] <= (alias_buf>>>3) +8'd126;//( $signed(adc_d-adc_d_old)>1 | $signed(adc_d_old-adc_d)>1)? alias_buf+adc_d-adc_d_old:alias_buf; //alias_buf[11:3]+8'd126;//adc_d;
|
||||
// adc_d_out[7:0]<=adc_d;
|
||||
adc_d_out[7:0] <=adc_d;//-(avg>>3) +8'd126;
|
||||
ssp_frame <= 1'b1;
|
||||
end
|
||||
else
|
||||
|
|
|
@ -171,6 +171,9 @@ typedef struct{
|
|||
#define CMD_FELICA_SIMULATE_TAG 0x03A0
|
||||
#define CMD_FELICA_SNOOP 0x03A1
|
||||
#define CMD_FELICA_COMMAND 0x03A2
|
||||
//temp
|
||||
#define CMD_FELICA_LITE_DUMP 0x03AA
|
||||
#define CMD_FELICA_LITE_SIM 0x03AB
|
||||
|
||||
// For measurements of the antenna tuning
|
||||
#define CMD_MEASURE_ANTENNA_TUNING 0x0400
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue