Hello Steve,
1. Immediately following the input capture event, TPM channel 0 reverts to software only compare mode, to be used for the data window timing. This means that the TPM module no longer has control of the channel pin, an it will revert to GPIO. Thus, this pin should be initalised as an input, maybe with pullup enabled. I suspect the pin may be currently initialised as a low output state. At the conclusion of the output pulse at channel 1, channel 0 will revert to input capture operation, so the TPM module will again take control of the pin.
2. The channel 1 interrupt handler controls the output pulse width, and I think I can see a potential problem. When a compare interrupt occurs it needs to be tested whether it is the first or the second interrupt in the sequence. If the first compare interrupt, the output pulse timing is set, otherwise further interrupts are disabled, and the channel initialisation state is resumed (all further compares will give a low pulse output state). The test is as follows -
if (TPM1C1SC == 0x5C) { // Output pulse currently high
Of course, I did not allow for the channel flag being set at this point within the ISR, so the test value should actually be 0xDC for the correct branch to be taken on the first interrupt.
The function set_delay() attempts to provide the data window monitoring. This would be called as a result of the SCI processing to obtain the variable delay data.
// Global variables:word tstart;void set_delay( word value){ DisableInterrupts; if (TPM1C0SC == 0x10) { // Compare mode & flag is clear TPM1C1SC = 0x5C; // Set o/p on next compare, int. enabled TPM1C1V = tstart + value; // Set delay period } else { // Outside data timing window TPM1C0SC = 0x48; // Revert to input capture mode TPM1C0SC_CH0F = 0; // Clear flag } TPM1C1SC_CH1F = 0; // Clear flag EnableInterrupts;}The test for software output compare mode is current, and the channel flag is clear (window timeout has not yet occurred) results in the variable delay being set. Otherwise, we revert to input capture mode ready for the next input pulse. It is at this point you may require to add some code to report the window timing error.
A possible circumstance that may still be a problem would be if the serial data never arrived, and set_delay() was never called. So perhaps an alternaltive way of handling the data timing window would be to enable interrupts for the software compare operation, and modify the channel 0 ISR code. If an output compare interrupt should occur, then revert to input capture mode, and set a global flag variable. The set_delay() function could then test for the global flag currently set (since the TPM channel flag would have been cleared within the ISR).
Regards,
Mac