Measuring Long Periods via Timer Over-Flow Flag Trick.

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

Measuring Long Periods via Timer Over-Flow Flag Trick.

1,003 Views
seank
Contributor I

I had the following code, which worked just fine before I assigned the over-flow ISR to XGATE. I'm using 800ns ticks.

 

/* code that is part of an IC ISR */    LongTime timeStamp;     /* Install the low word */     timeStamp.timeShorts[1] = edgeTimeStamp;     /* Find out what our timer value means and put it in the high word */     if(TFLGOF && !(edgeTimeStamp & 0x8000)){    /*see 68hc11 ref manual for details */         timeStamp.timeShorts[0] = timerExtensionClock + 1;     }else{         timeStamp.timeShorts[0] = timerExtensionClock;     }     unsigned long thisEventTimeStamp = timeStamp.timeLong; 

 

 

Due to new product requirements, XGATE now handles the timer-overflow ISR as well as some OC ISRs:

xgateTOFISR:     TOFISRSEM:   SSEM #1 ; try to lock semaphore   BCC TOFISRSEM; retry until locked   ;Increment the metronome request to trigger the s12 to run metronome();   LDW R7, metronomeRequestCount   LDW R6, (R7, #0)   ADDL R6, #1   STW R6, (R7, #0)   ;Clear timer overflow interrupt flag   LDL R7, #TFLGOF   LDL R6, #0x80   STB R6, (R7, #0)     CSEM #1 ;Release semaphore   RTS 

and in my NEW  S12 ISR:

 

do {   XGSEM = 0x0202; } while ((XGSEM &= BIT1) == 0);   timeStamp.timeShorts[0] = timerExtensionClock; XGSEM = 0x0200; //Clear semaphore 1 by writing mask=1 and flag=0 

 

 

My problem is that I often get bogus results when I diff the previous time-stamp. It's obvious that there are times when an over-flow is not correctly being accounted for. What's not so obvious is how to solve this.  Any input would be appriciated.

 

Thanks

Labels (1)
0 Kudos
7 Replies

742 Views
seank
Contributor I

Sorry, line:  

LDW R7, metronomeRequestCount should read LDW R7, timerExtensionClock .

I was attempting to create a delay-stage in which s12 had to increment a non-shared variable, which helped quit a bit, but did not work 100% of the time.

Thanks

0 Kudos

742 Views
kef2
Senior Contributor IV

Hi

I don't see a lot of sense in moving such short and very low frequency TOF ISR to XGATE, but I guess you know what are you doing.

It should work with no problems, provided semaphores are locked and released at appropriate times. I don't see whole ISR's and thus can't say whether you do it properly or not. You need to semaphore protect not only accesses to shared variables, but also to timer channel register and timer flags register. It is required to make original HC11 algorithm working. Timer channel and flags registers are kind of indirectly shared variables in original HC11 algorithm...

} while ((XGSEM &= BIT1) == 0); 

                          ^^  looks like you do write access to XGSEM here. But what for?

0 Kudos

742 Views
seank
Contributor I

What I have is one OC channel that generates 24 precision pulse-widths via xgate bit bang code(fuel and ignition controller for gasoline engines). The only method I have thought of to do this, requires immediate servicing of the overflow ISR. I need to retain 1-2 uS accuracy/jitter.  The S12 core does the math required for the correct PW and placement of the PW, then it's xgates job to make sure it all happens in real-time. It's a foss project and I'll post the code soon, in case you or anyone else has any input.

"} while ((XGSEM &= BIT1) == 0);"  Yep, that's one issue,  should be !(XGSEM & BIT1).

I also did not know that register access needed to be protected. Let me correct these two issues and rerun my tests.

Thanks!

0 Kudos

742 Views
kef2
Senior Contributor IV

Measuring long periods (taking more than 2^16 timer ticks) requires using timer overflow interrupt. But you don't need timer overflow interrupt to generate long delays.

Instead of using overflow interrupt, you can use the same output compare channel to count overflows. In ISR you need to update overflow counter and clear timer channel flag and ISR will trigger again after about 2^16 timer ticks.

