Timer2 not paying attention to me [solved]

Hello everyone! I have an issue that is driving me bonkers. I’ve seen similar and they always boiled down to me modifying registers incorrectly, but I seem to be doing everything right this time! Below is the main sketch, as well as the timerhelpers header which I got from Gammon’s site, but added some stuff for timer3, which is not implemented on my board. I am using a Rev 5 mini which is the 328P uC.

I came across a post saying sometimes the arduino libraries would re-set the registers so stuff done in setup is not always reliable unless called externally, hence the commented out setupTimers(), which did not fix the problem. please halp

main sketch

#include <TimerHelpers.h>

//minimal code to run two steppers
//using timer controlled pin, no ISR
//goes full rev forward and back at hardcoded speed
//uses timers 1 and 2
//          1A  1B           2A  2B
//sanguino: D13 D12        $ D15 D14
//mini:     D9  D10        $ D11 D3
//mega      D11 D12 D13    $ D10 D9

  #ifndef cbi
  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  #endif
  #ifndef sbi
  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
  #endif

  //#define ISR1AMARKER


const byte step1 =  9;  //1A on sanguino = D13
const byte step2 = 11;  //2A on sanguino = D15
const byte dir1  = 10;
const byte dir2  = 12;
const byte enable = 13; //13 on mini in rig
const byte isrFlagPin = 16;
const byte isrIntFlagPin = 17;

const int numSteps1 = 200;
const int numSteps2 = 200;
const int microSteps1 = 2;
const int microSteps2 = 16;

const unsigned int numuSteps1 = numSteps1*microSteps1;
const unsigned int numuSteps2 = numSteps2*microSteps2;

const unsigned int numRot1 = 30;  //max 20 @ 200 ppr & 16 ustep
const unsigned int numRot2 = 10;  //max 327 at 1 ustep

unsigned int uStepsElapsed1 = 0;
unsigned int uStepsElapsed2 = 0;

boolean invertFlag = false;

/*
void setupTimers() {
   // setup stepper 1 on 1A using library
  Timer1::setMode(4, Timer1::PRESCALE_256, Timer1::TOGGLE_A_ON_COMPARE);

  //Timer2::setMode(2, Timer2::PRESCALE_256, Timer2::TOGGLE_B_ON_COMPARE)
  TCCR2A = 0;
  TCCR2B = 0;
  sbi(TCCR2A, WGM21);     // CTC mode WGM=0b010
  sbi(TCCR2A, COM2B0);    // toggle on match COM2 = 0b01
  //  avail 1 8 32 64 128 256 1024, starting 0b001
  sbi(TCCR2B, CS22);
  sbi(TCCR2B, CS21);
  cbi(TCCR2B, CS20);
}
*/

void setup(){
  Serial.begin(19200);
  pinMode(enable, OUTPUT);
  pinMode(dir1, OUTPUT);
  pinMode(dir2, OUTPUT);
  pinMode(step1, OUTPUT);           //sets pin to output
  pinMode(step2, OUTPUT); digitalWrite(step2, HIGH);
  pinMode(isrFlagPin, OUTPUT);
  pinMode(isrIntFlagPin, OUTPUT);
  digitalWrite(step1, HIGH);
  digitalWrite(dir1, HIGH);
  digitalWrite(dir2, HIGH);
  digitalWrite(enable, LOW);  //active low stepper drivers

   // setup stepper 1 on 1A using library
  Timer1::setMode(4, Timer1::PRESCALE_256, Timer1::TOGGLE_A_ON_COMPARE);

  //Timer2::setMode(2, Timer2::PRESCALE_256, Timer2::TOGGLE_B_ON_COMPARE)
  TCCR2A = 0;
  TCCR2B = 0;
  sbi(TCCR2A, WGM21);     // CTC mode WGM=0b010
  sbi(TCCR2A, COM2B0);    // toggle on match COM2 = 0b01
  //  avail 1 8 32 64 128 256 1024, starting 0b001
  sbi(TCCR2B, CS22);
  sbi(TCCR2B, CS21);
  cbi(TCCR2B, CS20);

//  setupTimers();            //must be called to avoid arduino setting values AFTER I do

  OCR1A = 250;
  OCR2A = 50;

  //Enable interrupts
  //sbi(TIMSK1, OCIE1A);
  //sbi(TIMSK2, OCIE2A);}
}

void loop(){
  Serial.print("TCCR2A = ");
  Serial.println(TCCR2A);
  Serial.print("TCCR2B = ");
  Serial.println(TCCR2B);
  Serial.print("OCR2A = ");
  Serial.println(OCR2A);
  Serial.print("TCNT2 = ");
  Serial.println(TCNT2);
  delay(1000);
}

