Which to use - ISR OVF or COMPx?

Hello, I am trying to use an interrupt to toggle a pin at a certain frequency and with a specific pulse width. Its for NTSC composite video, so the pin goes low every 15748 KHz and stays low for only 4.445uS.

I attached my code below, but I just want to know if I am correct in thinking that an “ISR(TIMER1_OVF_vect)” will be called at point “A” and “ISR(TIMER1_COMPB_vect)” would be called at point “B” in the photo below, granted I set TIMSK1 correctly. If I am wrong, how can I call a routine at point B?

#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include "pins_arduino.h"
#include <avr/pgmspace.h>

#define SETC(x) {PORTB = PORTB&~B11|x;} // where x is bit data
#define NOP __asm__ __volatile__ ("nop\n\t") // delays 62.5nS (0.0625uS) on 16MHz arduino
// 10 NOPs for convenience 
#define NOP10 NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP;NOP
// 4.5uS backporch. (4.5/0.0625) = 72
#define backPorch NOP10;NOP10;NOP10;NOP10;NOP10;NOP10;NOP10;NOP;NOP;NOP
// 1.5uS frontPorch. (1.5/0.0625)=24
#define frontPorch NOP10;NOP10;NOP;NOP;NOP;NOP

// OPTION 1 to switch between short sync and long sync (Hsync and Vsync)
// This one looked better on my scope when I tested one cycle short, one cycle long. 
#define width7 OCR1B = (int) (ICR1 * 0.07)
#define width93 OCR1B = (int) (ICR1 * 0.93)
// OPTION 2 to switch between short sync and long sync (Hsync and Vsync)
#define Hsyncing TCCR1A = 0x32; // 0011 0010
#define Vsyncing TCCR1A = 0x22; // 0010 0010

  unsigned char temp;
  unsigned int index; // Keeps track of where you are up to in the pixel data arrays
  unsigned char bitposition; // Keeps track of which bit in the current byte you should display
  unsigned int lineNumber; // counts from 1-242, inverts sync, then counts 243-262.
  const byte lineOffset = 32;

void setup() {
  cli();//stop interrupts
  lineNumber = 0;
/********* CONFIGURE IO PORTS *********/
  DDRB |= B00000111; // PB-0-1-2 out
  // 0,1 = luma bits
  // 2 = oc1b output (sync)
  PORTB &= ~B11;

/**************************************/
//
// TIMER 1 for interrupt frequency 15,748.031496063Hz
//
/**************************************/

// RTM_TimerCalc 1.20,  RuntimeMicro.com
// Timer-1 Mode_14_16Bit_Fast_TOP_is_ICR
    
    TCCR1B = 0x18; // 0001 1000, Disable Timer Clock 
    TCCR1A = 0x32; // 0011 0010
    
    ICR1 = 1015;
    width7; // OCR1B = (int) (ICR1 * 0.07);
    TCNT1=0x0;
    
    // Set Overflow Interrupt Mask Bit 
    TIMSK1 |= 1; // ISR Prototype --> ISR(TIMER1_OVF_vect){}
    
    // UnComment following lines for UNO-NANO Timer-1 Pins 
    // pinMode(10, OUTPUT); // OC1b

    TCCR1B |= 1; // Prescale=1, Enable Timer Clock

    sei();
}

void loop() {
  // Everything happens in the interrupts
  // NOP;
}


ISR(TIMER1_OVF_vect){
    
   }

You are in a fast PWM to ICR1 mode, and there is no need to use interrupts to achieve the output you want on outputB (pin 10). You will have better timing if you simply use the hardware compare output enabled in the mode with COMB1/COMB0.

It's not clear to me from your description if you want a short LOW pulse like your image, or if you want a short HIGH pulse

If you set COM1B1 to 1 and COM1B0 to 1 you set OC1B on compare match and clear OC1B at BOTTOM(inverting mode). This will give a short LOW pulse.

If you set COM1B1 to 1 and COM1B0 to 0 you clear OC1B on compare match, and set OC1B at
BOTTOM (non-inverting mode). This will give a short HIGH pulse.

