Don't understand the nuances of Timer Modes 8 and 9

According to the datasheet, the only difference between 16 bit timer modes 8 and 9 are which values are used as TOP. In mode 8, ICR is used as TOP but in mode 9 OCR is used as TOP.

Now I've used mode 8 before and when I did, ICR was indeed TOP but OCR was used to determine the pulse width. So the counter would count up from BOTTOM, it would encounter OCR, trigger an edge, but still keep counting until it hit ICR, THEN it would stop and go back the other way. Since ICR could be any value between 0 and 2^16, it was ICR that controlled the frequency and OCR that controlled the PWM.

Now in mode 9, OCR is the TOP, which would suggest to me that ICR now serves as the PWM but for the life of me I can't find this documented anywhere, nor can I find any examples of mode 9 where ICR was used in this way. I do however see conflicting information that says OCR triggers the edges, but if that's true, you can never change frequency in mode 9, merely when the edges occur, which is the PWM duty.

I'm confused. I want a double-buffered TOP using OCR, but I want variable frequency as well and PWM. Mode 9 looks like it's supposed to do that. The data sheet even says, mode 9 is better for variable frequency because it uses the double-buffered OCR as a top instead of ICR. Sounds good and all except I don't see any clear evidence to support this.

Gahhhrrrlic:
Now in mode 9, OCR is the TOP, which would suggest to me that ICR now serves as the PWM

Nope. If you want to change the TOP value to set a particular frequency you can either use ICR1 for TOP (Mode 8) or use OCR1A for TOP (Mode 9). The advantage os Mode 8 is you get to use the OC1A pin for PWM. The advantage of using Mode 9 is that writing into the OCR1A register is double-buffered and happens once per cycle (at BOTTOM).
The ATmega2560 datasheet says:
"Using the ICRn Register for defining TOP works well when using fixed TOP values. By using ICRn, the OCRnA Register is free to be used for generating a PWM output on OCnA. However, if the base PWM frequency is actively changed by changing the TOP value, using the OCRnA as TOP is clearly a better choice due to its double buffer feature."

I have read all of this but the key piece of information is still missing... In Mode 9, how do you control duty? If ICR is not involved, then the OCR compare match is actually the only thing that can trigger an edge and it's exactly at top and the duty is exactly 50%.

Gahhhrrrlic:
I have read all of this but the key piece of information is still missing... In Mode 9, how do you control duty? If ICR is not involved, then the OCR compare match is actually the only thing that can trigger an edge and it's exactly at top and the duty is exactly 50%.

Not 50%. It's 100% (or 0%). The pin is set ON at BOTTOM and OFF at OCR1A/TOP counting up an ON at OCR1A/TOP and off at BOTTOM counting down.
The timers have 2 or 3 Output Compare Registers. In Mode 9 you can't use OCR1A for PWM but you can still use OCR1B and, on a MEGA, OCR1C.

Not 50%. It's 100% (or 0%). The pin is set ON at BOTTOM and OFF at OCR1A/TOP counting up an ON at OCR1A/TOP and off at BOTTOM counting down.

I think you can get a 50% square wave at half the frequency on the 1A pin by setting the output to toggle on compare match.

Well it would have to be 50% duty since there's no such thing as 0 or 100%. Either would be a straight line. But I'm curious how you'd use OCR2A or 3A to perform pwm. At least there's nothing in the documentation I could find suggesting this was possible.

cattledog:
I think you can get a 50% square wave at half the frequency on the 1A pin by setting the output to toggle on compare match.

Oh yes. I see now that the ATmega2560 will do that if you use COM mode 0b01 in WGM modes 9 or 11.

This does not work (no change on pin 5)

  DDRE |= (1 << PE3);               // Set OC3A as output

  TCCR3A = 0;
  TCCR3B = 0;                       // Set up timer 3 for PWM to tell the nano what code is currently in effect
  
  TCNT3 = 0;                        // Reset the counter

  TCCR3B |= (1 << WGM33);           // Toggle phase and frequency correct mode with OCR3A as top
  TCCR3B |= (1 << WGM30); 
  TCCR3A |= (1 << COM3A0);          // Toggle OC3A on compare match 

  // No prescaler 1 (001)
  // Prescaler 1024 (101)
  // Prescaler 256 (100)
 
//  TCCR3B |= (1 << CS32);    
//  TCCR3B |= (1 << CS31);        
  TCCR3B |= (1 << CS30);            // Prescaler of 2 and enable the timer

  OCR3A = 65000;                    // Set initial "idle" code
TCCR3B |= (1 << WGM33);           
TCCR3B |= (1 << WGM30);

Look more carefully at the data sheet again. WGM30 is on TCCR3A. I think that WGM30 is probably defined as 0 (that is bit 0) and you are just setting the CS30 bit which you actually do set later.

I think you are in mode 8 but without an ICR3 TOP value being set, which may default to 0.
All bets are off.

Holy shit you're right.

To be fair, they should have put them all on the same byte. Splitting them like that only causes confusion.

Bingo, that did it.

I did check each line of code like 5 times but I guess I wasn't paying attn to the register itself - thought that part was correct.

Thank you again.