i have given two square waves as input to arduino due's digital pins and trying to find the propagation delay between them. for this purpose instead of using micros() i want nanoseconds measurement hence DWT_CYCCNT is used . but the when the delay between two is zero( both are ideal square waves ) then alse the delay given by this code is 770ns. i just want your opinions on whether the appraoch to use DWT is correct for this purpose and how to improvise .
#define REG_DWT_CTRL (*(volatile unsigned int*)0xE0001000U) // DWT Control Register
#define REG_DWT_CYCCNT (*(volatile unsigned int*)0xE0001004U) // DWT Cycle Count Register
#define REG_DEMCR (*(volatile unsigned int*)0xE000EDFCU) // Debug Exception and Monitor Control Register
#define CYCCNTENA (1 << 0) // DWT CTRL Cycle Count Enable Bit
#define TRCENA (1 << 24) // DEMCR Trace Enable Bit
#define INPUT_PIN 4 // Buffer input
#define OUTPUT_PIN 5 // Buffer output
volatile uint32_t start_cycles = 0;
volatile uint32_t end_cycles = 0;
volatile bool measurement_ready = false;
void inputISR() {
start_cycles = REG_DWT_CYCCNT; // Capture cycles at input rising edge
measurement_ready = false; // Reset until output triggers
}
void outputISR() {
end_cycles = REG_DWT_CYCCNT; // Capture cycles at output rising edge
measurement_ready = true; // Signal measurement is ready
}
void setup() {
// Enable trace functionality
REG_DEMCR |= TRCENA;
// Reset cycle counter to 0 (optional)
REG_DWT_CYCCNT = 0;
// Enable the cycle counter
REG_DWT_CTRL |= CYCCNTENA;
pinMode(INPUT_PIN, INPUT);
pinMode(OUTPUT_PIN, INPUT);
// Attach interrupts for rising edges (buffer: input rise -> output rise)
attachInterrupt(digitalPinToInterrupt(INPUT_PIN), inputISR, RISING);
attachInterrupt(digitalPinToInterrupt(OUTPUT_PIN), outputISR, RISING);
Serial.begin(115200);
}
void loop() {
if (measurement_ready) {
uint32_t cycle_diff = end_cycles - start_cycles;
float delay_ns = cycle_diff * (1000.0 / 84.0); // Convert to ns (84 MHz)
Serial.print("Propagation delay (ns): ");
Serial.println(delay_ns);
measurement_ready = false; // Reset for next measurement
}
}