and Gammon’s lovely namespace, wish I had seen it before I wasted a week writing my own which never actually worked lol.

Oh I noticed I never posted what happened. When uploaded, timer 1 does its thing and pulses the pin attached to pin 9 happily (timer1) but pin 11 timer2 just sits high.

timerhelpers.h

/*
 Timer Helpers library.

Devised and written by Nick Gammon.
Date: 21 March 2012
Version: 1.0

Licence: Released for public use.

See: http://www.gammon.com.au/forum/?id=11504

 Example:

 // set up Timer 1
 TCNT1 = 0;         // reset counter
 OCR1A =  999;       // compare A register value (1000 * clock speed)

 // Mode 4: CTC, top = OCR1A
 Timer1::setMode (4, Timer1::PRESCALE_1, Timer1::CLEAR_A_ON_COMPARE);

 TIFR1 |= _BV (OCF1A);    // clear interrupt flag
 TIMSK1 = _BV (OCIE1A);   // interrupt on Compare A Match

*/

#ifndef _TimerHelpers_h
#define _TimerHelpers_h

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

/* ---------------------------------------------------------------
 Timer 0 setup
 --------------------------------------------------------------- */
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)

namespace Timer0
{
  // TCCR0A, TCCR0B
  const byte Modes [8] [2] =
  {

  { 0,                         0 },            // 0: Normal, top = 0xFF
  { _BV (WGM00),               0 },            // 1: PWM, Phase-correct, top = 0xFF
  {               _BV (WGM01), 0 },            // 2: CTC, top = OCR0A
  { _BV (WGM00) | _BV (WGM01), 0 },            // 3: Fast PWM, top = 0xFF
  { 0,                         _BV (WGM02) },  // 4: Reserved
  { _BV (WGM00),               _BV (WGM02) },  // 5: PWM, Phase-correct, top = OCR0A
  {               _BV (WGM01), _BV (WGM02) },  // 6: Reserved
  { _BV (WGM00) | _BV (WGM01), _BV (WGM02) },  // 7: Fast PWM, top = OCR0A

  };  // end of Timer0::Modes

  // Activation
  // Note: T0 is pin 6, Arduino port: D4
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_64, PRESCALE_256, PRESCALE_1024, T0_FALLING, T0_RISING };

  // what ports to toggle on timer fire
  enum { NO_PORT = 0,

    // pin 12, Arduino port: D6
    TOGGLE_A_ON_COMPARE  = _BV (COM0A0),
    CLEAR_A_ON_COMPARE   = _BV (COM0A1),
    SET_A_ON_COMPARE     = _BV (COM0A0) | _BV (COM0A1),

    // pin 11, Arduino port: D5
    TOGGLE_B_ON_COMPARE  = _BV (COM0B0),
    CLEAR_B_ON_COMPARE   = _BV (COM0B1),
    SET_B_ON_COMPARE     = _BV (COM0B0) | _BV (COM0B1),
  };


  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 7)  // sanity check
    return;

  // reset existing flags
  TCCR0A = 0;
  TCCR0B = 0;

  TCCR0A |= (Modes [mode] [0]) | port;
  TCCR0B |= (Modes [mode] [1]) | clock;
  }  // end of Timer0::setMode

}  // end of namespace Timer0

/* ---------------------------------------------------------------
 Timer 1 setup
 --------------------------------------------------------------- */

namespace Timer1
{
  // TCCR1A, TCCR1B
  const byte Modes [16] [2] =
  {

  { 0,                         0 },            // 0: Normal, top = 0xFFFF
  { _BV (WGM10),               0 },            // 1: PWM, Phase-correct, 8 bit, top = 0xFF
  {               _BV (WGM11), 0 },            // 2: PWM, Phase-correct, 9 bit, top = 0x1FF
  { _BV (WGM10) | _BV (WGM11), 0 },            // 3: PWM, Phase-correct, 10 bit, top = 0x3FF
  { 0,                         _BV (WGM12) },  // 4: CTC, top = OCR1A
  { _BV (WGM10),               _BV (WGM12) },  // 5: Fast PWM, 8 bit, top = 0xFF
  {               _BV (WGM11), _BV (WGM12) },  // 6: Fast PWM, 9 bit, top = 0x1FF
  { _BV (WGM10) | _BV (WGM11), _BV (WGM12) },  // 7: Fast PWM, 10 bit, top = 0x3FF
  { 0,                                       _BV (WGM13) },  // 8: PWM, phase and frequency correct, top = ICR1
  { _BV (WGM10),                             _BV (WGM13) },  // 9: PWM, phase and frequency correct, top = OCR1A
  {               _BV (WGM11),               _BV (WGM13) },  // 10: PWM, phase correct, top = ICR1A
  { _BV (WGM10) | _BV (WGM11),               _BV (WGM13) },  // 11: PWM, phase correct, top = OCR1A
  { 0,                         _BV (WGM12) | _BV (WGM13) },  // 12: CTC, top = ICR1
  { _BV (WGM10),               _BV (WGM12) | _BV (WGM13) },  // 13: reserved
  {               _BV (WGM11), _BV (WGM12) | _BV (WGM13) },  // 14: Fast PWM, TOP = ICR1
  { _BV (WGM10) | _BV (WGM11), _BV (WGM12) | _BV (WGM13) },  // 15: Fast PWM, TOP = OCR1A

  };  // end of Timer1::Modes

