Hello JR,
I will briefly attempt to describe the basic operation ot the TPM module, hopefully to clear up some of the confusion.
The module consists of a 16-bit counter that runs continuously during normal operation. Whenever the count value reaches the value contained within TPM1MOD, an overflow event occurs, and the counter will begin counting from zero at the next (prescaled) timer clock. The overflow will generate an interrupt if the TOIE bit within the TPM1SC register is set. The TOF flag within the same register will be set, whether or not the interrupt is enabled.
Even if you are not specifically using the TPM overflow facility, the TPM1SC register also controls the pre-scaler setting and the clock source selection, so will usually need to be initialized. Many applications may leave the TPM1MOD setting at the reset default setting, for a full 16-bit count.
Associated with the TPM are a number of "channels" that operate quite independently of the timer overflow, but their operation will be affected by the TPM1MOD setting. Each channel may be configured for one of the operating modes,
1) Input capture, or
2) Output compare with hardware output, or
3) Output compare, interrupt only, or
4) PWM operation, either edge aligned or centre aligned.
If the meaning of any of these operations is unclear, perhaps you should re-read the relevant paragraphs in the data sheet. For channel 0, the mode of operation is controlled by the TPM1C0SC register. If none of these operating modes are needed, the register can remain at the default setting.
An interrupt vector is provided for each channel, and a separate vector for overflow interrupts.
To provide a timeout delay as you require, the method used will depend on the length of the delay, and the accuracy required for the delay. The output compare method can be very accurate, especially for a hardware output, but becomes more complex if the required delay exceeds the overflow period.
If the required delay is quite long, and is many times the overflow period, a very simple method is to count the number of overflows. If the timer runs continuously, and is not reset, the timing uncertainty will be one overflow period.
I suspect that, for your specific application, high accuracy is not a requirement, and since you have a prescale division of 128, the second method may suffice if you were to reduce the prescale setting to 1.
word Tcount = 0; /* Global variable */
void TPM_Init(void)
{
TPM1SC = 0x50; /* prescale = 1, fixed system clock,
Overflow interrupt enabled */
}
void SetTimeout( word val)
{
Tcount = val; /* Multiple of TPM overflow period */
}
interrupt void TPM_Overflow_ISR(void)
{
TPM1SC_TOF = 0; /* Clear overflow flag */
if (Tcount) {
Tcount--;
if (Tcount == 0) {
/* Do timeout stuff */
}
}
}
If the action required on timeout is complex and lengty, it is probably not a good idea to execute within the ISR code. The alternative is, within main() or an associated function, to periodically poll the value of Tcount. When it reaches zero, the value will remain at zero to indicate that timeout has occurred.
Regards,
Mac