Hello,
Thank you for your answers.
Excuse my language but I go through google translation.
The last time I wrote code was in GW BASIC .... now I use LABVIEW instead. It took me a while to get back into this universe.
It is indeed to achieve a simple lock-in that I sought your help. After studying a little mechanics I got my way but it seems to me that I still have some bugs.
I have no merit ! To do this, I used Paul Stoffregen's library and simplified it for my particular needs.
I also helped myself to an excellent AN:
https://www.nxp.com/docs/en/application-note/AN5142.pdf
I have not yet grasped all the subtleties of the FTM but I am beginning to understand how it works.
Here is an example of the "bug" that I encounter when I read the raw value of the counter (Ref -Mes) every 10 ms. The returned value is false and that in a way that seems random.
17391;-1019.00
17402;64508.00 < ------
17413;-1021.00
17424;-1030.00
17435;-1022.00
17446;-1030.00
17457;-1024.00
17468;-1025.00
17479;-1026.00
17490;-1019.00
17501;-1025.00
17512;-1019.00
17523;-1028.00
17534;-1019.00
17545;-1027.00
17556;64514.00 <----------
17567;-1024.00
Here is the code in cpp :
#include "FreqMeasure.h"
#include "util/FreqMeasureCaptureMoi.h"
#define FREQMEASURE_BUFFER_LEN 12
static volatile uint32_t buffer_value[FREQMEASURE_BUFFER_LEN];
static volatile uint8_t buffer_head;
static volatile uint8_t buffer_tail;
static uint32_t captureRef;
static uint32_t captureMes;
static int32_t Dephasage;
void FreqMeasureClass::begin(void)
{
capture_init();
buffer_head = 0;
buffer_tail = 0;
capture_start();
}
uint8_t FreqMeasureClass::available(void)
{
uint8_t head, tail;
head = buffer_head;
tail = buffer_tail;
if (head >= tail) return head - tail;
return FREQMEASURE_BUFFER_LEN + head - tail;
}
int32_t FreqMeasureClass::read(void)
{
uint8_t head, tail;
int32_t value;
head = buffer_head;
tail = buffer_tail;
if (head == tail) return 0xFFFFFFFF;
tail = tail + 1;
if (tail >= FREQMEASURE_BUFFER_LEN) tail = 0;
value = buffer_value[tail];
buffer_tail = tail;
return value;
}
float FreqMeasureClass::countToNanoseconds(int32_t count)
{
return (float)count * (1000000000.0f / (float)F_BUS);
}
void FreqMeasureClass::end(void)
{
capture_shutdown();
}
void FTM_ISR_NAME (void)
{
uint8_t i = 0;
bool inc = false;
if (capture_overflow()) {
capture_overflow_reset();
inc = true;
}
if (capture_event_Ref()) {
captureRef = capture_read_Ref();
do {
} while (capture_event_Mes()==0);
captureMes = capture_read_Mes();
Dephasage = captureRef - captureMes;
i = buffer_head + 1;
if (i >= FREQMEASURE_BUFFER_LEN) i = 0;
if (i != buffer_tail) {
buffer_value
= Dephasage;
buffer_head = i;
}
}
}
FreqMeasureClass FreqMeasure;
The header :
#define CAPTURE_USE_FTM1_CH0 3 // FTM1 CH0 sur pin 3. C'est la Référence
#define CAPTURE_USE_FTM1_CH1 4 // FTM1 CH1 sur pin 4. C'est la Mesure
#define FTM_SC_VALUE (FTM_SC_TOIE | FTM_SC_CLKS(1) | FTM_SC_PS(0))
#define FTM_ISR_NAME ftm1_isr
static inline void capture_init(void)
{
if (FTM1_MOD != 0xFFFF || (FTM1_SC & 0x7F) != FTM_SC_VALUE) {
FTM1_SC = 0;
FTM1_CNT = 0;
FTM1_MOD = 0xFFFF;
FTM1_SC = FTM_SC_VALUE;
FTM1_MODE = 0;
FTM1_MODE = FTM_MODE_WPDIS; //allow reconfiguring the CSC on the fly
}
NVIC_SET_PRIORITY(IRQ_FTM1, 48);
}
static inline void capture_start(void)
{
FTM1_C0SC = 0b01000100;
*portConfigRegister(CAPTURE_USE_FTM1_CH0) = PORT_PCR_MUX(3);
FTM1_C1SC = 0b01000100;
*portConfigRegister(CAPTURE_USE_FTM1_CH1) = PORT_PCR_MUX(3);
NVIC_ENABLE_IRQ(IRQ_FTM1);
}
static inline uint16_t capture_event_Ref(void)
{
return (FTM1_C0SC & 0x80) ? 1 : 0;
}
static inline uint32_t capture_read_Ref(void)
{
uint32_t val = FTM1_C0V;
FTM1_C0SC = 0b01000100;
return val;
}
static inline uint8_t capture_overflow(void)
{
return (FTM1_SC & FTM_SC_TOF) ? 1 : 0;
}
static inline void capture_overflow_reset(void)
{
FTM1_SC = FTM_SC_VALUE;
}
static inline void capture_shutdown(void)
{
FTM1_C0SC = 0;
*portConfigRegister(CAPTURE_USE_FTM1_CH0) = 0;
FTM1_C1SC = 0;
*portConfigRegister(CAPTURE_USE_FTM1_CH1) = 0;
NVIC_DISABLE_IRQ(IRQ_FTM1);
}
static inline uint16_t capture_event_Mes(void)
{
return (FTM1_C1SC & 0x80) ? 1 : 0;
}
static inline uint32_t capture_read_Mes(void)
{
uint32_t val = FTM1_C1V;
FTM1_C1SC = 0b01000100;
return val;
}
second header :
#ifndef FreqMeasure_h
#define FreqMeasure_h
#include <Arduino.h>
class FreqMeasureClass {
public:
static void begin(void);
static uint8_t available(void);
static int32_t read(void);
static float countToNanoseconds(int32_t count);
static void end(void);
};
extern FreqMeasureClass FreqMeasure;
#endif
Thank you very much for your comments or suggestions