+int CmdEM4x05WriteWord(const char *Cmd) {
+ bool errors = false;
+ bool usePwd = false;
+ uint32_t data = 0xFFFFFFFF;
+ uint32_t pwd = 0xFFFFFFFF;
+ bool swap = false;
+ bool invert = false;
+ uint8_t addr = 16; // default to invalid address
+ bool gotData = false;
+ char cmdp = 0;
+ while(param_getchar(Cmd, cmdp) != 0x00)
+ {
+ switch(param_getchar(Cmd, cmdp))
+ {
+ case 'h':
+ case 'H':
+ return usage_lf_em_write();
+ case 'a':
+ case 'A':
+ addr = param_get8ex(Cmd, cmdp+1, 16, 10);
+ cmdp += 2;
+ break;
+ case 'd':
+ case 'D':
+ data = param_get32ex(Cmd, cmdp+1, 0, 16);
+ gotData = true;
+ cmdp += 2;
+ break;
+ case 'i':
+ case 'I':
+ invert = true;
+ cmdp++;
+ break;
+ case 'p':
+ case 'P':
+ pwd = param_get32ex(Cmd, cmdp+1, 1, 16);
+ if (pwd == 1) {
+ PrintAndLog("invalid pwd");
+ errors = true;
+ }
+ usePwd = true;
+ cmdp += 2;
+ break;
+ case 's':
+ case 'S':
+ swap = true;
+ cmdp++;
+ break;
+ default:
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+ errors = true;
+ break;
+ }
+ if(errors) break;
+ }
+ //Validations
+ if(errors) return usage_lf_em_write();
+
+ if ( strlen(Cmd) == 0 ) return usage_lf_em_write();
+
+ if (!gotData) {
+ PrintAndLog("You must enter the data you want to write");
+ return usage_lf_em_write();
+ }
+ return EM4x05WriteWord(addr, data, pwd, usePwd, swap, invert);
+}
+
+void printEM4x05config(uint32_t wordData) {
+ uint16_t datarate = EM4x05_GET_BITRATE(wordData);
+ uint8_t encoder = ((wordData >> 6) & 0xF);
+ char enc[14];
+ memset(enc,0,sizeof(enc));
+
+ uint8_t PSKcf = (wordData >> 10) & 0x3;
+ char cf[10];
+ memset(cf,0,sizeof(cf));
+ uint8_t delay = (wordData >> 12) & 0x3;
+ char cdelay[33];
+ memset(cdelay,0,sizeof(cdelay));
+ uint8_t numblks = EM4x05_GET_NUM_BLOCKS(wordData);
+ uint8_t LWR = numblks+5-1; //last word read
+ switch (encoder) {
+ case 0: snprintf(enc,sizeof(enc),"NRZ"); break;
+ case 1: snprintf(enc,sizeof(enc),"Manchester"); break;
+ case 2: snprintf(enc,sizeof(enc),"Biphase"); break;
+ case 3: snprintf(enc,sizeof(enc),"Miller"); break;
+ case 4: snprintf(enc,sizeof(enc),"PSK1"); break;
+ case 5: snprintf(enc,sizeof(enc),"PSK2"); break;
+ case 6: snprintf(enc,sizeof(enc),"PSK3"); break;
+ case 7: snprintf(enc,sizeof(enc),"Unknown"); break;
+ case 8: snprintf(enc,sizeof(enc),"FSK1"); break;
+ case 9: snprintf(enc,sizeof(enc),"FSK2"); break;
+ default: snprintf(enc,sizeof(enc),"Unknown"); break;
+ }
+
+ switch (PSKcf) {
+ case 0: snprintf(cf,sizeof(cf),"RF/2"); break;
+ case 1: snprintf(cf,sizeof(cf),"RF/8"); break;
+ case 2: snprintf(cf,sizeof(cf),"RF/4"); break;
+ case 3: snprintf(cf,sizeof(cf),"unknown"); break;
+ }
+
+ switch (delay) {
+ case 0: snprintf(cdelay, sizeof(cdelay),"no delay"); break;
+ case 1: snprintf(cdelay, sizeof(cdelay),"BP/8 or 1/8th bit period delay"); break;
+ case 2: snprintf(cdelay, sizeof(cdelay),"BP/4 or 1/4th bit period delay"); break;
+ case 3: snprintf(cdelay, sizeof(cdelay),"no delay"); break;
+ }
+ uint8_t readLogin = (wordData & EM4x05_READ_LOGIN_REQ)>>18;
+ uint8_t readHKL = (wordData & EM4x05_READ_HK_LOGIN_REQ)>>19;
+ uint8_t writeLogin = (wordData & EM4x05_WRITE_LOGIN_REQ)>>20;
+ uint8_t writeHKL = (wordData & EM4x05_WRITE_HK_LOGIN_REQ)>>21;
+ uint8_t raw = (wordData & EM4x05_READ_AFTER_WRITE)>>22;
+ uint8_t disable = (wordData & EM4x05_DISABLE_ALLOWED)>>23;
+ uint8_t rtf = (wordData & EM4x05_READER_TALK_FIRST)>>24;
+ uint8_t pigeon = (wordData & (1<<26))>>26;
+ PrintAndLog("ConfigWord: %08X (Word 4)\n", wordData);
+ PrintAndLog("Config Breakdown:");
+ PrintAndLog(" Data Rate: %02u | RF/%u", wordData & 0x3F, datarate);
+ PrintAndLog(" Encoder: %u | %s", encoder, enc);
+ PrintAndLog(" PSK CF: %u | %s", PSKcf, cf);
+ PrintAndLog(" Delay: %u | %s", delay, cdelay);
+ PrintAndLog(" LastWordR: %02u | Address of last word for default read - meaning %u blocks are output", LWR, numblks);
+ PrintAndLog(" ReadLogin: %u | Read Login is %s", readLogin, readLogin ? "Required" : "Not Required");
+ PrintAndLog(" ReadHKL: %u | Read Housekeeping Words Login is %s", readHKL, readHKL ? "Required" : "Not Required");
+ PrintAndLog("WriteLogin: %u | Write Login is %s", writeLogin, writeLogin ? "Required" : "Not Required");
+ PrintAndLog(" WriteHKL: %u | Write Housekeeping Words Login is %s", writeHKL, writeHKL ? "Required" : "Not Required");
+ PrintAndLog(" R.A.W.: %u | Read After Write is %s", raw, raw ? "On" : "Off");
+ PrintAndLog(" Disable: %u | Disable Command is %s", disable, disable ? "Accepted" : "Not Accepted");
+ PrintAndLog(" R.T.F.: %u | Reader Talk First is %s", rtf, rtf ? "Enabled" : "Disabled");
+ PrintAndLog(" Pigeon: %u | Pigeon Mode is %s\n", pigeon, pigeon ? "Enabled" : "Disabled");
+}
+