mirror of
https://github.com/apache/nuttx.git
synced 2026-05-20 04:16:35 +08:00
esp_i2s: use actual channel count for BCLK calculation
The I2S BCLK frequency is calculated as: bclk = sample_rate * total_slot * data_width Previously, total_slot was always taken from the static config (esp_i2s0_config / esp_i2s1_config), which is hardcoded to 2. This is correct for mono and stereo, but wrong for TDM modes with more than 2 channels (e.g. 4-channel recording with ES7210). With 4 channels but total_slot=2, the BCLK is only half of what it should be, causing the actual sample rate to be half of the requested rate (e.g. requesting 16 kHz actually samples at 8 kHz). Replace priv->config->total_slot with MAX(priv->channels, 2) in all three BCLK calculation sites (i2s_check_mclkfrequency and i2s_set_clock for both master and slave paths). The MIN of 2 preserves the I2S protocol requirement that at least 2 slots exist even for mono, while correctly scaling for multi-channel TDM configurations. Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
@@ -26,6 +26,8 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
@@ -288,8 +290,6 @@
|
||||
# define I2S_RCC_ATOMIC()
|
||||
#endif
|
||||
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@@ -2012,7 +2012,7 @@ static int32_t i2s_check_mclkfrequency(struct esp_i2s_s *priv)
|
||||
{
|
||||
uint32_t mclk_freq;
|
||||
uint32_t mclk_multiple = priv->mclk_multiple;
|
||||
uint32_t bclk = priv->rate * priv->config->total_slot * priv->data_width;
|
||||
uint32_t bclk = priv->rate * MAX(priv->channels, 2) * priv->data_width;
|
||||
int i;
|
||||
|
||||
/* If the master clock is divisible by both the sample rate and the bit
|
||||
@@ -2146,7 +2146,7 @@ static void i2s_set_clock(struct esp_i2s_s *priv)
|
||||
|
||||
if (priv->config->role == I2S_ROLE_MASTER)
|
||||
{
|
||||
bclk = priv->rate * priv->config->total_slot *
|
||||
bclk = priv->rate * MAX(priv->channels, 2) *
|
||||
priv->config->data_width;
|
||||
mclk = priv->mclk_freq;
|
||||
bclk_div = mclk / bclk;
|
||||
@@ -2156,7 +2156,7 @@ static void i2s_set_clock(struct esp_i2s_s *priv)
|
||||
/* For slave mode, mclk >= bclk * 8, so fix bclk_div to 2 first */
|
||||
|
||||
bclk_div = 8;
|
||||
bclk = priv->rate * priv->config->total_slot *
|
||||
bclk = priv->rate * MAX(priv->channels, 2) *
|
||||
priv->config->data_width;
|
||||
mclk = bclk * bclk_div;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user