Hello,
I am a newbie to this forum, and I am working on a project using a Teensy 4.1. I would like to output a square digital waveform at approximately 30 Hz and sample data at 10 kHz from an analog signal on another pin, with the goal of implementing a lock-in amplifier later on. I would like the digital waveform generation and the ADC sampling to share the same clock.
Therefore, I started implementing the digital waveform using the Quad Timer. My code is below, but there is something I do not understand. I read in the reference manual and in several forum posts that the Quad Timers use a 150 MHz clock. Based on this, I expected that setting PIN_TOGGLE_FREQ = 30 and using a prescaler of 128 would result in a pin_load value of (150 MHz / 128) / 30 − 1 = 39,061 (thus ok for a 16 bits counter) which should give a waveform period of (128 / 150 MHz) × 39,061 ≈ 0.03 s
Instead, I measure a period of roughly 0.095 s, corresponding to about 10.48 Hz (as measured with an oscilloscope on pin 6), which is three times lower than expected.
Is there a configuration error in my code, or is there something I am misunderstanding about how the Quad Timer works?
Thanks in advance for any advice or explanation.
Greg
I am a newbie to this forum, and I am working on a project using a Teensy 4.1. I would like to output a square digital waveform at approximately 30 Hz and sample data at 10 kHz from an analog signal on another pin, with the goal of implementing a lock-in amplifier later on. I would like the digital waveform generation and the ADC sampling to share the same clock.
Therefore, I started implementing the digital waveform using the Quad Timer. My code is below, but there is something I do not understand. I read in the reference manual and in several forum posts that the Quad Timers use a 150 MHz clock. Based on this, I expected that setting PIN_TOGGLE_FREQ = 30 and using a prescaler of 128 would result in a pin_load value of (150 MHz / 128) / 30 − 1 = 39,061 (thus ok for a 16 bits counter) which should give a waveform period of (128 / 150 MHz) × 39,061 ≈ 0.03 s
Instead, I measure a period of roughly 0.095 s, corresponding to about 10.48 Hz (as measured with an oscilloscope on pin 6), which is three times lower than expected.
Is there a configuration error in my code, or is there something I am misunderstanding about how the Quad Timer works?
Thanks in advance for any advice or explanation.
Greg
Code:
#include <Arduino.h>
#include <imxrt.h>
#include <cstring> // For strcpy, strtok, strcmp, strchr
#define QTMR4 (IMXRT_TMR4)
/*
* Timer Configuration
*/
#define PIN_TOGGLE_FREQ 30u // 10.48 Hz pin toggle ????
void setup(){
// ============================================================
// Enable clocks
// ============================================================
CCM_CCGR6 |= CCM_CCGR6_QTIMER4(CCM_CCGR_ON);
delayMicroseconds(10); // Wait for clocks to stabilize
// ============================================================
// Pin mux
// ============================================================
// pin 6 on teensy 4,1, see manual for ALT1 = QTMR4_TIMER1
IOMUXC_SW_MUX_CTL_PAD_GPIO_B0_10 = 1; //page 518 at ALT1 = QTMR4_TIMER1
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_10 = 0x10B0; // page 395
// ============================================================
// QTMR4 setup (shared clock domain)
// ============================================================
uint32_t qtmr_clk = 150000000u; // 150 MHz peripheral clock
delayMicroseconds(10);
// ----------------------------
// QTMR4 Channel 1 -> Pin 10 Hz
// ----------------------------
QTMR4.CH[1].CTRL = 0; // stop timer
QTMR4.CH[1].CNTR = 0;
// define toogle value for counter
uint32_t pin_load = (qtmr_clk / (PIN_TOGGLE_FREQ)) - 1;
QTMR4.CH[1].LOAD = pin_load;
QTMR4.CH[1].COMP1 = int(pin_load/2);
QTMR4.CH[1].CMPLD1 = pin_load/2; // Same as COMP1
QTMR4.CH[1].CSCTRL = TMR_CSCTRL_CL1(1) | TMR_CSCTRL_ALT_LOAD;
QTMR4.CH[1].CTRL =
TMR_CTRL_CM(1) | // Count to compare mode
TMR_CTRL_PCS(15) | // Primary clock source: IPG clock (150 MHz) for QTIMER4 with 128 prescaler, see page 3000 of manual
TMR_CTRL_LENGTH | // Periodic mode
TMR_CTRL_OUTMODE(3) | // Toggle on compare + roll over
(1 << 0); // ENABLE: enable timer immediately
// Enable output to pin 6 - ?
QTMR4.CH[1].SCTRL = TMR_SCTRL_OEN | TMR_SCTRL_OPS | TMR_SCTRL_VAL;
}
//end setup
void loop(){
}