DavidTroendle
New member
Experts,
I saw Nefarious' post on sub-microsecond timers, but did not see an answer. I have a similar question.
Is it possible to create an interval timer that interrupts every μs on a Teensy 3.6? (I am using DWT_CYCCNT to measure jitter and processing times.)
I tried the sketch below under Windows 10 on a Teensy 3.6. It works as long as the indicated line below "MyTimer.begin(Sample,3000);" is 3000 or more. (Sample output is after code.)
Many thanks for helping a newbie.
David
===================================Sketch===================================
class cCycleCount
{
volatile uint32_t *DWT_CYCCNT;
volatile uint32_t *DWT_CONTROL;
volatile uint32_t *SCB_DEMCR; // debug exception and monitor control
volatile uint32_t *LAR;
public:
cCycleCount(void)
{
DWT_CYCCNT = (volatile uint32_t *) 0xE0001004;
DWT_CONTROL = (volatile uint32_t *) 0xE0001000;
SCB_DEMCR = (volatile uint32_t *) 0xE000EDFC;
LAR = (uint32_t *) 0xE0001FB0;
return;
}
void init(void)
{
*SCB_DEMCR |= 0x01000000;
*LAR = 0xC5ACCE55;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL |= 1; // enable the counter
}
inline uint32_t ticks(void)
{
return *DWT_CYCCNT;
}
inline uint32_t micros(void)
{
static const uint16_t DIV = F_CPU / 1000 / 1000;
return *DWT_CYCCNT / DIV; // TODO: will skip when wrapping, only use to check drift!
}
inline void reset(void)
{
*DWT_CYCCNT = 0;
return;
}
};
cCycleCount CycleCount;
IntervalTimer MyTimer;
#define nSamples 16u
volatile uint32_t SampleTimes[nSamples];
volatile uint32_t ProcessingTimes[nSamples];
volatile uint32_t SampleIndex = 0u;
void setup(void)
{
CycleCount.init();
SampleIndex = 0u;
Serial.begin(9600);
Serial.println("Setup complete.");
MyTimer.begin(Sample,3000); // <<<<================== Lowest number that works.
}
FASTRUN void Sample(void)
{
uint32_t Count = CycleCount.ticks();
CycleCount.reset();
if (SampleIndex < nSamples)
{
SampleTimes[SampleIndex] = Count;
ProcessingTimes[SampleIndex] = CycleCount.ticks();
++SampleIndex;
}
return;
}
void loop(void)
{
uint32_t Index;
noInterrupts();
Index = SampleIndex;
interrupts();
if (Index == nSamples)
{
for (uint32_t i = 0u; i < nSamples; ++i)
{
Serial.print("Sample: ");
Serial.print(i);
Serial.print(" Count: ");
Serial.print(SampleTimes);
Serial.print(" Processing Time: ");
Serial.println(ProcessingTimes);
}
++SampleIndex;
}
}
===================================Sample Output===================================
Sample: 0 Count: 540492 Processing Time: 16
Sample: 1 Count: 539983 Processing Time: 16
Sample: 2 Count: 540004 Processing Time: 16
Sample: 3 Count: 539992 Processing Time: 16
Sample: 4 Count: 539998 Processing Time: 16
Sample: 5 Count: 539998 Processing Time: 16
Sample: 6 Count: 540004 Processing Time: 16
Sample: 7 Count: 539992 Processing Time: 16
Sample: 8 Count: 539998 Processing Time: 16
Sample: 9 Count: 539998 Processing Time: 16
Sample: 10 Count: 539998 Processing Time: 16
Sample: 11 Count: 539998 Processing Time: 16
Sample: 12 Count: 540013 Processing Time: 16
Sample: 13 Count: 539983 Processing Time: 16
Sample: 14 Count: 539998 Processing Time: 16
Sample: 15 Count: 539998 Processing Time: 16
I saw Nefarious' post on sub-microsecond timers, but did not see an answer. I have a similar question.
Is it possible to create an interval timer that interrupts every μs on a Teensy 3.6? (I am using DWT_CYCCNT to measure jitter and processing times.)
I tried the sketch below under Windows 10 on a Teensy 3.6. It works as long as the indicated line below "MyTimer.begin(Sample,3000);" is 3000 or more. (Sample output is after code.)
Many thanks for helping a newbie.
David
===================================Sketch===================================
class cCycleCount
{
volatile uint32_t *DWT_CYCCNT;
volatile uint32_t *DWT_CONTROL;
volatile uint32_t *SCB_DEMCR; // debug exception and monitor control
volatile uint32_t *LAR;
public:
cCycleCount(void)
{
DWT_CYCCNT = (volatile uint32_t *) 0xE0001004;
DWT_CONTROL = (volatile uint32_t *) 0xE0001000;
SCB_DEMCR = (volatile uint32_t *) 0xE000EDFC;
LAR = (uint32_t *) 0xE0001FB0;
return;
}
void init(void)
{
*SCB_DEMCR |= 0x01000000;
*LAR = 0xC5ACCE55;
*DWT_CYCCNT = 0; // reset the counter
*DWT_CONTROL |= 1; // enable the counter
}
inline uint32_t ticks(void)
{
return *DWT_CYCCNT;
}
inline uint32_t micros(void)
{
static const uint16_t DIV = F_CPU / 1000 / 1000;
return *DWT_CYCCNT / DIV; // TODO: will skip when wrapping, only use to check drift!
}
inline void reset(void)
{
*DWT_CYCCNT = 0;
return;
}
};
cCycleCount CycleCount;
IntervalTimer MyTimer;
#define nSamples 16u
volatile uint32_t SampleTimes[nSamples];
volatile uint32_t ProcessingTimes[nSamples];
volatile uint32_t SampleIndex = 0u;
void setup(void)
{
CycleCount.init();
SampleIndex = 0u;
Serial.begin(9600);
Serial.println("Setup complete.");
MyTimer.begin(Sample,3000); // <<<<================== Lowest number that works.
}
FASTRUN void Sample(void)
{
uint32_t Count = CycleCount.ticks();
CycleCount.reset();
if (SampleIndex < nSamples)
{
SampleTimes[SampleIndex] = Count;
ProcessingTimes[SampleIndex] = CycleCount.ticks();
++SampleIndex;
}
return;
}
void loop(void)
{
uint32_t Index;
noInterrupts();
Index = SampleIndex;
interrupts();
if (Index == nSamples)
{
for (uint32_t i = 0u; i < nSamples; ++i)
{
Serial.print("Sample: ");
Serial.print(i);
Serial.print(" Count: ");
Serial.print(SampleTimes);
Serial.print(" Processing Time: ");
Serial.println(ProcessingTimes);
}
++SampleIndex;
}
}
===================================Sample Output===================================
Sample: 0 Count: 540492 Processing Time: 16
Sample: 1 Count: 539983 Processing Time: 16
Sample: 2 Count: 540004 Processing Time: 16
Sample: 3 Count: 539992 Processing Time: 16
Sample: 4 Count: 539998 Processing Time: 16
Sample: 5 Count: 539998 Processing Time: 16
Sample: 6 Count: 540004 Processing Time: 16
Sample: 7 Count: 539992 Processing Time: 16
Sample: 8 Count: 539998 Processing Time: 16
Sample: 9 Count: 539998 Processing Time: 16
Sample: 10 Count: 539998 Processing Time: 16
Sample: 11 Count: 539998 Processing Time: 16
Sample: 12 Count: 540013 Processing Time: 16
Sample: 13 Count: 539983 Processing Time: 16
Sample: 14 Count: 539998 Processing Time: 16
Sample: 15 Count: 539998 Processing Time: 16