cattledog:
You are in a fast PWM to ICR1 mode, and there is no need to use interrupts to achieve the output you want on outputB (pin 10). You will have better timing if you simply use the hardware compare output enabled in the mode with COMB1/COMB0.

It's not clear to me from your description if you want a short LOW pulse like your image, or if you want a short HIGH pulse

If you set COM1B1 to 1 and COM1B0 to 1 you set OC1B on compare match and clear OC1B at BOTTOM(inverting mode). This will give a short LOW pulse.

If you set COM1B1 to 1 and COM1B0 to 0 you clear OC1B on compare match, and set OC1B at
BOTTOM (non-inverting mode). This will give a short HIGH pulse.

Thanks for the reply!
I do have code in my interrupt, so I do need to use interrupts. I had to delete some text above because I had reached the 9000 character limit. Deleting my massive 2-dimensional array probably sufficed though.

I want a short (7%) low pulse, but at a certain point I change this to a wide (93%) low pulse for 3 or 4 cycles, then back again. This works better on my television than if I were to keep the 7% width and invert the output. For the record, I am getting a valid composite sync signal on my television and the luma is what my ISR is for.

ISR(TIMER1_OVF_vect){
    
    switch(lineNumber++){
    case (lineOffset+245): // Change to long sync. There should be 3 vertical sync scanlines.
        width93;
        // PORTB &= ~B11;
        break;
      case (lineOffset+247): // Change back to short sync, H-sync 
        width7;
        //PORTB &= ~B11;
        break;
      case (lineOffset+262): // 261 or 262? ... 263?
        lineNumber = 0;
        break;

        
      case (lineOffset+0) ... (lineOffset+143): // draw each line from the buffer
        backPorch;
        DRAW_PIXELS_FOR_LINE(lineNumber-1-lineOffset); //
        PORTB &= ~B11;
        break; 
      }
   }

I do have both COM1B1 and COM1B0 set to 1, so yes, I get a short low pulse which is exactly what I want.
Can you tell me at which point an "ISR(TIMER1_COMPB_vect)" would be called? Am I right in assuming a COMPB would it be called when OC1B is set? At the rising edge of OC1B?

Can you tell me at which point an "ISR(TIMER1_COMPB_vect)" would be called? Am I right in assuming a COMPB would it be called when OC1B is set? At the rising edge of OC1B?

Yes, that correct, but there is time taken from the point of the compare match to execute the isr. The first rising or falling edge of the initial hardware compare output on pinB will be ahead of the execution of the interrupt.

My understanding from the data sheet is that the compare match interrupt flag is set on the next clock cycle after the match.

The 16-bit comparator continuously compares TCNT1 with the output compare register (OCR1x). If TCNT equals OCR1x
the comparator signals a match. A match will set the output compare flag (OCF1x) at the next timer clock cycle. If enabled
(OCIE1x = 1), the output compare flag generates an output compare interrupt.

Then there is the interrupt latency to actually enter the ISR to execute the code. I have not seen the exact assembly code for a Timer compare interrupt, but I believe it maybe be on the order of 1.5 us to enter the interrupt and begin executing the code.

cattledog:
Yes, that correct, but there is time taken from the point of the compare match to execute the isr. The first rising or falling edge of the initial hardware compare output on pinB will be ahead of the execution of the interrupt.

My understanding from the data sheet is that the compare match interrupt flag is set on the next clock cycle after the match.

Thanks. I just needed someone to verify that for me.

cattledog:
Then there is the interrupt latency to actually enter the ISR to execute the code. I have not seen the exact assembly code for a Timer compare interrupt, but I believe it maybe be on the order of 1.5 us to enter the interrupt and begin executing the code.

That must be for a 16MHz clock? That makes sense I guess. I should take note of that since composite video is so precise.

I'm gonna try porting this over to a MEGA that I have and utilize the multiple serial ports to speed up my luma bit stream. If thats all I need to print the whole horizontal resolution I want, then I'll be really happy. Otherwise I may need to try out a teensy 2.1 or Trinket M0 for the extra speed. - just a few other boards I have in a drawer.

Thanks again!