I tried out the timer idea I had, assuming an Atmega328 based "Arduino". It looks like it actually works although it's not that straightforward. Because the timer compare output is double buffered, getting it to generate a signal in one clock cycle (and then clearing the latch afterward) required feeding it internal clock pulses, then switching over to the external source. I don't have an oscilloscope, so to measure the delay I used a second Atmega328 and slowed the target processor down to 1/256 it's normal clock rate so I had enough measurement resolution.
I never saw it take more than 2.7 clocks, which at 16MHz would be about 170ns. Now maybe there is additional delay that my timing method couldn't capture. But I think it would work. Atmel says 3.5 clocks worst case. That would be 219ns.
This is the code (with the clock division code I used for testing deleted):
#define T1_INPUT_PIN 5 // 328 pin 11
#define OC1A_OUTPUT_PIN 9 // 328 pin 15
void setup()
{
pinMode(OC1A_OUTPUT_PIN, OUTPUT); // OC1A timer 1 compare output, digital pin 9, chip pin 15
pinMode(T1_INPUT_PIN, INPUT);
TCCR1A = 0; // Reset timer
TCCR1B = 0;
OCR1A = 1; // Output compare = 1
TCCR1A = 0xC0; // set 0C1A on compare match
TCCR1B = 0x0F; // CTC, external clock T1, clock on rising edge
TCNT1 = 0; // counter = 0
}
void loop()
{
if (digitalRead(OC1A_OUTPUT_PIN)) {
// Do something...
// Instead of polling this could be interrupt driven via the timer 1 compare ISR
delay(100); // just a placeholder
// When whatever we're driving with this pin needs to go low again, do this:
//
resetLatch();
}
}
void resetLatch()
{
TCCR1A = 0x40; // toggle OC1A on compare match
TIFR1 = 0x02; // clear compare flag
TCCR1B = 0x0C; // CTC, internal clock, prescaler = 256
while ((TIFR1 & 0x02) == 0) {} // wait for toggle
TCCR1B = 0; // disable clock
TCCR1A = 0;
OCR1A = 1; // output compare = 1
TCCR1A = 0xC0; // set 0C1A on compare match
TCCR1B = 0x0D; // CTC, prescaler = 1024
TCNT1 = 0;
delayMicroseconds(64+8); // clock period is 64us, make sure we get one clock
TCCR1B = 0x0F; // CTC, external clock T1, clock on rising edge
}
It's still probably simpler to use a 7474 or whatever the modern version of that part is.