I'm using the arudinostm32 core (v1.9.0) with platformIO on a Nucleo-F103RB board.
I'm having difficulty using more than one timer channels with input capture. In my example below, im using TIM2_CH1 and TIM2_CH2 on PA0 and PA1.
If i start with just TIM2_CH1 - it works fine. Once I add TIM2_CH2 - TIM2_CH1 stops working (returns 0), although TIM2_CH2 works correctly.
I'm sure it's something jacked up in the code i lifted from the examples - could anyone point in the right direction please.
thanks
Code: Select all
#include <Arduino.h>
const int rcCH1 = PA0;
const int rcCH2 = PA1;
//const int rcCH2 = PB6;
//Timer setup for rcCH1
volatile uint32_t rcCH1channel;
volatile int32_t rcCH1PulseWidth, rcCH1startTime, rcCH1endTime;
volatile TimerModes_t rcCH1currentMode;
HardwareTimer *ch1;
//Timer setup for rcCH2
volatile uint32_t rcCH2channel;
volatile int32_t rcCH2PulseWidth, rcCH2startTime, rcCH2endTime;
volatile TimerModes_t rcCH2currentMode;
HardwareTimer *ch2;
void rcCH1InputCapture_IT_callback(void)
{
ch1->pause();
rcCH1currentMode = ch1->getMode(rcCH1channel);
if (rcCH1currentMode == TIMER_INPUT_CAPTURE_RISING){
rcCH1startTime = ch1->getCaptureCompare(rcCH1channel);
//ch1->pause();
ch1->setMode(rcCH1channel, TIMER_INPUT_CAPTURE_FALLING, rcCH1);
//ch1->resume();
}
if (rcCH1currentMode == TIMER_INPUT_CAPTURE_FALLING){
rcCH1endTime = ch1->getCaptureCompare(rcCH1channel);
//ch1->pause();
ch1->setMode(rcCH1channel, TIMER_INPUT_CAPTURE_RISING, rcCH1);
//ch1->resume();
rcCH1PulseWidth = (rcCH1endTime - rcCH1startTime);
if (rcCH1PulseWidth < 0)rcCH1PulseWidth += 0xFFFF;
}
ch1->resume();
}
void rcCH2InputCapture_IT_callback(void)
{
ch2->pause();
rcCH2currentMode = ch2->getMode(rcCH2channel);
if (rcCH2currentMode == TIMER_INPUT_CAPTURE_RISING){
rcCH2startTime = ch2->getCaptureCompare(rcCH2channel);
//ch2->pause();
ch2->setMode(rcCH2channel, TIMER_INPUT_CAPTURE_FALLING, rcCH2);
//ch2->resume();
}
if (rcCH2currentMode == TIMER_INPUT_CAPTURE_FALLING){
rcCH2endTime = ch2->getCaptureCompare(rcCH2channel);
//ch2->pause();
ch2->setMode(rcCH2channel, TIMER_INPUT_CAPTURE_RISING, rcCH2);
//ch2->resume();
rcCH2PulseWidth = (rcCH2endTime - rcCH2startTime);
if (rcCH2PulseWidth < 0)rcCH2PulseWidth += 0xFFFF;
}
ch2->resume();
}
void setup()
{
//Timer setup for rcCH1
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(rcCH1), PinMap_PWM);
rcCH1channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(rcCH1), PinMap_PWM));
ch1 = new HardwareTimer(Instance);
ch1->setMode(rcCH1channel, TIMER_INPUT_CAPTURE_RISING, rcCH1);
uint32_t PrescalerFactor =71;
ch1->setPrescaleFactor(PrescalerFactor);
ch1->setOverflow(0x10000); // Max Period value to have the largest possible time to detect rising edge and avoid timer rollover
ch1->attachInterrupt(rcCH1channel, rcCH1InputCapture_IT_callback);
ch1->resume();
//Timer setup for rcCH2
TIM_TypeDef *Instance2 = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(rcCH2), PinMap_PWM);
rcCH2channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(rcCH2), PinMap_PWM));
ch2 = new HardwareTimer(Instance2);
ch2->setMode(rcCH2channel, TIMER_INPUT_CAPTURE_RISING, rcCH2);
uint32_t PrescalerFactor2 =71;
ch2->setPrescaleFactor(PrescalerFactor2);
ch2->setOverflow(0x10000); // Max Period value to have the largest possible time to detect rising edge and avoid timer rollover
ch2->attachInterrupt(rcCH2channel, rcCH2InputCapture_IT_callback);
ch2->resume();
Serial2.begin(115200);
}
void loop()
{
Serial2.print(rcCH1PulseWidth);
Serial2.print(",");
Serial2.println(rcCH2PulseWidth);
}