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());
}