Hi Robin.
Thanks for your interest.
You are right. But in reality the main purpose of this timer it's to generate a slow pwm frequency on channel 1.
So, I have to keep the MOD register at the desidered period. Usually it's 8 hz. (about 46875 value at 187,5 Khz).
But I wanted to use the same timer to get a 1 ms tick on another output.
Below, I send the total code that I'm using now, so may be more clear for you.
As I wrote the strange thing is at the beginning it works fine and properly. I can see the output toggle every 1ms (500 hz frequency) but suddendly afeter 250ms - 300 ms the TPM0 interrupt is no longer call.
Thanks
Attilio
void InitTimers(void)
{
float bus_tick, frequency, period, duty;
UINT8 duty_cycle;
/* TIMER 0 channels setting */
GetLampParameters(&frequency, &duty_cycle);
bus_tick = (1.0 / (BUSCLOCK / Power(2, 0x07)));
period = (1.0 / frequency) / bus_tick;
duty = (period / 100) * duty_cycle;
SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK; // clock gating
SIM->SOPT2 |= SIM_SOPT2_TPMSRC(0x10); // tpm clock source
TPM0->SC = 0x00UL;
TPM0->SC |= TPM_SC_PS(0x07); // prescaler divide 0x07 = 128 times
TPM0->SC |= TPM_SC_CMOD(0x01); // tpm increment every tpm counter clock
TPM0->MOD = (UINT32)period; // timer period
// channel 1 setting
TPM0->CONTROLS[TPM_CHANNEL_1].CnV = (UINT32)duty; // timer duty cycle
TPM0->CONTROLS[TPM_CHANNEL_1].CnSC = PWM_EDGE_ALIGN_HIGH_PULSE; // pwm - no CHIE
PORTA->PCR[4] = PORT_PCR_MUX(ALTERNATE_FUNCTION_3); // PTA4 wired to manage lamp
// channel 2
TPM0->CONTROLS[TPM_CHANNEL_2].CnSC = OUT_COMPARE_TOGGLE +\
TPM_CnSC_CHIE_MASK; // ch2 - out.comp. - CHIE request
TPM0->CONTROLS[TPM_CHANNEL_2].CnV = 375; // first match after ~2ms
PORTA->PCR[5] = PORT_PCR_MUX(ALTERNATE_FUNCTION_3); // PTA5 wired to lamp
ConnectInterruptToCortex(TPM0_IRQn); // set TPM0 interrupt
}
void TPM0_IRQHandler(void)
{
UINT32 status;
UINT16 l;
static UINT8 break_test;
status = TPM0->STATUS;
// OVERFLOW
if(status & TPM_OVERFLOW_COUNTER)
{
break_test = 1;
}
// CH0
if(status & TPM_CH0_FLAG)
{
break_test = 1;
}
// CH1
if(status & TPM_CH1_FLAG)
{
break_test = 1;
}
// CH2
if(status & TPM_CH2_FLAG)
{
l = TPM0->CNT;
l = l + 375;
TPM0->CONTROLS[TPM_CHANNEL_2].CnV = (UINT32)l;
}
// CH3
if(status & TPM_CH3_FLAG)
{
break_test = 1;
}
// CH4
if(status & TPM_CH4_FLAG)
{
break_test = 1;
}
// CH5
if(status & TPM_CH5_FLAG)
{
break_test = 1;
}
TPM0->STATUS |= status;
}