Where to find interrupt numbers for Teensy 4? Specifically SPI Frame Complete Int.

Status
Not open for further replies.

JimKazmer

Well-known member
Below is a short test program where I try to attachInterrupt(IRQ_LPSPI4...). It appears I am not using the correct value for the interrupt.
I am looking at the MOSI signal on a scope and all the code is doing what you would expect, except my ISR is never being called.

Where can I find the number that would correspond to LPSPI4_IER=LPSPI_IER_FCIE ?

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
//from Teensy 4 imxrt.h
//        IRQ_LPSPI1 =            32, 
//        IRQ_LPSPI2 =            33,
//        IRQ_LPSPI3 =            34,
//        IRQ_LPSPI4 =            35,
//...
//        IRQ_GPIO6789 =          157, // RT1060 only
#include <SPI.h>

const int slaveSelectPin = 10;
int i=0;
  
void setup() {
  Serial.begin(38400);
  pinMode (slaveSelectPin, OUTPUT);
  digitalWrite (slaveSelectPin, HIGH);

  SPI.begin(); 
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));  
  while(i++<20)
  { //wiggle High signal to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);
    SPI.transfer(0xFF);
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
    //wiggle Low signal to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);
    SPI.transfer(0x00);
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
  }

  //SPI.usingInterrupt(IRQ_LPSPI4);
  attachInterrupt(IRQ_LPSPI4, SPI_FrameComplete, HIGH); //IRQ_LPSPI3 cuases this function to called immediately
}

volatile uint32_t cnt_ist=0;
void SPI_FrameComplete() //IRQ_LPSPI4
{
  //Serial.printf(" i'm here.\n");
  cnt_ist++;
  digitalWrite (slaveSelectPin, HIGH);
  LPSPI4_SR = 0x3f00;//Reset All flags and errors
  asm("dsb");
}
// NOTE: The SPI write code below only works because I am giving the system 100ms between writes.
// This is an example for discussing the SPI Frame Complete Interrupt (not proper SPI buffering).
void loop() 
{
  Serial.printf(" CNT: ***** %d *****\n",cnt_ist);
  i=0;
  while(i++<20)
  { //wiggle EVEN bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0xAA;    asm volatile("nop");
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
    //wiggle ODD bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0x55;    asm volatile("nop");
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
  }
  // the above works almost the same, but my slaveSelectPin goes HIGH almost immediately, long before the END of Frame.
  // Let's enable the SPI interrupt and use that to set my slaveSelectPin HIGH
  //LPSPI4_CR = 0x0300; //Disable SPI, reset FIFOs
  //asm volatile("nop");
  LPSPI4_IER=LPSPI_IER_FCIE; //Set Frame Complete Interrupt Enable
  //LPSPI4_IER=LPSPI_IER_FCIE | LPSPI_IER_TDIE; //Set Frame Complete Interrupt Enable AND Transmit Data Interrupt Enable
  //asm volatile("nop");
  //LPSPI4_CR = 0x0001; //Enable SPI
  //asm volatile("nop");
  i=0;
  while(i++<20)
  { //wiggle LEFT bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0xF0;    asm volatile("nop");
    //digitalWrite (slaveSelectPin, HIGH);  // This should be done in ISR
    delay(100);
    //wiggle RIGHT bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0x0F;    asm volatile("nop");
    //digitalWrite (slaveSelectPin, HIGH);   // This should be done in ISR
    delay(100);
  }
}
 
Okay... it appears that attachInterrupt(...) is associated with I/O Pins... It is using my IRQ number (IRQ_LPSPI4=35) (from MX RT1060 table 3-2) as a pin number and compiling with no warnings.

Is there any function like ISR(int-vector) that is described at https://www.pjrc.com/teensy/interrupts.html (which may not apply to the Teensy 3/4)?

From another post I read, it could be related to these functions/macros... But I didn't get those working either.
NVIC_SET_PRIORITY(spi_irq, 1); // set priority
NVIC_ENABLE_IRQ(spi_irq); // enable IRQ
 
Last edited:
That is very much what I needed. Thank you!

Here is the corrected code... not much use to anyone unless you have a scope (and even then there are better things to watch wiggle (only a reference to the code)). You can uncomment the "Serial.printf()" in the ISR.

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
//from Teensy 4 imxrt.h
//        IRQ_LPSPI1 =            32, 
//        IRQ_LPSPI2 =            33,
//        IRQ_LPSPI3 =            34,
//        IRQ_LPSPI4 =            35,
#include <SPI.h>

const int slaveSelectPin = 10;
int i=0;
  
void setup() {
  Serial.begin(38400);
  pinMode (slaveSelectPin, OUTPUT);
  digitalWrite (slaveSelectPin, HIGH);

  SPI.begin(); 
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));  
  while(i++<20)
  { //wiggle High signal to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);
    SPI.transfer(0xFF);
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
    //wiggle Low signal to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);
    SPI.transfer(0x00);
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
  }

  //SPI.usingInterrupt(IRQ_LPSPI4);
  attachInterruptVector(IRQ_LPSPI4, SPI_FrameComplete);
  NVIC_SET_PRIORITY(IRQ_LPSPI4, 2); // set priority
  NVIC_ENABLE_IRQ(IRQ_LPSPI4); // enable IRQ
}

volatile uint32_t cnt_ist=0;
void SPI_FrameComplete() //IRQ_LPSPI4
{
  cnt_ist++;
  digitalWrite (slaveSelectPin, HIGH);
  //Serial.printf(" ISR_cnt:%d.\n",cnt_ist);
  LPSPI4_SR = 0x3f00;//Reset All flags and errors
  asm("dsb");
}
// NOTE: The SPI write code below only works because I am giving the system 100ms between writes.
// This is an example for discussing the SPI Frame Complete Interrupt (not proper SPI buffering).
void loop() 
{
  Serial.printf(" CNT: ***** %d *****\n",cnt_ist);
  i=0;
  while(i++<20)
  { //wiggle EVEN bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0xAA;    asm volatile("nop");
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
    //wiggle ODD bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0x55;    asm volatile("nop");
    digitalWrite (slaveSelectPin, HIGH);
    delay(100);
  }
  // the above works almost the same, but my slaveSelectPin goes HIGH almost immediately, long before the END of Frame.
  // Let's enable the SPI interrupt and use that to set my slaveSelectPin HIGH
  //LPSPI4_CR = 0x0300; //Disable SPI, reset FIFOs
  //asm volatile("nop");
  LPSPI4_IER=LPSPI_IER_FCIE; //Set Frame Complete Interrupt Enable
  //LPSPI4_IER=LPSPI_IER_FCIE | LPSPI_IER_TDIE; //Set Frame Complete Interrupt Enable AND Transmit Data Interrupt Enable
  //asm volatile("nop");
  //LPSPI4_CR = 0x0001; //Enable SPI
  //asm volatile("nop");
  i=0;
  while(i++<20)
  { //wiggle LEFT bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0xF0;    asm volatile("nop");
    //digitalWrite (slaveSelectPin, HIGH);  // This should be done in ISR
    delay(100);
    //wiggle RIGHT bits to oscilloscope, trigger scope using slaveSelectPin going low
    digitalWrite(slaveSelectPin,LOW);     
    LPSPI4_TCR =  LPSPI_TCR_RXMSK | 0x0000007;    asm volatile("nop");
    LPSPI4_TDR = 0x0F;    asm volatile("nop");
    //digitalWrite (slaveSelectPin, HIGH);   // This should be done in ISR
    delay(100);
  }
}
 
Status
Not open for further replies.
Back
Top