Shop OBEX P1 Docs P2 Docs Learn Events
Interrupt rate "Trick" — Parallax Forums

Interrupt rate "Trick"

BeanBean Posts: 8,129
edited 2008-02-14 17:58 in General Discussion
I came up with this trick. It's really useful when you need exact interrupt rates.

' Interrupt Rate Trick
DEVICE SX28, OSCHS2, TURBO, STACKX, OPTIONX
FREQ   78_750_000
 
' Define pins
UnusedRA  PIN RA INPUT PULLUP
UnusedRB  PIN RB INPUT PULLUP
UnusedRC  PIN RC INPUT PULLUP
 
FreqPin   PIN RB.0 OUTPUT
 
 
' Define variables
' None
 
 
' *** Interrupt rate "trick" ***
' The oscillator is 78.750 MHz or 22 times the colorburst.
' We want exactly 228 colorburst times per line.
' So 228 * 22 = 5016 <- We want to interrupt every 5016 clocks
' We must use a prescaler of 1:32
' 156 * 32 = 4992 clocks
' 157 * 32 = 5024 clocks
'
' Hmmm, how can we get the interrupt rate to be exactly 5016. think...think...think (taps head)
'
' Well the prescaler counts from 0 to 31 then overflows back to zero and increments RTCC,
'  and writing a value to RTCC will reset the prescaler to zero (this is the "trick")
'
' So if we wait until the prescaler is 24, then reset it back to zero,
'  we will add 24 cycles to NEXT interrupt period
'
' If you look at this code, at exactly 23 cycles into the interrupt we do a "CLR RTCC",
'  RTCC is already zero, but this has the effect of clearing the prescaler back to zero.
'

' NOTE: If the prescaler is set to 8,16,32,64,128 or 256, the instruction that modifies RTCC is 1 count
'       If the prescaler is set to 1, the instruction that modifies RTCC is 3 counts
'       If the prescaler is set to 2 or 4, the instruction that modifes RTCC is 5 counts
'
' For low prescale values you will have to either set RTCC to a value, or adjust your RETURNINT value.
'
'
'======================================================================================== 
' Interrupt routine (occurs every 5016 clocks, or 15699.73 times a second) 

INTERRUPT NOPRESERVE '(4) <- cycle count
ASM
  JMP $+1         ' (3=7)
  JMP $+1         ' (3=10)
  JMP $+1         ' (3=13)
  JMP $+1         ' (3=16)
  JMP $+1         ' (3=19)
  JMP $+1         ' (3=22)
  NOP             ' (1=23)
  CLR RTCC        ' (1=24) This will reset the prescaler, making the next interrupt take 24 cycles longer
 
  ' Generate a pulse to count
  SETB FreqPin
  MOV FSR,#$FF
  DJNZ FSR,$
  CLRB FreqPin
ENDASM
RETURNINT 156

 
 
PROGRAM Start NOSTARTUP
 
 
Start:
  OPTION = $84 ' Set prescaler to 1:32
  DO
  LOOP
END
 


Bean.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
www.iElectronicDesigns.com



Post Edited (Bean (Hitt Consulting)) : 2/13/2008 2:07:13 PM GMT

