From 35c8dfc4e04383b46b7ed28775e767f6ce270add Mon Sep 17 00:00:00 2001 From: douniwan5788 Date: Thu, 19 Sep 2024 18:29:59 +0800 Subject: [PATCH] fix: Hitag S logtrace time --- armsrc/hitagS.c | 79 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index ea38f395af..c696e5b532 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -71,6 +71,10 @@ static int rotate_uid = 0; static int sof_bits; // number of start-of-frame bits static uint8_t pwdh0, pwdl0, pwdl1; // password bytes static uint8_t rnd[] = {0x74, 0x12, 0x44, 0x85}; // random number +static uint16_t timestamp_high = 0; // Timer Counter 2 overflow count, ~47min + +#define TIMESTAMP (AT91C_BASE_TC2->TC_SR &AT91C_TC_COVFS ? timestamp_high += 1 : 0, ((timestamp_high << 16) + AT91C_BASE_TC2->TC_CV) / T0) + //#define SENDBIT_TEST /* array index 3 2 1 0 // bytes in sim.bin file are 0 1 2 3 @@ -360,18 +364,24 @@ static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len, bool LOW(GPIO_SSC_DOUT); } +static void hts_stop_clock(void) { + AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS; +} + static void hts_init_clock(void) { // Enable Peripheral Clock for // Timer Counter 0, used to measure exact timing before answering // Timer Counter 1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); + // Timer Counter 2, used to log trace time + AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; // Disable timer during configuration - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + hts_stop_clock(); // TC0: Capture mode, clock source = MCK/32 (TIMER_CLOCK3), no triggers AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; @@ -384,19 +394,23 @@ static void hts_init_clock(void) { AT91C_TC_ABETRG | // TIOA is used as an external trigger AT91C_TC_LDRA_FALLING; // load RA on on falling edge + // TC2: Capture mode, clock source = MCK/32 (TIMER_CLOCK3), no triggers + AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; + // Enable and reset counters AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + + // Assert a sync signal. This sets all timers to 0 on next active clock edge + AT91C_BASE_TCB->TCB_BCR = 1; // synchronized startup procedure // In theory, with MCK/32, we shouldn't be waiting longer than 32 instruction statements, right? while (AT91C_BASE_TC0->TC_CV != 0) {}; // wait until TC0 returned to zero -} - -static void hts_stop_clock(void) { - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + // reset timestamp + timestamp_high = 0; } /* @@ -679,7 +693,7 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { StopTicks(); - int response = 0, overflow = 0; + int overflow = 0; uint8_t rx[HITAG_FRAME_LEN]; size_t rxlen = 0; uint8_t tx[HITAG_FRAME_LEN]; @@ -740,13 +754,13 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { // Enable Peripheral Clock for // Timer Counter 0, used to measure exact timing before answering // Timer Counter 1, used to capture edges of the tag frames - AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); + // Timer Counter 2, used to log trace time + AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; // Disable timer during configuration - AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; - AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; + hts_stop_clock(); // TC0: Capture mode, default timer source = MCK/32 (TIMER_CLOCK3), no triggers AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; @@ -755,17 +769,27 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { // external trigger rising edge, load RA on rising edge of TIOA. AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING; + // TC2: Capture mode, default timer source = MCK/32 (TIMER_CLOCK3), no triggers + AT91C_BASE_TC2->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; // Enable and reset counter AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; + + // Assert a sync signal. This sets all timers to 0 on next active clock edge + AT91C_BASE_TCB->TCB_BCR = 1; // synchronized startup procedure while (AT91C_BASE_TC0->TC_CV != 0); // wait until TC0 returned to zero + // reset timestamp + timestamp_high = 0; + if (ledcontrol) LED_D_ON(); while ((BUTTON_PRESS() == false) && (data_available() == false)) { + uint32_t start_time = 0; WDT_HIT(); @@ -783,14 +807,14 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; if (ledcontrol) LED_B_ON(); + // Capture reader cmd start timestamp + if (start_time == 0) start_time = TIMESTAMP - HITAG_T_LOW; // Capture reader frame if (ra >= HITAG_T_STOP) { if (rxlen != 0) { //DbpString("weird0?"); } - // Capture the T0 periods that have passed since last communication or field drop (reset) - response = (ra - HITAG_T_LOW); } else if (ra >= HITAG_T_1_MIN) { // '1' bit rx[rxlen / 8] |= 1 << (7 - (rxlen % 8)); @@ -807,7 +831,7 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { // Check if frame was captured if (rxlen > 0) { - LogTraceBits(rx, rxlen, response, response, true); + LogTraceBits(rx, rxlen, start_time, TIMESTAMP, true); // Disable timer 1 with external trigger to avoid triggers during our own modulation AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; @@ -825,8 +849,9 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { // Send and store the tag answer (if there is any) if (txlen > 0) { // Transmit the tag frame + start_time = TIMESTAMP; hitag_send_frame(tx, txlen, ledcontrol); - LogTraceBits(tx, txlen, 0, 0, false); + LogTraceBits(tx, txlen, start_time, TIMESTAMP, false); } // Enable and reset external trigger in timer for capturing future frames @@ -834,7 +859,6 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { // Reset the received frame and response timing info memset(rx, 0x00, sizeof(rx)); - response = 0; if (ledcontrol) LED_B_OFF(); } @@ -847,6 +871,7 @@ void hts_simulate(bool tag_mem_supplied, const uint8_t *data, bool ledcontrol) { } + hts_stop_clock(); set_tracing(false); lf_finalize(ledcontrol); // release allocated memory from BigBuff. @@ -863,7 +888,6 @@ static void hts_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint3 int lastbit = 1; bool bSkip = true; - *resptime = 0; uint32_t errorCount = 0; bool bStarted = false; @@ -886,13 +910,12 @@ static void hts_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint3 if (ledcontrol) LED_B_ON(); - // Capture tag frame (manchester decoding using only falling edges) + // Capture tag response timestamp + if (*rxlen == 0) *resptime = TIMESTAMP; + // Capture tag frame (manchester decoding using only falling edges) if (bStarted == false) { - // Capture the T0 periods that have passed since last communication or field drop (reset) - *resptime = ra - HITAG_T_TAG_HALF_PERIOD; - if (ra >= HITAG_T_WAIT_RESP) { bStarted = true; @@ -960,8 +983,7 @@ static void hts_receive_frame(uint8_t *rx, size_t sizeofrx, size_t *rxlen, uint3 } static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t sizeofrx, size_t *prxbits, int t_wait, bool ledcontrol, bool ac_seq) { - - LogTraceBits(tx, txlen, HITAG_T_WAIT_SC, HITAG_T_WAIT_SC, true); + uint32_t start_time; // Send and store the reader command // Disable timer 1 with external trigger to avoid triggers during our own modulation @@ -974,6 +996,8 @@ static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t // All timer values are in terms of T0 units while (AT91C_BASE_TC0->TC_CV < T0 * t_wait) {}; + start_time = TIMESTAMP; + // Transmit the reader frame hitag_reader_send_frame(tx, txlen, ledcontrol); @@ -981,12 +1005,13 @@ static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t return PM3_ETEAROFF; } + LogTraceBits(tx, txlen, start_time, TIMESTAMP, true); + // Enable and reset external trigger in timer for capturing future frames AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; - uint32_t resptime = 0; size_t rxlen = 0; - hts_receive_frame(rx, sizeofrx, &rxlen, &resptime, ledcontrol); + hts_receive_frame(rx, sizeofrx, &rxlen, &start_time, ledcontrol); int k = 0; // Check if frame was captured and store it @@ -1049,7 +1074,7 @@ static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t } } } - LogTraceBits(rx, k, resptime, resptime, false); + LogTraceBits(rx, k, start_time, TIMESTAMP, false); } *prxbits = k;