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

Thread: Timer interrupt, or other way to read SPI consistently on Teensy3.0?

  1. #1
    Junior Member
    Join Date
    Nov 2012
    Posts
    3

    Timer interrupt, or other way to read SPI consistently on Teensy3.0?

    Hi,

    I would like to read two SPI ADCs at a consistent rate. I've got code working that reads them asynchronously, but I'd prefer to use a timer interrupt. Probably trigger at 2x the read rate, first interrupt would start the sampling, second would read the data, repeat.

    Any suggestions? I'm open to bizarre hacks like generating pulses and feeding them back in to interrupt pins.

    Thanks.

  2. #2
    Quote Originally Posted by gopiballava View Post
    Hi,

    I would like to read two SPI ADCs at a consistent rate. I've got code working that reads them asynchronously, but I'd prefer to use a timer interrupt.

    Have you looked at the periodic interrupt timer (PIT) section of the datasheet?

    -c

  3. #3
    Junior Member
    Join Date
    Nov 2012
    Posts
    3
    Quote Originally Posted by cmason View Post
    Have you looked at the periodic interrupt timer (PIT) section of the datasheet?
    I was hoping to avoid that, and just work with an existing library, because it always seems to take more time with the datasheet

    I've got it working right now. Here's snippets of my code:

    Code:
    #define TIE 0x2
    #define TEN 0x1
    //Turn on interrupts:
    	SIM_SCGC6 |= SIM_SCGC6_PIT;
    	// turn on PIT
    	PIT_MCR = 0x00;
    	NVIC_ENABLE_IRQ(IRQ_PIT_CH2);
    
    	PIT_LDVAL2 = period; // setup timer 2 for period cycles
    	PIT_TCTRL2 = TIE; // enable Timer 2 interrupts
    	PIT_TCTRL2 |= TEN; // start Timer 2
    	PIT_TFLG2 |= 1;
    //Turn off interrupts:
    	PIT_TCTRL2 = 0; // disable Timer 2 interrupts
    And the interrupt routine itself:

    Code:
    extern "C"
    {
    void pit2_isr(void)
    {
    ..........
    	PIT_TFLG2 = 1;
    }
    }

  4. #4
    Nice, thanks for posting your code snippet!

    -c

  5. #5
    Junior Member
    Join Date
    Dec 2012
    Location
    Oakland, CA
    Posts
    15
    Thanks for the code! Worked great. Can't wait for the ISR macros but it's been an educational experience.

    mauricio

  6. #6
    Junior Member
    Join Date
    Oct 2012
    Location
    Switzerland
    Posts
    19
    Hi,

    could please someone give me some more hints about how to use this in the Arduino IDE? I've added these code snippets to my Sketch but it won't work. Do I have to change something else?

    Also, what unit is the period written to PIT_LDVAL2? Is it counting every clock tick?

    Thanks!

    Thomas

  7. #7
    Junior Member
    Join Date
    Dec 2012
    Location
    Oakland, CA
    Posts
    15
    Hi,

    What I did was modify mk20dx128.c to make a call to a weak reference to a feature that I defined in my main arduino code. It worked well and required minimal change.

    Take a look at the PIT section in the datasheet posted at pjrc. It shows how to define the load value for the timer very nicely.

    Hope that helps...
    mauricio

  8. #8
    Junior Member
    Join Date
    Oct 2012
    Location
    Switzerland
    Posts
    19
    Thank you Mauricio

    So you changed this line inside mk20dx128.c?

    void pit2_isr(void) __attribute__ ((weak, alias("unused_isr")));

    Sorry to bother you again but I don't get itů For me it looks like everything is here already. Could you post your mk20dx128.c here?

    Thomas

  9. #9
    Junior Member
    Join Date
    Dec 2012
    Location
    Oakland, CA
    Posts
    15
    Np.

    The weak reference gets overridden at link time when you implement in your main code, so no need to change that portion.

    I added the following:

    void blankFeature() {
    }

    void setupFrameTimer(void) __attribute__ ((weak, alias("blankFeature")));

    and added a call to setupFrameTimer() in ResetHandler before __enable_irq().

    In my main code I implemented the setupFrameTimer feature to perform the correct flag settings. At link, this feature will be used instead of the weak reference.

    Hope that helps.

    mauricio

  10. #10
    Junior Member
    Join Date
    Oct 2012
    Location
    Switzerland
    Posts
    19
    It's working! Thank you Mauricio for your support. I had quite some problems but it looks like some stuff changedů

    I added this in my setup() to enable Timer1 (no longer using Timer2!)
    Code:
      // Teensy 3.0 version
      SIM_SCGC6 |= SIM_SCGC6_PIT; // Activates the clock for PIT
      
      // Turn on PIT
      PIT_MCR = 0x00;
      
      // Set the period of the timer.  Unit is (1 / 50MHz) = 20ns
      // 100 ms period -> 5000000 * 20ns
      PIT_LDVAL1 = 5000000;
      
      // Enable interrupts on timer1
      PIT_TCTRL1 = TIE;
      // Start the timer
      PIT_TCTRL1 |= TEN;
      
      NVIC_ENABLE_IRQ(IRQ_PIT_CH1); // Another step to enable PIT channel 1 interrupts
    and this function inside the Sketch too:

    Code:
    void pit1_isr(void) {
      Serial.print(".");
      PIT_TFLG1 = 1;
    }
    Looks like all these changes inside mk20dx128.c are no longer needed on beta 12. This post was also very helpful.

Posting Permissions

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