Comments

  • pjvpjv Posts: 1,903
    edited 2008-02-12 16:53
    Hi Bean;

    Something you may not be aware of because it's not really dealt with in the SX documentation, and that is anytime you do a write, or read-modify-write, to the RTCC, it "eats" 3 clock cycles. So if your trick writes to the RTCC - and I suspect CLR RTCC might fall into that category but needs to be confirmed- then you need to account for those 3 cycles.

    And in testing this, please be careful, as the debug IDE will not show the proper count....... if I recall correctly, it is out by one.

    Cheers,

    Peter (pjv)
  • BeanBean Posts: 8,129
    edited 2008-02-12 17:36
    Peter,
    · I've never heard that. Is it documented anywhere ?
    · I'll have to do some experiments (Whhhaaa, hhhaaa, hhaaa) [noparse][[/noparse]thunder clap].

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.iElectronicDesigns.com



    Post Edited (Bean (Hitt Consulting)) : 2/12/2008 5:45:55 PM GMT
  • BeanBean Posts: 8,129
    edited 2008-02-12 18:55
    Peter,
    · Okay I see what you mean. When you modify RTCC the next 3 instructions don't increment RTCC.

    · BUT it seems that if you have prescaler set to 1:8 or higher (1:16, 1:32:, etc), then the instructions DO increment the prescaler (I guess because there won't be a problem with the RTCC value in the pipeline).

    · If the prescaler is set to 1:4 or lower (1:2, 1:1), then the next 3 instructions DO NOT increment the prescaler (I guess because there could be a problem with RTCC value changing in the pipeline).

    ··That is why my example worked because I had the prescaler set to 1:32.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.iElectronicDesigns.com

    ·
  • BeanBean Posts: 8,129
    edited 2008-02-13 14:10
    Okay by experiments here is what is works out to be:

    If the prescaler is 1:8 or higher, the instruction that modifes RTCC is one count.

    If the presclaer is 1:1, the instruction that modifies RTCC is three counts.

    If the prescaler is 1:2 or 1:4, the instruction that modifes RTCC is five counts.

    Seems weird, but that is how it works in my experiments. What I did was get the interrupt rate to be the same when I modifed RTCC and when I didn't. If the resulting rate was the same, the calculation must be correct.

    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.iElectronicDesigns.com

    ·
  • dkemppaidkemppai Posts: 315
    edited 2008-02-14 02:36
    pjv said...
    Hi Bean;

    Something you may not be aware of because it's not really dealt with in the SX documentation, and that is anytime you do a write, or read-modify-write, to the RTCC, it "eats" 3 clock cycles. So if your trick writes to the RTCC - and I suspect CLR RTCC might fall into that category but needs to be confirmed- then you need to account for those 3 cycles.

    And in testing this, please be careful, as the debug IDE will not show the proper count....... if I recall correctly, it is out by one.

    Cheers,

    Peter (pjv)
    This my version of modifying the RTCC time...
    mov RTCC,#47 ;Sets RTCC Cycles = ((255 - x) +3 +3 +3) 
    ;Where x is (mov RTCC,#x) 
    ;for x = #47, RTCC happens every 217 
    

    I've experimentally found that the interrupt taks 3 cycles in, 3 cycles out, and there are 3 more lost in the confusion. I measured the time on an o-scope...·· ...and adjust my math accordingly. It also took a while to figure out what was going on. Of course I wasn't using a prescaler on anything here·[noparse];)[/noparse]

    -Dan




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

    "A saint-like quantity of patience is a help, if this is unavailable, a salty vocabulary works nearly as well." - A. S. Weaver
  • pjvpjv Posts: 1,903
    edited 2008-02-14 16:34
    Hi Dan;

    When dealing with interrupts, and NOT directly messing with the RTCC, it takes 3 cycles to get in, and 3 cycles to get out. Under those circumstances, never have I experienced any cycles lost "in the confusion". That said, when the RTCC is directly accessed by a write, or a read-modify-write, (but not with a mov w,RTCC) then several (three as I recall) cycles are not counted in the RTCC. No confusion here. As stated previously this is without the use of a pre-scaler.

    Bean's discoveries are quite interesting, and I'll have to make some tests on that so that I can fully appreciate his comments.

    There is some confusion as to what the IDE indicates as the value of RTCC while in interrupt in DEBUG. I believe the count is out by one.

    Cheers,

    Peter (pjv)
  • BeanBean Posts: 8,129
    edited 2008-02-14 17:58
    Peter,
    · Yes the real point of the trick is that you can have the prescaler set to 1:32 (or whatever), and have interrupts generated with 1 cycle resolution instead of 32 cycle resolution.

    · Here are the programs I used to determine the cycles lost with the prescaler. You connect the FreqPin to a frequency counter. You should get the same frequency on the counter if the "MOV RTCC,W" line is commented out or not. Because either way RTCC will be 3, and the prescaler will be cleared.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.iElectronicDesigns.com
Sign In or Register to comment.