From 0c54d13c47b4a3d6ddc8ef8f93bec3b881237c50 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Fri, 9 Oct 2020 14:30:34 +0200 Subject: [PATCH] added a precision timer ( 0.6ns for 43ms) --- armsrc/ticks.c | 25 +++++++++++++++++++++++++ armsrc/ticks.h | 1 + 2 files changed, 26 insertions(+) diff --git a/armsrc/ticks.c b/armsrc/ticks.c index e8ac13f89..9b563cc54 100644 --- a/armsrc/ticks.c +++ b/armsrc/ticks.c @@ -13,6 +13,31 @@ #include "proxmark3_arm.h" #include "dbprint.h" + +// timer counts in 666ns increments (32/48MHz), rounding applies +// WARNING: timer can't measure more than 43ms (666ns * 0xFFFF) +void SpinDelayUsPrecision(int us) { + int ticks = ((MCK / 1000000) * us + 16) >> 5; + + // Borrow a PWM unit for my real-time clock + AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0); + + // 48 MHz / 32 gives 1.5 Mhz + AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(5); // Channel Mode Register + AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0; // Channel Duty Cycle Register + AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xFFFF; // Channel Period Register + + uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + + for (;;) { + uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; + if (now == (uint16_t)(start + ticks)) + return; + + WDT_HIT(); + } +} + // timer counts in 21.3us increments (1024/48MHz), rounding applies // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff) void SpinDelayUs(int us) { diff --git a/armsrc/ticks.h b/armsrc/ticks.h index 9d8d178d5..dcf23ece1 100644 --- a/armsrc/ticks.h +++ b/armsrc/ticks.h @@ -20,6 +20,7 @@ void SpinDelay(int ms); void SpinDelayUs(int us); +void SpinDelayUsPrecision(int us); // precision 0.6us , running for 43ms before void StartTickCount(void); uint32_t RAMFUNC GetTickCount(void);