So to generate for example 0x21234 ticks delay you set up TCx = TCNT + (0x21234 % 0x10000) and execute TCx ISR  0x21234 / 0x10000 = 2 times. Each time ISR is called, you need to clear timer flag and update overflows counter. 2nd (last) time ISR is executed you disable channel interrupt and set up timer pin for proper output compare action on 3rd output compare. So you have 3 OC intervals 0x1234+0x10000+0x10000=0x21234. Simple, but there's one problem. In case ticks % 0x10000 is about or less the interrupt latency limit, you need to do something special. For example you need to generate 0x20015 ticks delay and interrupt latency is say 0x30 or more timer ticks:

Setting TCx = TCNT + 0x15 is a bad idea and won't work. But you may take one overflow interval, add to it this small 0x15 value and divide the sum into two nonequal parts. So instead of setting up TCx = TCNT + 0x15 and executing ISR two times with TCx fixed, you may set TCx = TCNT + 0x8015 and execute ISR again two times, like in 0x21234 case, but changing TCx = TCx + 0x8000 on first ISR call. So you again have 3 OC intervals 0x8015+0x8000+0x10000=0x20015.
I hope above is clear. I'm using this technique a lot to generate jitterless long and short pulses with best possible timer resolution.

0 Kudos

742 Views
seank
Contributor I

Thanks for the tip. I'll rethink some things.  I'm trying to bit-bang 24 individual port pins(channels), sometimes they overlap or occur right next to each other . It's not that I'm trying to generate long periods, I'm trying to use a cheap method to figure out what events are next and which ones may be late. All of that works decently but requires me to handle the overflow interrupt in xgate, which as I stated created a new problem in my S12 IC ISR. Let me see if your suggestions sparks some new ideas. 

On a different note, making those mutex changes did not fix the problem. Here is what almost works(1000x less bogus input capture stamps), but I'm not sure why.

do {
  XGSEM = 0x0202;
} while (!(XGSEM & BIT1));

if(((timerExtensionClock != timerExtensionClockShared) && !(edgeTimeStamp & 0x8000))) {
timeStamp.timeShorts[0] = timerExtensionClock + 1;
}else{

        timeStamp.timeShorts[0] = timerExtensionClock;

    }

XGSEM = 0x0200; //Clear semaphore 1 by writing mask=1 and flag=0

timerExtensionClock, is not a shared variable, it gets updated in an S12 RTI interrupt that runs every 10uS. Why does this work so much better, but not 100% of the time?

void RTIISR(){

  /* Clear the RTI flag */

  CRGFLG = 0x80;

  do {

   XGSEM = 0x0202;

  } while (!(XGSEM & BIT1));

  if (timerExtensionClock != timerExtensionClockShared) {

  metronome();

  }

  XGSEM = 0x0200; //Clear semaphore 1 by writing mask=1 and flag=0

///metronome()

do {

  XGSEM = 0x0202;

  } while (!(XGSEM & BIT1));

  timerExtensionClock = timerExtensionClockShared; // bring s12 timer extension up to date

XGSEM = 0x0200; //Clear semaphore 1 by writing mask=1 and flag=0

Thanks

http://powerefi.com/files/operation.txt

0 Kudos

742 Views
seank
Contributor I

Field Description

7:0 Toggle On Overflow Bits — TOV97:0] toggles output compare pin on timer counter overflow. This feature only

TOV[7:0] takes effect when in output compare mode. When set, it takes precedence over forced output compare but not

        channel 7 override events.

       0 Toggle output compare pin on overflow feature disabled.

        1 Toggle output compare pin on overflow feature enabled.

Does that also trigger the ISR for that timer channel? And if so does it change the contents of the OC register?

Thanks,

Sean

0 Kudos

742 Views
kef2
Senior Contributor IV

No, toggle on overflow doesn't trigger additional OC interrupts and doesn't change contents of TCx registers.

Regarding input capture problems. Measure long time periods algorithm from MC68HC11RM.pdf needs reading input capture timer value and reading timer overflow flag from input capture ISR. I see something in your code verifying the sign or MSB of timer capture value, but where's is a check for overflow flag? 2nd is also important.

0 Kudos