Using Teensy4.0 with external word clock

Not open for further replies.


Well-known member
I want to supply the Teensy just with the studio Master Clock (96kHz in our case) and have it generate it's own I2S LRCLK and BCLK (and MCLK if possible) from it. I've read through the whole iMXRT Reference Manual but it doesn't seem to cover this particular case, though I suspect it is possible given how powerful the processor is.

I'm anticipating that the Master clock input will use the LRCLK2 pin as an input and then the whole of SAI1 will slave to this with LRCLK1, BCLK1 and MCLK1 being outputs to drive the ADCs and DACs. BCLK2 would be unused as we don't distribute a high frequency clock around the studio. Ideally SPDIF-Out would also be synchronised to the Master Clock but not essential as we can source the SPDIF-in with the “Zero Bit Digital Black” output from the Master Clock generator.

Can anybody give me any hints on the clock routing and dividers I would need to do this ?

Many thanks

Sorry I can't help with the clock timing, but solving this problem will help with some other unresolved issues in the audio library/design tool - i.e. clock syncing with i2sslave. Have you considered using MCLK as an input and using the timers to create the subsidiary clocks? I don't think Paul's library is deeply wedded to MCLK generation from the Teensy.

Why I'm posting, is that I'm working on a similar problem - I'm working on a multi-channel input/output pair of interfaces to add to the library that use TCP/UDP to transport data. The first project from this will be a monitoring system, like an Aviom, where a master Teensy broadcasts (multicasts) monitoring channels to many slaves using the WIZ5500 and off-the shelf 10/100 switches for distribution. Phase 2 would allow sampling on the slaves, upstreamed to the master.

For clock sync, I'm exploring two modes - using a separate Master Clock input to the slaves and regenerating clocks from that, or embedding occasional timecode/sync packets into the data stream and creating a soft PLL to generate clocks.

Have fun with your project, and BTW, it wouldn't take too much effort to convert the ADAT output into SAI/MADI/AES3 or some other more modern multi-channel audio bitstream.

Thanks Richard

