Hi All.
As I was thinking about a solution to a question posted in another thread, I wondered if it would be possible to extend the input capture capability of a T3.2/5/6’s FTM to 32-bit values (from the FTM hardware’s 16 bits). My simplistic idea (untested code below) is to increment a variable representing the upper 16 bits every time the counter overflows (TOF flag). This would happen in the FTM ISR along with checking the CHF flag.
The only way I can think that this scheme would screw up is if an input edge was detected capturing the counter value right when it became 0x0000 but for some reason the TOF flag wasn’t yet set. I don’t think this scenario would happen if it is guaranteed that TOF will be set in the same clock cycle as CHF when a counter value of 0x0000 is captured. But, I can’t find a definitive statement one way or the other in the datasheet.
Anyone have any insight here?
Thanks.
As I was thinking about a solution to a question posted in another thread, I wondered if it would be possible to extend the input capture capability of a T3.2/5/6’s FTM to 32-bit values (from the FTM hardware’s 16 bits). My simplistic idea (untested code below) is to increment a variable representing the upper 16 bits every time the counter overflows (TOF flag). This would happen in the FTM ISR along with checking the CHF flag.
The only way I can think that this scheme would screw up is if an input edge was detected capturing the counter value right when it became 0x0000 but for some reason the TOF flag wasn’t yet set. I don’t think this scenario would happen if it is guaranteed that TOF will be set in the same clock cycle as CHF when a counter value of 0x0000 is captured. But, I can’t find a definitive statement one way or the other in the datasheet.
Anyone have any insight here?
Thanks.
Code:
#include "Arduino.h"
volatile bool newData = false;
volatile uint32_t capturedCount;
void setup() {
const uint8_t triggerInput = 3;
Serial.begin(115200);
delay(2000);
Serial.println("Starting");
pinMode(triggerInput, INPUT);
FTM1_SC = 0;
FTM1_MODE = FTM_MODE_WPDIS;
FTM1_CNT = 0000; // Reset counter
FTM1_MOD = 0xFFFF; // Terminal count
FTM1_CNTIN = 0; // Counter reload value
*portConfigRegister(triggerInput) = PORT_PCR_MUX(3); // FTM1 Ch 0 pin - PTA12
FTM1_C0SC = FTM_CSC_ELSA; // FTM1 Ch0 capture on rising edge
FTM1_SC &= ~FTM_SC_TOF; // Force read-modify-write, clear TOF flag
FTM1_C0SC &= ~FTM_CSC_CHF; // Force read-modify-write, clear CHF flag
FTM1_SC |= FTM_SC_TOIE; // enable overflow interrupt
FTM1_C0SC |= FTM_CSC_CHIE; // enable channel interrupt
//NVIC_SET_PRIORITY(IRQ_FTM1, 0); // should we change FTM1 interrupt priority?
NVIC_ENABLE_IRQ(IRQ_FTM1); // Enable FTM1 interrupts
FTM1_SC = FTM_SC_CLKS(1); // run from sys clk, prescaler = 1
}
void loop() {
uint32_t localCounter;
if (newData) {
noInterrupts();
newData = false;
localCounter = capturedCount;
interrupts();
Serial.print("New Count Captured: ");
Serial.println(localCounter);
}
}
void ftm1_isr() {
static uint32_t upperWord = 0;
if (FTM1_SC & FTM_SC_TOF) {
upperWord += 0x10000; // increment upper 16 bits
FTM1_SC &= ~FTM_SC_TOF; // Force read-modify-write, clear TOF flag
}
if (FTM1_C0SC & FTM_CSC_CHF) {
capturedCount = upperWord | FTM1_C0V; // captured 32-bit word
FTM1_C0SC &= ~FTM_CSC_CHF; // Force read-modify-write, clear channel flag
newData = true;
}
}
Last edited: