From 9b3bc551368bf126e03f504d695518afbf188bca Mon Sep 17 00:00:00 2001 From: tharexde Date: Tue, 29 Dec 2020 17:40:18 +0100 Subject: [PATCH] aa --- armsrc/em4x50.c | 132 ++++++++++++++++++++++++--------------- client/src/cmdlfem4x50.c | 96 ++++++++++++++++++++++++++-- include/em4x50.h | 5 +- 3 files changed, 178 insertions(+), 55 deletions(-) diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index a84a911c5..b03872bea 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -62,6 +62,26 @@ static void wait_timer(uint32_t period) { while (AT91C_BASE_TC0->TC_CV < period); } +static void catch_samples(void) { + + uint8_t sample = 0; + + if (EM4X50_MAX_NO_SAMPLES > CARD_MEMORY_SIZE) { + Dbprintf("exeeded emulator memory size"); + return; + } + + uint8_t *em4x50_sample_buffer = BigBuf_get_addr(); + + memcpy(em4x50_sample_buffer, &gHigh, 1); + memcpy(em4x50_sample_buffer + 1, &gLow, 1); + + for (int i = 2; i < EM4X50_MAX_NO_SAMPLES + 2; i++) { + sample = AT91C_BASE_SSC->SSC_RHR; + memcpy(em4x50_sample_buffer + i, &sample, 1); + wait_timer(T0); // 8µs delay + } +} // extract and check parities // return result of parity check and extracted plain data @@ -242,11 +262,13 @@ static bool invalid_bit(void) { // get sample at 3/4 of bit period wait_timer(T0 * EM4X50_T_TAG_THREE_QUARTER_PERIOD); + //wait_timer(T0 * EM4X50_T_TAG_HALF_PERIOD); uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // wait until end of bit period wait_timer(T0 * EM4X50_T_TAG_QUARTER_PERIOD); + //wait_timer(T0 * EM4X50_T_TAG_HALF_PERIOD); // bit in "undefined" state? if (sample <= gHigh && sample >= gLow) @@ -422,6 +444,8 @@ static int find_double_listen_window(bool bcommand) { // skip the next bit... wait_timer(T0 * EM4X50_T_TAG_FULL_PERIOD); + catch_samples(); + break; // ...and check if the following bit does make sense // (if not it is the correct position within the second @@ -723,24 +747,11 @@ static bool em4x50_sim_send_word(uint32_t word) { static bool em4x50_sim_send_listen_window(void) { - bool cond = false; uint16_t check = 0; - uint32_t tval1[5 * EM4X50_T_TAG_FULL_PERIOD] = {0}; - uint32_t tval2[5 * EM4X50_T_TAG_FULL_PERIOD] = {0}; - - StartTicks(); for (int t = 0; t < 5 * EM4X50_T_TAG_FULL_PERIOD; t++) { - cond = ((t >= 3 * EM4X50_T_TAG_FULL_PERIOD) && (t < 4 * EM4X50_T_TAG_FULL_PERIOD)); - // wait until SSC_CLK goes HIGH - if (cond) { - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV > 0); - } - while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { WDT_HIT(); @@ -751,8 +762,6 @@ static bool em4x50_sim_send_listen_window(void) { } ++check; } - if (cond) - tval1[t] = GetTicks(); if (t >= 4 * EM4X50_T_TAG_FULL_PERIOD) SHORT_COIL(); @@ -768,12 +777,6 @@ static bool em4x50_sim_send_listen_window(void) { check = 0; // wait until SSC_CLK goes LOW - if (cond) { - AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; - AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; - while (AT91C_BASE_TC0->TC_CV > 0); - } - while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { WDT_HIT(); if (check == 1000) { @@ -783,15 +786,7 @@ static bool em4x50_sim_send_listen_window(void) { } ++check; } - if (cond) - tval2[t] = GetTicks(); } - - for (int t = 0; t < 5 * EM4X50_T_TAG_FULL_PERIOD; t++) { - //if (tval[t] > 4) - Dbprintf("%3i probably RM intialization found: delta = %i %i", t, tval1[t], tval2[t]); - } - Dbprintf(""); return true; } @@ -1315,33 +1310,72 @@ void em4x50_test(em4x50_test_t *ett) { int status = PM3_EFAILED; - em4x50_setup_read(); + // set field on or off + if (ett->field != -1) { + em4x50_setup_read(); + if (ett->field == 1) { + LED_A_ON(); + } else { + HIGH(GPIO_SSC_DOUT); + LED_A_OFF(); + } + status = ett->field; + } - if (ett->field) { - LOW(GPIO_SSC_DOUT); - LED_A_ON(); + // check field status + if (ett->check_field) { + em4x50_setup_sim(); + bool field_on = false; + while (BUTTON_PRESS() == false) { - if (DBGLEVEL >= DBG_DEBUG) - Dbprintf("switched field on"); - + if (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + if (field_on == false) { + Dbprintf("field on"); + field_on = true; + } + } else if (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK){ + if (field_on == true) { + Dbprintf("field off"); + field_on = false; + } + } + } status = 1; - } else { - HIGH(GPIO_SSC_DOUT); - LED_A_OFF(); - - if (DBGLEVEL >= DBG_DEBUG) - Dbprintf("switched field off"); - - status = 0; } - while (BUTTON_PRESS() == false) { + // timing values + if (ett->cycles != 0) { + uint32_t tval = 0; + uint32_t tvalhigh[ett->cycles]; + uint32_t tvallow[ett->cycles]; - if (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - Dbprintf("field on"); - } else if (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)){ - Dbprintf("field on"); + em4x50_setup_sim(); + AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0); + AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK; + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + while (AT91C_BASE_TC0->TC_CV > 0); + + for (int t = 0; t < ett->cycles; t++) { + + // field on -> high value + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + tval = AT91C_BASE_TC0->TC_CV; + while (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)); + tvalhigh[t] = AT91C_BASE_TC0->TC_CV - tval; + + // filed off -> zero value + AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; + tval = AT91C_BASE_TC0->TC_CV; + while (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK); + tvallow[t] = AT91C_BASE_TC0->TC_CV - tval; } + + for (int t = 0; t < ett->cycles; t++) { + Dbprintf("%03i %li %li", t, tvallow[t], tvalhigh[t]); + } + } reply_ng(CMD_LF_EM4X50_TEST, status, NULL, 0); diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index 8182a822f..a3da00bcc 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -23,6 +23,61 @@ static int CmdHelp(const char *Cmd); +static void write_gnuplot_config_file(int gHigh, int gLow) { + + const char *fn = "../data/data.gnu"; + FILE *fp = NULL; + + if ((fp = fopen(fn, "w+")) == false) { + PrintAndLogEx(WARNING, "Fail, open file %s", fn); + } + + fprintf(fp, "set term qt size 1400, 350 enhanced\n"); + fprintf(fp, "set border 31 front linecolor rgb 'dark-grey' linewidth 1.000 dashtype solid\n"); + fprintf(fp, "set xtics 0, 1 textcolor rgb 'dark-grey'\n"); + fprintf(fp, "set ytics 0, 64 textcolor rgb 'dark-grey'\n"); + fprintf(fp, "set title 'EM4x50 signal (amplitude vs time)'\n"); + fprintf(fp, "set title font ',14' textcolor rgb 'white'\n"); + fprintf(fp, "set xlabel 'time / ms'\n"); + fprintf(fp, "set xlabel font ',12' textcolor rgb 'dark-grey'\n"); + fprintf(fp, "set ylabel 'amplitude'\n"); + fprintf(fp, "set ylabel font ',12' textcolor rgb 'dark-grey'\n"); + fprintf(fp, "set key textcolor 'green'\n"); + fprintf(fp, "set grid\n"); + fprintf(fp, "#set time textcolor 'dark-grey'\n"); + fprintf(fp, "plot [0:][-50:300] '../data/data.dat' u ($1/1000):2 w l linecolor 'green' title '500/4', '../data/data.dat' u ($1/1000):3 w l linecolor 'yellow' title 'gHigh = %i', '../data/data.dat' u ($1/1000):4 w l linecolor 'yellow' title 'gLow = %i'\n", gHigh, gLow); + fprintf(fp, "pause -1\n"); + + fclose(fp); +} + +static void get_samples(void) { + + int gHigh = 0, gLow = 0; + const char *fn = "../data/data.dat"; + FILE *fp = NULL; + + // download from BigBuf memory + uint8_t data[EM4X50_MAX_NO_SAMPLES + 2] = {0x0}; + if (GetFromDevice(BIG_BUF, data, EM4X50_MAX_NO_SAMPLES + 2, 0, NULL, 0, NULL, 2500, false) == false) { + PrintAndLogEx(WARNING, "Fail, transfer from device time-out"); + } + + if ((fp = fopen(fn, "w+")) == false) { + PrintAndLogEx(WARNING, "Fail, open file %s", fn); + } + + gHigh = data[0]; + gLow = data[1]; + for (int i = 2; i < EM4X50_MAX_NO_SAMPLES + 2; i++) { + fprintf(fp, "%i %i %i %i\n", (i - 2) * 8, data[i], gHigh, gLow); + } + + fclose(fp); + + write_gnuplot_config_file(gHigh, gLow); +} + static void prepare_result(const uint8_t *data, int fwr, int lwr, em4x50_word_t *words) { // restructure received result in "em4x50_word_t" structure @@ -612,6 +667,8 @@ int CmdEM4x50Read(const char *Cmd) { } } + get_samples(); + return em4x50_read(&etd, NULL); } @@ -1162,19 +1219,43 @@ int CmdEM4x50Test(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "lf em 4x50 test", "perform EM4x50 tests.", - "lf em 4x50 test --field 1 -> reader field on \n" + "lf em 4x50 test --field on -> reader field on\n" + "lf em 4x50 test --field off -> reader field off\n" + "lf em 4x50 test --check -> check on/off status of reader field\n" + "lf em 4x50 test --cycles 100 -> measure time of 100 field cycles\n" ); void *argtable[] = { arg_param_begin, - arg_lit0("", "field", "field off/on"), + arg_str0(NULL, "field", "on/off", "field on/off"), + arg_lit0(NULL, "check", "check if field is on or off"), + arg_int0(NULL, "cycles", "", "number of field cycles"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); - em4x50_test_t ett; - ett.field = arg_get_lit(ctx, 1); + // option: field + int slen = 0; + char format[3] = {0}; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)format, sizeof(format), &slen); + em4x50_test_t ett = {.field = -1}; + if (slen != 0) { + if (strcmp(format, "on") == 0) { + ett.field = 1; + } else if (strcmp(format, "off") == 0) { + ett.field = 0; + } else { + PrintAndLogEx(INFO, "Unknown option for --field: %s", format); + return PM3_ESOFT; + } + } + + // option: check_field + ett.check_field = arg_get_lit(ctx, 2); + // option: cycles + ett.cycles = arg_get_int_def(ctx, 3, 0); + CLIParserFree(ctx); // start @@ -1185,9 +1266,14 @@ int CmdEM4x50Test(const char *Cmd) { // print response if (resp.status == 1) { - PrintAndLogEx(SUCCESS, "Field switched " _GREEN_("on")); + if (ett.field == 1) + PrintAndLogEx(SUCCESS, "Field switched " _GREEN_("on")); + if (ett.check_field == 1) + PrintAndLogEx(SUCCESS, "Field status evaluated"); } else if (resp.status == 0) { PrintAndLogEx(SUCCESS, "Field switched " _GREEN_("off")); + } else if (resp.status == -1) { + PrintAndLogEx(INFO, "Nothing done"); } else { PrintAndLogEx(FAILED, "Test call " _RED_("failed")); } diff --git a/include/em4x50.h b/include/em4x50.h index 27d71e661..3308a371f 100644 --- a/include/em4x50.h +++ b/include/em4x50.h @@ -36,6 +36,7 @@ // misc #define TIMEOUT 2000 #define DUMP_FILESIZE 136 +#define EM4X50_MAX_NO_SAMPLES 1000 typedef struct { bool addr_given; @@ -47,7 +48,9 @@ typedef struct { } PACKED em4x50_data_t; typedef struct { - bool field; + bool check_field; + int field; + int cycles; } PACKED em4x50_test_t; typedef struct {