setting up o/p compare within input capture code

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

setting up o/p compare within input capture code

1,395 Views
stevec
Contributor III
Hi,
New to this board so hope someone can help
I wish to capture an input pulse (of time t1)on channel 0 and on the leading edge input capture interrupt routine set up channel 1 as an output compare to set PA3 low when a predetermined time (t2)has passed. I need the output compare on ch.1 to generate an interrupt so that I can write a new value (t1 + t2)into the compare registers so that it generates an interrupt when the new compare value is reached(so that I can cancel any further compare functions till the next i/p pulse). All I am trying to do is duplicate the i/p pulse on PA2, on PA3 after a delay of a few mS. It is possible that these pulses may overlap at times so I need the timer counter to be running without reset at least until the end of the i/p pulse.

I have tried various scenarious all of which seem sound but which fail to generate an interrupt after I set up the initial output compare from within the i/p capture interrupt routine. I have tried setting this up from within the main body of the code and this appears to work.I am just having problems doing it from with the ch0 i/p capture interrupt code.
Can someone give me some pointers on this as I am slowly going mad over this. Maybe there is a pulse delay routine somewhere. It cant be that difficult can it?
I am using the HC908KX8 and writing in assembler.

Steve
Labels (1)
0 Kudos
3 Replies

285 Views
bigmac
Specialist III
Hello Steve,
 
If you are trying to delay the input pulses by a predetermined number of bus cycles, you would need to consider both positive and negative edges as separate time events.  Can I assume that the maximum required delay is less than the timer overflow period - the situation will be much simpler if so?  You will also need to determine how many time events may occur during the maximum delay period - I assume that this is more than one.  A FIFO (circular) buffer will be needed to hold the timer value for each input event.
 
Input capture ISR processing would be as follows:
  1. Read timer channel register
  2. Add required delay value, ignoring carry bit
  3. Write modified value to buffer
  4. Toggle the polarity bit for the next input capture state
  5. Enable output compare interrupt
Output compare ISR processing would be as follows:
  1. Read next value from the buffer
  2. If buffer is empty disable further output compare interrupts and exit
  3. Write the next timer value to the channel register
  4. Toggle the polarity bit for the next output compare state
Note that the ISR processing cycles will determine the minimum delay value allowed - sufficient to allow update of the output compare value prior to the event time being reached.  You would need to take into account the time required by all other interrupt sources.
 
Within the timer overflow ISR you could also check whether the buffer was empty, and if so, ensure that the output state matched the input state, to correct for any glitches.
 
Regards,
Mac
 
 
 
0 Kudos

285 Views
stevec
Contributor III
Thanks for the reply.
The delay is well within one max timer period (1 uS resolution). There will only be one event, i.e one pulse in one pulse out, about every 100mS.
I have the input capture routine sorted which measures the i/p pulse width. I did find it odd that I had to have the timer running (TSTOP = 0) to get the i/p capture edge detect interrupt to work. I had planned to reset and start the timer when the first edge occurred, enable ch.1 output compare interrupt with the delay period set. I couldn't get the output compare interrupt to work though. Will try again tonight.
 
Steve
0 Kudos

285 Views
bigmac
Specialist III
Hello Steve,
 
I suspect that there may be some misunderstanding about the operation of the TIM module.  The timer needs to run continuously for proper operation.  To delay a pulse by a predetermined period does not normally involve the calculation of pulse width (although it can be done if this data is required).  The simpler way is to treat each input pulse as having two time events, corresponding to the leading edge and the trailing edge.  So it is really only a question of applying the same delay to each edge.
 
In my previous post, I described a more general situation where multiple events could occur within the delay period, and a circular buffer would be necessary.  However, for the case you seem to have, and assuming that the pulse width is less than the delay period, there would actually be only two input capture events, one for each edge of the pulse.  The delayed value for the first event could be written immediately to the timer channel register used for output compare, but the delayed value for the second event would need to be temporarily stored until after the first output compare event has occurred, before being written to the channel register.
 
Revised input capture ISR processing would be as follows:
  1. Read timer channel register
  2. Add required delay value, ignoring carry bit
  3. If current pulse edge is positive {
    Set next input capture for negative edge
    Write modified value to output compare channel register
    Set next output compare for high state
    Enable output compare channel interrupt
    }
    else {
    Set next input capture for positive edge (ready for next pulse)
    Write modified value to a temporary register
    }
Revised output compare ISR processing would be as follows:
  1. Read value from the temporary register and write this to the output compare channel register
  2. Set next output compare for low state
  3. Disable further output compare interrupts

With this arrangement, for each input pulse, the input capture ISR would execute twice, and the output compare ISR once only.  Should you have further difficulty getting this concept to work, you will need to post your code for initialisation of the timer, and the two ISR routines.

Regards,
Mac

 

0 Kudos