2023-12-04 01:17 PM
Hi,
I use a STM32F767 Nucleo-144 board with a STM32F767ZIT6 processor.
With CubeIDE I configure SPI1 as I2S1 input and pump the data via DMA2/Stream0 in a short 8x16Bit circular buffer. The clock of the SPI1 is at ~ 3MHz .I set up the HAL_I2S_RxHalfCpltCallback() and HAL_I2S_RxCpltCallback() routines. In both routines i toggle a GPIO and get a ~23.8kHz square wave. This all works as exspected.
But: The square wave suffers from a big jitter. First, there is a constant jitter in the range of 100ns. Second, sometimes the duty cycle (not the frequency) of the signal changes by ~330ns for some parts of a second. 330ns ist the reciprocal of my 3MHz clock.
How can I get rid of the jitter? I tried to slim down HAL_DMA_IRQHandler() to the necessary parts for my use case. That did not affect the jitter. I also changed the NVIC priorities with no effect.
How can I get rid of the jitter?
THX
Cheers
Detlef
Solved! Go to Solution.
2023-12-07 09:43 PM
Any other interrupts active?
For clean 96 kHz with a F767 you need a dedicated 24.576 MHz (or better 49.152 MHz if you want to switch to 192 kHz later on) oscillator at I2S_CKIN. Or as HSE, then again you might get some PLL jitter (which is not too bad, as I found out by using PLL driven TX SPDIF, actually with a F767).
2023-12-07 11:49 PM
One way to solve this is to feed back externally the bit clock from SPI/I2S into a timer's pin and use that timer in external clock mode to generate framing using PWM. There may be some sub-TIM-clock-period jitter from mismatch of I2S and TIM clock.
A better way may be to use PLL so that the system clock and I2S clock are set up identically or having an integer mutual ratio, that should remove source of abovementioned jitter. In that case you also might be able to start timer and I2S in a way that they are synchronous, although it's not simple, removing the need to feed back clock externally. As LCE said above, this will probably require a specific frequency crystal, if you are after some particular frequency, although it may quite well be that you don't need some of the "usual audio" frequencies anyway, as you are going to process the signal locally (i.e. don't depend on other equipment into which digital signal is going to be fed, which might require the "usual frequencies").
Yet another, and possibly better, way may be to use SAI set up so that the framing clock output fulfills your requirement, or use two synchronized SAIs, one generating the I2S signal and other generating the framing signal.
A similar method may be to use two I2S clocked from the same PLL tap (if they are available), use one to generate the I2S signal and the other to generate framing alone, with different divider setting.
JW
2023-12-09 11:14 AM
As I told previously, the SAI peripheral is preferred. Not only the SAI streams can be run from the same clock, but they are also designed to be started synchronously. One stream can capture the PDM audio and the other can generate basically any bitstream, including a square wave.