  // Activation
  // Note: T1 is pin 11, Arduino port: D5
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_64, PRESCALE_256, PRESCALE_1024, T1_FALLING, T1_RISING };

  // what ports to toggle on timer fire
  enum { NO_PORT = 0,

    // pin 15, Arduino port: D9
    TOGGLE_A_ON_COMPARE  = _BV (COM1A0),
    CLEAR_A_ON_COMPARE   = _BV (COM1A1),
    SET_A_ON_COMPARE     = _BV (COM1A0) | _BV (COM1A1),

    // pin 16, Arduino port: D10
    TOGGLE_B_ON_COMPARE  = _BV (COM1B0),
    CLEAR_B_ON_COMPARE   = _BV (COM1B1),
    SET_B_ON_COMPARE     = _BV (COM1B0) | _BV (COM1B1),
  };

  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 15)  // sanity check
    return;

  // reset existing flags
  TCCR1A = 0;
  TCCR1B = 0;

  TCCR1A |= (Modes [mode] [0]) | port;
  TCCR1B |= (Modes [mode] [1]) | clock;
  }  // end of Timer1::setMode

}  // end of namespace Timer1

/* ---------------------------------------------------------------
 Timer 2 setup
 --------------------------------------------------------------- */

namespace Timer2
{
  // TCCR2A, TCCR2B
  const byte Modes [8] [2] =
  {

  { 0,                         0 },            // 0: Normal, top = 0xFF
  { _BV (WGM20),               0 },            // 1: PWM, Phase-correct, top = 0xFF
  {               _BV (WGM21), 0 },            // 2: CTC, top = OCR2A
  { _BV (WGM20) | _BV (WGM21), 0 },            // 3: Fast PWM, top = 0xFF
  { 0,                         _BV (WGM22) },  // 4: Reserved
  { _BV (WGM20),               _BV (WGM22) },  // 5: PWM, Phase-correct, top = OCR2A
  {               _BV (WGM21), _BV (WGM22) },  // 6: Reserved
  { _BV (WGM20) | _BV (WGM21), _BV (WGM22) },  // 7: Fast PWM, top = OCR2A

  };  // end of Timer2::Modes

  // Activation
  enum { NO_CLOCK, PRESCALE_1, PRESCALE_8, PRESCALE_32, PRESCALE_64, PRESCALE_128, PRESCALE_256, PRESCALE_1024 };

  // what ports to toggle on timer fire
  enum { NO_PORT = 0,

    // pin 17, Arduino port: D11
    TOGGLE_A_ON_COMPARE  = _BV (COM2A0),
    CLEAR_A_ON_COMPARE   = _BV (COM2A1),
    SET_A_ON_COMPARE     = _BV (COM2A0) | _BV (COM2A1),

    // pin 5, Arduino port: D3
    TOGGLE_B_ON_COMPARE  = _BV (COM2B0),
    CLEAR_B_ON_COMPARE   = _BV (COM2B1),
    SET_B_ON_COMPARE     = _BV (COM2B0) | _BV (COM2B1),
  };


  // choose a timer mode, set which clock speed, and which port to toggle
  void setMode (const byte mode, const byte clock, const byte port)
  {
  if (mode < 0 || mode > 7)  // sanity check
    return;

  // reset existing flags
  TCCR2A = 0;
  TCCR2B = 0;

  TCCR2A |= (Modes [mode] [0]) | port;
  TCCR2B |= (Modes [mode] [1]) | clock;
  }  // end of Timer2::setMode

}  // end of namespace Timer2


/* ---------------------------------------------------------------
 Timer 3 setup
 --------------------------------------------------------------- */
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)

===============================
removed due to space limitation in forum
===============================
===============================
}  // end of namespace Timer2
#endif

#endif
#endif

as is always the case, within 10 minutes of posting I find my problem, 4 hours after I started my diagnosis (lunch break included). Shockingly, OC1A != OC1B...

nothing to see here, carry one