// Test for CTC mode for Timer1 pin 9 and Timer2 pin 11
//
// Calculate myOCR:
//   Select frequency, for example 625Hz.
//   Select a prescaler, for example 256
//   The OCR = 16MHz / (frequency * prescaler) - 1 = 49
//
// Test 1
//   myIndex = 3, myOCR = 49 => 625 Hz in PulseView  Good
// Test 2
//   myIndex = 0, myOCR = 159 => 50.000 kHz in PulseView  Good
//   With my Uno (with resonator) in real life: Bad, 49.7kHz
// Test 3
//   A Uno clone with a accurate 16MHz crystal.
//   The LHT00SU1 turns out to sample at a wrong rate at 48MHz.
//   It is accurate at 24MHz sample rate.
//
// Conclusion: My resonator is bad, my LHT00SU1 is not accurate at 48MHz,
//             the CTC mode in Wokwi is the same as in real life.
//             The other mode is probably correct by Wokwi as well.


// The combined prescaler values for Timer1 and Timer2.
const unsigned prescalerlist[5] = { 1, 8, 64, 256, 1024 };


// Select the index for the prescaler array and the OCR value
int myIndex = 0;        // 0...4
uint8_t myOCR = 159;    // 0...255



void setup() 
{
  Serial.begin(115200);
  pinMode( 9, OUTPUT);       // Timer1
  pinMode( 11, OUTPUT);      // Timer2
  
  float result = float(F_CPU) / (float(prescalerlist[myIndex]) * (float(myOCR) + 1.0) * 2.0);
  Serial.print( "result: ");
  Serial.print( result, 4);
  Serial.println( " Hz");

  // convert the choosen prescaler index to 
  // the bits of the register for the TCCR1B register.
  int prescaler = myIndex + 1;  

  // Set Timer1, pin 9
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = myOCR;
  TCCR1A = _BV(COM1A0);        // OC1A is toggle output
  TCCR1B = _BV(WGM12) | (uint8_t) prescaler;  // ctc mode

  // Convert the prescaler even more, for the bits
  // of the TCCR2B register
  prescaler += (prescaler / 3) + (prescaler / 4);

  // Set Timer2, pin 11
  TCCR2A = 0;
  TCCR2B = 0;
  TCNT2 = 0;
  OCR2A = myOCR;
  TCCR2A = _BV(WGM21) | _BV(COM2A0); // ctc mode, OC2A is toggle output
  TCCR2B = (uint8_t) prescaler;      // start
}

void loop() {}

D0D1D2D3D4D5D6D7GNDLOGIC