All studios just distribute a 96kHz (or 192/384 if you've a lot of hard discs you want to fill up :) clock to sync everything. Sending MCLK everywhere would be a nightmare and wouldn't actually ensure anything is synced that well if you think about it. There's a wide range of Master Clock units on the market for doing this so I won't promote the one I use, but they all send out just the sampling rate on a 5V BNC connector, and some add a 'zero stream' SPDIF output at the same rate.

Regarding ADAT, I don't think the chip in the Teensy can be made to support that sorry. ADAT is purely serial whereas NXP's version of SAI offers multichannel using parallel data lines. STM's chips are different and could possibly support ADAT but have other problems.


My bad - I used MCLK when I meant master clock - which confused everything!

There are a few hints in but not enough to complete the task.

Perhaps the audio tools PLL calculation tool will give you what you need

Have you thought of aligning the iMXRT chip's Xtal oscillator with the M.C.? A CS2000 could create a suitable 24MHz CPU clock from the 96KHz signal, which could be fed directly into TXC0. Then everything would naturally stay in sync.

I have the feeling, we have here some semantic issues.
I2S/SAI has 4 lines, say for RX or TX

-MCLK (master clock)
-BCLK (Bit clock)
-L/R (left/right) clock, or Framesync

we have two modes, master/slave
(I only use ADC terminology, but believe DAC is similar)

Teensy in Master mode, ADC in slave mode
some ADCs require a MCLK that is 256, 512, 0r 1024 times the BCLK.
L/R clock is derived from bit-clock by taking into account the word length in bits
data is then sampled by BCLK.
there are other ADCs that do NOT require MCLK (they generate them internally in ADC from BCLK).
All required clocks (MCLK), BCLK, L/R clock are generated by Teensy

Teensy in Slave mode, ADC in master mode
external device provides BCLK and L/R clock and Teensy adapts to master
no MCLK needs to be configured in Teensy

Hybrid mode:
Teensy in Slave mode, ADC in Master mode, BUT ADC needs MCLK
then, in absence of an ADC xtal, Teensy can provide MCLK (using either MCLK pin or and high speed clock)
but otherwise Teensy expects BCLK and L/R clock as input.
(I'm doing it this way in one of my applications)
Thanks Richard

Those links are very useful. Will try the tool and see if it does what I want. Given there are so many PLLs in the Teensy MCU I was hoping not to add an external one, but that's always a possibility.


We tend to only use equipment that generates it's own MCLK from the master frame sync (L/R) clock so everything in the studio just receives LRCLK and then sends out another LRCLK, BCLK and DOUT. This ensures that all the LRCLK/BCLK/Data sets have optimal timing and hence can go quite long distances with extenders if needed. Receiving is similar. DACs and ADCs sit everywhere as needed, but we make sure all of ours generate their own MCLK from LRCLK as of course MCLK varies from device to device - it can be 24 or 32 times the frame clk, or even longer sometimes.

So it's a variation on your Hybrid mode in that it needs two SAIs, one to receive the master LRCLK, but the second to transmit with the data out. This was what caught the eye about the Teensy 4.0 over many other single board computers in that it had two I2S/SAIs so should be able to do this. I'm sure it can do this, but not there yet.
Well, I use the same SAI for doing both (sending MCLK out and using L/R and BCLK as slave)
here is a snippet of the code for a T3.6

void i2s_rx_slave_setup(void)

  CORE_PIN36_CONFIG = PORT_PCR_MUX(4);  //pin36, PTC9,   I2S0_RX_BCLK
  CORE_PIN37_CONFIG = PORT_PCR_MUX(4);  //pin37, PTC10,  I2S0_RX_FS
  CORE_PIN27_CONFIG = PORT_PCR_MUX(6);  //pin27, PTA15,  I2S0_RXD0


  // enable MCLK output
  while(I2S0_MCR & I2S_MCR_DUF);
  I2S0_RMR=0; // enable receiver mask
  I2S0_RCR1 = I2S_RCR1_RFW(3); 

  I2S0_RCR2 = I2S_RCR2_SYNC(0) 
              | I2S_RCR2_BCP ;
  I2S0_RCR3 = I2S_RCR3_RCE; // single rx channel

  I2S0_RCR4 = I2S_RCR4_FRSZ(7) // 8 words (TDM - mode)
              | I2S_RCR4_FSE  // frame sync early
              | I2S_RCR4_MF;
  I2S0_RCR5 = I2S_RCR5_WNW(31) | I2S_RCR5_W0W(31) | I2S_RCR5_FBT(31);
it uses 8-word TDM, but that can easily be changed
also T4 will need different clock enabling and routing and port settings
Even though the IMXRT chip on Teensy 4.0 is packed with powerful hardware, I don't see how any of that hardware is going to help you much with creating BCLK from LRCLK. There are 7 PLLs in the clock generator (aka "CCM"), but all of those PLLs are designed to take a 24 MHz input signal. Even if you could somehow get LRCLK to the input of any of those PLLs, their lock range is very unlikely to extend all the way down to ~100 kHz.

Perhaps you could implement a delay locked loop, using PWM outputs to create BCLK & LRCLK and software to gradually adjust to get them in phase sync with the reference clock. But like all DLLs, you can expect quite a lot of phase jitter. Probably not what you want for a high quality audio setup!

I'm pretty sure you're going to need a real analog PLL chip to create BCLK (mult by 32 or 64) or MCLK (mult by 256). This just isn't a use case NXP built into the hardware.
I'm pretty sure you're going to need a real analog PLL chip to create BCLK (mult by 32 or 64) or MCLK (mult by 256). This just isn't a use case NXP built into the hardware.

Thanks Paul. That's a pity. Looks like I'm back to the STM32H7 MCU series then as that can multiply the LRCLK by up to 256 with extremely low jitter - but is an absolute PITA with dreadful support :-( I'd assumed the NXP chip would have roughly the same capabilities as they compete for the same design-ins but obviously not always.
Not open for further replies.