MC9S08JM60 Non-linear Output Compare frequency scaling

Question asked by Alexander Baum on Jan 13, 2017
Latest reply on Jan 24, 2017 by Michael Fugere

I'm intending to use the output of the TMP2CH0, PTF2, as the sampling frequency for an external ADC.  I would like to have really accurate control over the frequency going into the ADC.  What I've noticed is that as I change the MOD value, the frequency of the Output Compare changes non-linearly.  Here are the values I've tested in the TPM2MODH:L:

Value            Output Frequency

0x0001            375 kHz

0x00F0            3.11 kHz

0x00FF            2.93 kHz

0x0FFF            183.101 Hz

0xFFFE            11.5 Hz

And here is the code that I used to generate it:

void initializeClock(void)
{
/* Set:
* BDIV to Divide by 1 (%00)
* RANGE to 1 because it is High Frequency (%1)
* HGO to 1 for high-gain operation (%1)
* EREFS to 1 to use crystal (%1)
* ERKCLKEN to 1 to ensure the external reference clock is active(%1)
*
* 0b00110110 */
MCGC2 = 0x36;

// Wait for OSCINIT to be set;
while((MCGSC & 0x02) == 0x00);
DisableInterrupts;

/* Set:
* CLKS to select external reference clock (%10);
* RDIV to divide-by-128 (%111)
* IREFS to select external reference clock (%0);
*
* 0b10111000 */
MCGC1 = 0xB8;

// Loop until IREFST is cleared and CLKST indicates external clk src slected;
while(MCGSC_IREFST == 1);
while(MCGSC_CLKST != 2);

// Set LP bit to enter BLPE mode. This is essential when oscillator > 5 MHz;
MCGC2 = 0x3E;

// Set RDIV to divide by 8 to get 1.5 MHz reference;
MCGC1 = 0x98;

/* Set:
* PLLS to select the PLLS (%1)
* VDIV to multiply by 32 (%1000)
*
* 0b01001000 */
MCGC3 = 0x48; //Set to Multiply 1.5 reference by 32 for 48 MHz;
while(MCGSC_PLLST == 0);

MCGC2_LP = 0;
while(MCGSC_LOCK == 0);

MCGC1 = 0x18; // Set MCGC1 CLKS bits to select the output of the PLL;
while(MCGSC_CLKST != 3);
}

void initializeTPM2(void)
{
TPM2SC_TOIE = 1; // Enable the interrupt;
TPM2SC_CPWMS = 0; // Allow it to operate in output compare;
TPM2SC_CLKSB = 0; // Select Bus Rate Clock for source;
TPM2SC_CLKSA = 1;
TPM2SC_PS = 0x4; // Select divide-by-4 to give us a 12 MHz output;

TPM2C0SC_CH0IE = 1; // Enable interrupts from this channel;

TPM2C0SC_MS0B = 0; // Set the channel mode to output compare;
TPM2C0SC_MS0A = 1;

TPM2C0SC_ELS0B = 0; // Set to toggle output on compare;
TPM2C0SC_ELS0A = 1;
TPM2MODH = 0x01; // This value gets me to to my target of 2 kHz;
TPM2MODL = 0x75;
}

Quite frankly this is my first time using the 8-bit Freescale/NXP uC's so I'm not even particularly sure that my clock is running at the intended speed of 48 MHz.  Is this normal operation for the Output Compare module?