Hello Zorrotz,
I might have thought that the latency prior to the execution of the interrupt pin ISR would be equally problematic, as the restoral of PWM operation. I have no idea of your PWM frequency, duty cycle range, bus frequency, and what sort of delays you can tolerate. However, I can see some problems with your current approach. I assume that your interrupt event is asynchronous relative to the PWM waveform.
- After you alter the TPM1C0V setting to an indeterminate value, you do not restore the previous value prior to the next PWM cycle. Without restoral, the following PWM duty will be unknown.
- I would have expected that you would wait, within the ISR, until the compare event had occurred, and only then would have restored PWM operation.
- It is potentially possible for the compare value in TPM1C0V to exceed the value in TPM1MOD register, with the result that the compare event will never occur. It is also evident that, if the delayed TPM1CNT value should exceed the PWM duty value within TPM1C0V, the PWM output will already become inactive, and no compare event would be necessary. This test would also help alleviate the other problem, provided the PWM duty does not exceed a maximum limit somewhat less than 100 percent.
Within the ISR, the following code may overcome these issues. However, the DELAY period may need to be substantially increased from a value of 11. You will need to determine the number of bus cycles between markers (1) and (2). Then divide by the TPM1 prescale setting.
word duty, count;
duty = TPM1COV; // Current PWM duty
// (1)
count = TPM1CNT + DELAY;
if (count < duty) {
TPM1C0SC = 0x1C; // Set output on compare
TPM1C0V = count;
TPM1CSC_CH0F = 0; // Clear flag
// (2)
while (!TPM1C0SC_CH0F); // Wait for compare event
TPM1C0V = duty; // Restore previous value
TPM1C0SC = 0x3C; // Low true PWM mode
// (3)
}
To determine the maximum allowable duty value within TPM1C0V, use the number of bus cycles between markers (1) and (3), again divide by the TPM1 prescale value, and subtract this amount from TPM1MOD.
On a completely different tack, if the uncertain interrupt latency due to the occurrence of other interrupts is too much for your application, you might also consider the use of additional hardware to gate the PWM output, with sub-microsecond latency. For each PWM channel, the additional hardware would consist of a D flip-flop stage (say 'HC74), and a single 2-input NAND gate, i.e. the addition of two packages to cater for both PWM outputs.
Regards,
Mac