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

Status
Not open for further replies.

gopiballava

New member
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.
 
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
 
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;
}
}
 
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
 
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
 
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
 
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
 
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.
 
Status
Not open for further replies.
Back
Top