How do I timer interrupt SPI on Nano 33 IoT?

Hello:
My Nano 33 IoT flight controller is using SX1276 LoRa as the radio, communicating through SPI. But the PWM timer interrupts cannot function reliably for it's being barred by the SPI.
Although I can snug the LoRa thingies in-betweeen PWM edges () if I set the signal bandwidth to 250k, still I'd like to know how to make it work with default bandwidth settings.

LoRa library: modified from Sandeep Mistry's lib

Here's the code of the PWM timer interrupt:
( "LoRa.checkDio0()" is in loop(), checking if LoRa has recieved or done transmitting packets)

// PWM section ------------------------------------------------------------------------------------------------------

// TC5_Handler, do these when timer's up

void TC5_Handler (void)

{

  PWM.low(output_i); // set previous low

  output_i = (output_i+1) & 0b11; // iterate

  TC5->COUNT16.CC[0].reg = (uint16_t)(output_v[output_i]*3); // set timer time

  PWM.high(output_i); // channel high

  TC5->COUNT16.INTFLAG.bit.MC0 = 1; // start timer

  //LoRa.checkDio0(); // if using 250000 signal bandwidth
}

// initialize TC5 timer

 void TC5init()

{

  // select the generic clock generator used as source to the generic clock multiplexer

  GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;

  while (GCLK->STATUS.bit.SYNCBUSY);

  tcReset(); //reset TC5

  // Set Timer counter 5 Mode to 16 bits, it will become a 16bit counter ('mode1' in the datasheet)

  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;

  // Set TC5 waveform generation mode to 'match frequency'

  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;

  //set prescaler, TC_CTRLA_ENABLE divides GCLK_TC frequency by 1024

  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV16 | TC_CTRLA_ENABLE;

  TC5->COUNT16.CTRLA.bit.PRESCALER = 1;

  //set the compare-capture register.

  TC5->COUNT16.CC[0].reg = (uint16_t)(output_v[0]*3); // TC_CTRLA_PRESCALER_DIVx, x = 16, 48Mhz main clock, cc = 300 => timer set to (48/2)/16 * 300 = 450us

  while (tcIsSyncing());

 

  // Configure interrupt request

  NVIC_DisableIRQ(TC5_IRQn);

  NVIC_ClearPendingIRQ(TC5_IRQn);

  NVIC_SetPriority(TC5_IRQn, 0);

  NVIC_EnableIRQ(TC5_IRQn);

  // Enable the TC5 interrupt request

  TC5->COUNT16.INTENSET.bit.MC0 = 1;

  while (tcIsSyncing()); //wait until TC5 is done syncing

}

//Function that is used to check if TC5 is done syncing

//returns true when it is done syncing

bool tcIsSyncing()

{

  return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;

}

//This function enables TC5 and waits for it to be ready

void tcStartCounter()

{

  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; //set the CTRLA register

  while (tcIsSyncing()); //wait until snyc'd

}

//Reset TC5

void tcReset()

{

  TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;

  while (tcIsSyncing());

  while (TC5->COUNT16.CTRLA.bit.SWRST);

}

//disable TC5

void tcDisable()

{

  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;

  while (tcIsSyncing());

}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.