UNO timer1: can you do both input capture and output compare at same time?

I'm trying to use timer 1 for both input capture and output compare simultaneously but can't get it to work. In a test program input capture only works, output compare only works but not both at the same time.

Using an UNO, pin 8 has a square wave input at 1khz to 2.5khz (from a different board not the same one I'm asking about here).

The test program uses the input capture of the UNO to measure the average time between edges.

Next, the test program is using output compare to generate a different square wave. I'm able to use the internal ability to automatically toggle D9 on compare and can also manually toggle D10 from the ISR.

However, I can't get both Input Capture (IC) and Output Compare (OC) at the same time.

I'm using an oscilloscope and can see when the outputs on D9 and D10 are running, and see the serial output using the serial monitor.

In the test program, at the bottom of setup() there are 3 lines. (A) The first enables OC interrupt only. (B) Second enables IC interrupt only. (C) Third enables both.

If (A) OC only, D9 and D10 toggle, no serial output -- (expected)
If (B) IC only, serial output is there and no D9 or D10 -- (expected)
If (C) both IC and OC, no D9 or D10 toggle, (but do see serial output) -- (NOT expected)

I've checked the datasheet but don't see why both shouldn't work, and don't see what is wrong.

Any ideas are greatly appreciated.

Thanks -

#include "Arduino.h"
#include <avr/interrupt.h>

#define SERIAL_BAUD 9600

// Digital pin 9 for OCR automatic output
// Digital pin 10 for OCR manual output
// Digital pin 8 for square wave input from other UNO at around 1khz to 2khz

const int OCPin           = 9;
const int ICPin           = 8;

#define   OUT_PIN         10

const int Prescale          = 8;             // prescaler factor, 0.5 uS @16Mhz
const byte PrescaleBits     = B010;

bool enabled = false;

const int numResults = 64;
volatile byte index = 0;
volatile unsigned int results[numResults];

volatile unsigned char tog=0;


// Output Compare ISR

ISR(TIMER1_COMPA_vect)
{
    OCR1A += 1000;    // set next interrupt compare time

   // manually toggle D10 in addition to D9
   if(tog & 1)
        bitClear(PORTB, 2);
    else
        bitSet(PORTB, 2);

    tog++;
}


// Input capture ISR

ISR(TIMER1_CAPT_vect) 
{
    TCNT1 = 0;          // reset counter

    if(enabled && (index < numResults))
    {
        results[index] = ICR1;
        index++;
    }

    // stop collection until loop() prints result
    if(index == numResults)
        enabled = false;
        
    // look for other edge
    TCCR1B ^= _BV(ICES1);
}


//
// Setup timers Arduino UNO
//        BIT      7      6      5      4      3      2       1      0
// TCCR1A has COM1A1 COM1A0 COM1B1 COM1B0      –      –   WGM11   WGM10
// TCCR1B has  ICNC1  ICES1      –  WGM13  WGM12   CS12    CS11    CS10
// TIMSK1 has      –      –  ICIE1      –      –  OCIE1B OCIE1A   TOIE1

void setup(void) 
{
    // Set up the I/O direction
    pinMode(ICPin, INPUT_PULLUP);
    pinMode(OCPin, OUTPUT);
    pinMode(OUT_PIN, OUTPUT);   // Make Port D10 output
    
    Serial.begin(SERIAL_BAUD);

    // Input Capture, Output Compare setup

    TCCR1A = 0x01 << 6;             // COM1A1, COM1A0 = 01 => D9 toggle compare match
    TCCR1B = PrescaleBits;          // divide by 8 from prescaler

    // 
    // Note: A and B work as expected, C does not:
    //
    
    //TIMSK1 = TIMSK1 | 0x02;         // (A) enable OCIE1A only
    //TIMSK1 = TIMSK1 | 0x20;         // (B) enable ICIE1 only
    TIMSK1 = TIMSK1 | 0x22;         // (C) enable both OCIE1A and ICIE1

    index = 0;
    enabled = true;                 // enable time collection
}





///////////////////////////////////////////////////////////////////////////////
void loop(void) 
{
  unsigned avg = 0;
  unsigned min = 65535;
  unsigned max = 0;
  unsigned long sum=0;
  int i;

    // wait for IC ISR to collect some edges
    while (index < numResults) 
    {
        delay(5);
    }
        
    // print the results of square wave timing
    for(i=0; i<numResults; i++)
    {
        if(results[i] > max) max = results[i];
        if(results[i] < min) min = results[i];
        sum = sum + results[i];
    }
    
    avg = sum / numResults;

    Serial.print(avg); Serial.print(" "); 
    Serial.print(min); Serial.print(" "); 
    Serial.print(max); 
    Serial.println(""); 


    // re-enable Input Capture ISR to start recording time again
    index = 0;
    enabled = true;
}

Oops -- User Error -- one problem is I just now saw by accident Timer 1 is set to zero inside the IC ISR.

I'm guessing the timer counter never reaches the value in OCR1A because you reset it to zero on every capture interrupt.

EDIT:
Never mind, I see you just caught that.

Thanks for looking it over though.

Also, it looks like at the beginning of setup you need to clear / set the timer registers to known values - I guess the Arduino initialization is writing into some of them. Previously I was just setting the fields I wanted to use. Looks like it works when first zeroing TCCR1A, TCCR1B and TIMSK1 then setting specific fields. Obviously nothing else can use Timer 1 but that's fine.

Once I confirm its working I'll repost the code as an example if someone else wants to do the same thing - using Timer 1 for both input capture and output compare simultaneously in "Normal" mode.