Hello,
My previous response was badly worded. The unorthodoxy that I was referring to was not the modification of the registers from within the ISR, but the stopping, starting and clearing of the TPM counter, and the changing of the TPMMOD value - it is usually possible to avoid these. The reason they should generally be avoided is they affect all channels of the TPM module, and may prevent the use of spare channels for other purposes.
For the case of TPM2, with only a single channel, this issue is probably not of importance, but I was alluding to the fact that there is an alternative way of handling the timing that avoids the issue. I did not mean to imply that your method could not be made to work, and had any bearing on your current problem.
The alternative method in more detail -
Within the TPM1 channel (input capture) ISR:
TPM2C0SC = 0x50; // Software output compare interrupt
TPM2C0V = TPM2CNT + 0x7000; // Setup timeout period
TPM2C0SC_CH0F = 0; // Clear flag (if set)
When timeout occurs, a TPM2 channel 0 interrupt would take place. Within this ISR:
TPM2C0SC = 0x00; // Disable output compare mode
TPM2C0SC_CH0F = 0; // Clear flag
Your input capture ISR code might then become something like the following -
#define RESET 0
byte i;
word store[70];
interrupt 6 void TPM1C1_ISR (void)
{
//TPM1C1SC; Unnecessary for flag clearing
TPM1C1SC_CH1F = RESET; Clear flag
if (i == 70) {
//TPMC1SC_CH1IE = RESET;
//TPMCNT=0;
//TPMSC=0x00;
TPM1C1SC = 0x00; // Disable input capture operation
TPM2C0SC = 0x00; // ?? Disable output compare operation
}
else if (i > 1) { // I presume this is what is really intended
//if (i > 1 ) {
//TPM2SC=0x00; //Stop Timer2 or Stop timeout timer
store[i] = TPM1C1V; // Simpler to handle a word value
//store[i].period[0]=TPMC1VH;
//store[i].period[1]=TPMC1VL;
TPM2C0SC = 0x50; // Software output compare interrupt
TPM2C0V = TPM2CNT + 0x7000; // Setup timeout period 86ms
TPM2C0SC_CH0F = 0; // Clear flag (if set)
//TPM2MOD = 0x7000; //Timeout of 86msec.
//TPM2SC = 0x4D; //Restart Timer
i++; // May be better placed here
}
//TPMCNT = 0;
//i++;
}
One other point about input capture operation - it may be more reliable to capture on a single edge at a time, rather than both edges. This may prevent phasing errors occurring in the event of spurious interrupts - you will always be assured of the edge polarity that each capture event represents. During the input capture ISR simply toggle to the opposite edge for the next event.
Regards,
Mac