Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: Timer 1 cycle problems

  1. #1
    Junior Member
    Join Date
    Mar 2017
    Posts
    6

    Timer 1 cycle problems

    Hello,

    I'm trying to get Timer1 running as I want it. I'm using PIT but the frequency of the timer seems to be too slow. Does someone know on what frequency the Bus Clock runs?
    I'm trying to get an interrupt every 31.25ns (3 cycles at 96MHz).

    Code:
    char CLKout = 2;
    
    void setup() {
      pinMode(CLKout, OUTPUT);
      
      SIM_SCGC6 |= SIM_SCGC6_PIT;
      PIT_MCR = 0x00;
      NVIC_ENABLE_IRQ(IRQ_PIT_CH1);
      
      PIT_LDVAL1 = 0x00000002; // setup Timer 1 for 3 cycles
      PIT_TCTRL1 |= 0x00000003; // enable Timer 1 interrupts (TIE = 1) & start Timer 1 (TEN = 0)
    }
    
    void pit1_isr(void){
        digitalWrite(CLKout,!digitalRead(CLKout));
        PIT_TFLG1 = 0;
    }
    
    void loop() {
    }
    with this code I only get 716kHz at the output instead of 32MHz.

    Thanks a lot for your help!

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,292
    Quote Originally Posted by RobinK View Post
    Does someone know on what frequency the Bus Clock runs?
    When F_CPU is 96 MHz, F_BUS defaults to 48 MHz.

    Look in kinetis.h for details.

    I'm trying to get an interrupt every 31.25ns (3 cycles at 96MHz).
    That's never going to work. The ARM processor takes at least a dozen cycles just to enter interrupt mode, and likely more if your function isn't in 1-cycle RAM with FASTRUN.

  3. #3
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    The absolute maximum Teensy 3.2 can handle is about 3'400'000 pulses per second (6'800'000 interrupts).

    "PIT_TFLG1 = 0;" doesn't clear the interrupt, it remains asserted. You need to do "PIT_TFLG1 = 1;".

    digitalWrite is extremely slow. Use digitalWriteFast instead. For the fastest possible pin toggling, you need to use the port toggle register. E.g.:

    Code:
    const uint8_t out_pin = 12;
    #define OUT_PIN_PTOR GPIOC_PTOR
    #define OUT_PIN_BMASK CORE_PIN12_BITMASK
    
    void pit1_isr(void){
        PIT_TFLG1 = 1;
        OUT_PIN_PTOR = OUT_PIN_BMASK;
    }
    Even then, you will have a lot of jitter. Interrupt latency is variable by several clock cycles and various libraries disable interrupts.
    Last edited by tni; 03-15-2017 at 03:42 PM.

  4. #4
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,321
    Quote Originally Posted by tni View Post
    The absolute maximum Teensy 3.2 can handle is about 6'800'000 interrupts per second.
    Where did you get that figure?

    i have a sketch that uses systick to count cycles into and out of isr. For T3.1 i get 46 ticks in, 25 ticks out, so that's 71/96 = 0.74 us/ interrupt, or about 1.35 million/sec.
    Last edited by manitou; 05-05-2018 at 05:43 PM.

  5. #5
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    Quote Originally Posted by manitou View Post
    Where did you get that figure?

    i have a sketch that uses systick to count cycles into and out of isr. For T3.1 i get 46 ticks in, 25 ticks out, so that's 71/96 = 0.74 us/ interrupt, or about 1.35 million/sec.
    Your measurement methodology has too much overhead. Can you post your sketch?

    Code:
    const uint8_t out_pin = 12;
    #define OUT_PIN_PTOR GPIOC_PTOR
    #define OUT_PIN_BMASK CORE_PIN12_BITMASK
    
    void setup() {
        pinMode(out_pin, OUTPUT);
    
        SIM_SCGC6 |= SIM_SCGC6_PIT;
        PIT_MCR = 0x00;
        NVIC_ENABLE_IRQ(IRQ_PIT_CH1);
        PIT_LDVAL1 = 1; // count to 1
        PIT_TCTRL1 |= 0x00000003; // enable Timer 1 interrupts (TIE = 1) & start Timer 1 (TEN = 0)
    }
    
    void pit1_isr(void){
        OUT_PIN_PTOR = OUT_PIN_BMASK;
        PIT_TFLG1 = 1;
    }
    
    void loop() {}
    Teensy 3.2 running at 96MHz. 'FASTRUN' doesn't really make a difference. A second Teensy is used for pulse counting.

  6. #6
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,321
    Quote Originally Posted by tni View Post
    Your measurement methodology has too much overhead. Can you post your sketch?
    Yep, it's that "too much overhead" that I am trying to measure.
    sketch at https://github.com/manitou48/teensy3...er/isrperf.ino
    T3.1 results are for FASTISR where i hack the core PORTC ISR to go directly to my sketch isr
    anecdotal results from various MCUs at https://github.com/manitou48/DUEZoo/...er/isrperf.txt

    I can do better. if i PWM @2mhz into attachInterrupt isr (not FASTISR) i count 1819499 ticks/sec in the isr. If PWM is faster than 2mhz, then sketch hangs (all CPU cycles consumed in ISR)

    EDIT: with FASTISR (direct PORTC ISR) and T3.2@120mhz and PWM at 2.5mhz, I get 5 million interrupts/sec, 400 ns in ISR toggling pin 12. 400/8.3333 is 24 cycles. With default ISR, 46 cycles.

    Cortex M4 architecture manual says 12 cycles entry latency, and 10 cycles exit latency, assuming lazy stacking for float.
    Last edited by manitou; 05-08-2018 at 11:08 AM.

  7. #7
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    There are two big differences. My code will trigger the use of interrupt chaining, reducing interrupt overhead quite a bit.

    Your measurements also have overhead for the GPIO toggle instructions, GPIO bus latency, the wait loop and reading the systick counter.

  8. #8
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,321
    In doing some PIT tests, i revisited this post and tni's sketch in post #5. With the scope attached to pin 12, i noticed that pin 12 frequency was same as PIT frequency when PIT_LDVAL1 = 59, BUT pin 12 frequency should be half of PIT. So i think the ISR is firing twice. The FIX is to reset PIT_TFLG1 in the ISR before doing the toggle,.

    In that configuration, with T3.2@120mhz and PIT_LDVAL1=1, the pin 12 frequency is 2.5 mhz, implying that max PIT ISR rate is 5 million interrupts/sec. ISR duration is 200 ns or 24 cycles with F_CPU 120mhz.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •