Skip to content

Conversation

@raiker
Copy link
Contributor

@raiker raiker commented Apr 7, 2023

In I2S, I2SO_BCK and I2SI_BCK are generated from I2S_TX_CLK and I2S_RX_CLK respectively using an integer clock divider (ref ESP32C3 TRM p607). The existing code uses a x256 multiplier of the sample rate to generate I2S_?X_CLK in all cases. However, because 24 isn't a power of two, that means that there isn't a valid integer divisor when the bit depth is set to 24.
e.g. 2 channels, 24-bits, 48 kHz:

  • BCLK should be 2.304 MHz
  • MCLK is computed as 12.288 MHz
  • MLCK / BCK = 5.33333...

Since we don't have a fractional divider, the closest integer is 5, which causes the BCLK to run at 2.4576 MHz and the LRCLK to run at 51.2 kHz, which is too fast.
The only way to avoid this is to use a different multiplier, one that is a multiple of 24. My CODEC (TI PCM3060) accepts 192, which seems like a reasonable option.
This patch modifies the calculate_clock function to make it use 192 for the 24-bit case and 256 in all others (all the other supported bit depths are powers of two).

I've tested this change on an esp32c3 and verified that the BCLK and LRCLK are correct after the change.

Copy link
Contributor

@bjoernQ bjoernQ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Thanks for your contribution

@bjoernQ bjoernQ merged commit 696b21b into esp-rs:main Apr 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants