You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/10/26 16:09:07 UTC
[incubator-nuttx] branch master updated (dfcfce24f6 -> 0bf7afad25)
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
from dfcfce24f6 New configuration for CAN bus
new 6f1fbc29ee audio/i2s: add i2s_mclkfrequency method to the I2S lower half
new 41475e11e0 drivers/audio: fix CS4344 supported sample rates
new b4b0624f6a drivers/audio: add support for setting I2S's mclk on CS4344 codec
new 0bf7afad25 xtensa/esp32: add i2s_mclkfrequency to set master clock on I2S
The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
arch/xtensa/src/esp32/esp32_i2s.c | 62 ++++++++++++---
drivers/audio/cs4344.c | 159 ++++++++++++++++++++++++++++++++++++--
drivers/audio/cs4344.h | 5 ++
include/nuttx/audio/i2s.h | 28 +++++++
4 files changed, 240 insertions(+), 14 deletions(-)
[incubator-nuttx] 03/04: drivers/audio: add support for setting I2S's mclk on CS4344 codec
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit b4b0624f6a465dff72c356c9add43a801eb32b29
Author: Tiago Medicci Serrano <ti...@espressif.com>
AuthorDate: Sun Oct 23 10:30:39 2022 -0300
drivers/audio: add support for setting I2S's mclk on CS4344 codec
Set the mclk frequency on I2S lower half by 1) checking supported
sample rate, data width and mclk multiplier table and 2) setting
this value using the I2S_MCLKFREQUENCY macro. I2S driver may or
may not implement the i2s_mclkfrequency method for setting the
master clock.
---
drivers/audio/cs4344.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++--
drivers/audio/cs4344.h | 5 ++
2 files changed, 159 insertions(+), 4 deletions(-)
diff --git a/drivers/audio/cs4344.c b/drivers/audio/cs4344.c
index 3c49b9586b..45e6ecc0c7 100644
--- a/drivers/audio/cs4344.c
+++ b/drivers/audio/cs4344.c
@@ -54,6 +54,7 @@
* Private Function Prototypes
****************************************************************************/
+static int cs4344_setmclkfrequency(FAR struct cs4344_dev_s *priv);
static void cs4344_setdatawidth(FAR struct cs4344_dev_s *priv);
static void cs4344_setbitrate(FAR struct cs4344_dev_s *priv);
@@ -154,10 +155,138 @@ static const struct audio_ops_s g_audioops =
cs4344_release /* release */
};
+struct mclk_rate_s
+{
+ uint32_t mclk_freq; /* Master clock frequency (in Hz) */
+ uint32_t sample_rate; /* Sample rate (in Hz) */
+ uint16_t multiple; /* Multiple of the mclk_freq to the sample_rate */
+};
+
+static const struct mclk_rate_s mclk_rate[] =
+{
+ {
+ 8192000, /* mclk_freq */
+ 16000, /* sample_rate */
+ 512, /* multiple */
+ },
+ {
+ 12288000, /* mclk_freq */
+ 16000, /* sample_rate */
+ 768, /* multiple */
+ },
+ {
+ 11289600, /* mclk_freq */
+ 22050, /* sample_rate */
+ 512, /* multiple */
+ },
+ {
+ 8192000, /* mclk_freq */
+ 32000, /* sample_rate */
+ 256, /* multiple */
+ },
+ {
+ 12288000, /* mclk_freq */
+ 32000, /* sample_rate */
+ 384, /* multiple */
+ },
+ {
+ 11289600, /* mclk_freq */
+ 44100, /* sample_rate */
+ 256, /* multiple */
+ },
+ {
+ 16934400, /* mclk_freq */
+ 44100, /* sample_rate */
+ 384, /* multiple */
+ },
+ {
+ 22579200, /* mclk_freq */
+ 44100, /* sample_rate */
+ 512, /* multiple */
+ },
+ {
+ 12288000, /* mclk_freq */
+ 48000, /* sample_rate */
+ 256, /* multiple */
+ },
+ {
+ 18432000, /* mclk_freq */
+ 48000, /* sample_rate */
+ 384, /* multiple */
+ },
+ {
+ 24576000, /* mclk_freq */
+ 48000, /* sample_rate */
+ 512, /* multiple */
+ },
+};
+
/****************************************************************************
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: cs4344_setmclkfrequency
+ *
+ * Description:
+ * Set the frequency of the Master Clock (MCLK)
+ *
+ * Input Parameters:
+ * priv - A reference to the driver state structure
+ *
+ * Returned Value:
+ * Returns OK or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static int cs4344_setmclkfrequency(FAR struct cs4344_dev_s *priv)
+{
+ int ret = OK;
+ int i;
+
+ priv->mclk_freq = 0;
+
+ for (i = 0; i < ARRAY_SIZE(mclk_rate); i++)
+ {
+ if (mclk_rate[i].sample_rate == priv->samprate)
+ {
+ /* Normally master clock should be multiple of the sample rate
+ * and bclk at the same time. The field mclk_rate_s::multiple
+ * means the multiple of mclk to the sample rate. This value
+ * should be divisible by the size (in bytes) of the sample,
+ * otherwise the ws signal will be inaccurate. For instance,
+ * if data width is 24 bits, in order to keep mclk a multiple
+ * to the bclk, the mclk_rate_s::multiple should be divisible
+ * by the size of the sample, i.e, 24 / 8 = 3.
+ */
+
+ priv->mclk_freq = mclk_rate[i].mclk_freq;
+
+ /* Check if the current master clock frequency is divisible by
+ * the size (in bytes) of the sample. If so, we have a perfect
+ * match. Otherwise, try to find a more suitable value for the
+ * master clock.
+ */
+
+ if (mclk_rate[i].multiple % (priv->bpsamp / 8) == 0)
+ {
+ break;
+ }
+ }
+ }
+
+ if (priv->mclk_freq != 0)
+ {
+ ret = I2S_MCLKFREQUENCY(priv->i2s, priv->mclk_freq);
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
+
+ return ret > 0 ? OK : ret;
+}
+
/****************************************************************************
* Name: cs4344_setdatawidth
*
@@ -407,6 +536,8 @@ cs4344_configure(FAR struct audio_lowerhalf_s *dev,
case AUDIO_TYPE_OUTPUT:
{
+ ret = OK;
+
audinfo(" AUDIO_TYPE_OUTPUT:\n");
audinfo(" Number of channels: %u\n", caps->ac_channels);
audinfo(" Sample rate: %u\n", caps->ac_controls.hw[0]);
@@ -414,11 +545,11 @@ cs4344_configure(FAR struct audio_lowerhalf_s *dev,
/* Verify that all of the requested values are supported */
- ret = -ERANGE;
if (caps->ac_channels != 1 && caps->ac_channels != 2)
{
auderr("ERROR: Unsupported number of channels: %d\n",
caps->ac_channels);
+ ret = -ERANGE;
break;
}
@@ -426,6 +557,7 @@ cs4344_configure(FAR struct audio_lowerhalf_s *dev,
{
auderr("ERROR: Unsupported bits per sample: %d\n",
caps->ac_controls.b[2]);
+ ret = -ERANGE;
break;
}
@@ -435,13 +567,30 @@ cs4344_configure(FAR struct audio_lowerhalf_s *dev,
priv->nchannels = caps->ac_channels;
priv->bpsamp = caps->ac_controls.b[2];
- /* Reconfigure the FLL to support the resulting number or channels,
- * bits per sample, and bitrate.
+ /* Reconfigure the master clock to support the resulting number of
+ * channels, data width, and sample rate. However, if I2S lower half
+ * doesn't provide support for setting the master clock, execution
+ * goes on and try just to set the data width and sample rate.
*/
+ ret = cs4344_setmclkfrequency(priv);
+ if (ret != OK)
+ {
+ if (ret != -ENOTTY)
+ {
+ auderr("ERROR: Unsupported combination of sample rate and"
+ "data width\n");
+ break;
+ }
+ else
+ {
+ audwarn("WARNING: MCLK could not be set on lower half\n");
+ priv->mclk_freq = 0;
+ }
+ }
+
cs4344_setdatawidth(priv);
cs4344_setbitrate(priv);
- ret = OK;
}
break;
@@ -1255,6 +1404,7 @@ static void cs4344_reset(FAR struct cs4344_dev_s *priv)
priv->samprate = CS4344_DEFAULT_SAMPRATE;
priv->nchannels = CS4344_DEFAULT_NCHANNELS;
priv->bpsamp = CS4344_DEFAULT_BPSAMP;
+ priv->mclk_freq = 0;
/* Configure the FLL and the LRCLK */
diff --git a/drivers/audio/cs4344.h b/drivers/audio/cs4344.h
index 0244372b39..92a0d6b3f0 100644
--- a/drivers/audio/cs4344.h
+++ b/drivers/audio/cs4344.h
@@ -41,6 +41,10 @@
* Pre-Processor Definitions
****************************************************************************/
+#ifndef ARRAY_SIZE
+# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
#define CS4344_DEFAULT_SAMPRATE 11025 /* Initial sample rate */
#define CS4344_DEFAULT_NCHANNELS 1 /* Initial number of channels */
#define CS4344_DEFAULT_BPSAMP 16 /* Initial bits per sample */
@@ -76,6 +80,7 @@ struct cs4344_dev_s
uint16_t samprate; /* Configured samprate (samples/sec) */
uint8_t nchannels; /* Number of channels (1 or 2) */
uint8_t bpsamp; /* Bits per sample (8 or 16) */
+ uint32_t mclk_freq; /* Master clock frequency */
volatile uint8_t inflight; /* Number of audio buffers in-flight */
bool running; /* True: Worker thread is running */
bool paused; /* True: Playing is paused */
[incubator-nuttx] 04/04: xtensa/esp32: add i2s_mclkfrequency to set master clock on I2S
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 0bf7afad253a16b81c6c5712c453dd759f758d41
Author: Tiago Medicci Serrano <ti...@espressif.com>
AuthorDate: Sun Oct 23 10:41:42 2022 -0300
xtensa/esp32: add i2s_mclkfrequency to set master clock on I2S
---
arch/xtensa/src/esp32/esp32_i2s.c | 62 +++++++++++++++++++++++++++++++++------
1 file changed, 53 insertions(+), 9 deletions(-)
diff --git a/arch/xtensa/src/esp32/esp32_i2s.c b/arch/xtensa/src/esp32/esp32_i2s.c
index ee907050f0..830b25b728 100644
--- a/arch/xtensa/src/esp32/esp32_i2s.c
+++ b/arch/xtensa/src/esp32/esp32_i2s.c
@@ -242,6 +242,7 @@ struct esp32_i2s_s
sem_t exclsem; /* Assures mutually exclusive access */
uint32_t rate; /* I2S actual configured sample-rate */
uint32_t data_width; /* I2S actual configured data_width */
+ uint32_t mclk_freq; /* I2S actual master clock */
int cpuint; /* I2S interrupt ID */
uint8_t cpu; /* CPU ID */
spinlock_t lock; /* Device specific lock. */
@@ -305,13 +306,15 @@ static void i2s_tx_schedule(struct esp32_i2s_s *priv,
/* I2S methods (and close friends) */
+static uint32_t esp32_i2s_mclkfrequency(struct i2s_dev_s *dev,
+ uint32_t frequency);
static uint32_t esp32_i2s_txsamplerate(struct i2s_dev_s *dev,
- uint32_t rate);
+ uint32_t rate);
static uint32_t esp32_i2s_txdatawidth(struct i2s_dev_s *dev, int bits);
static int esp32_i2s_send(struct i2s_dev_s *dev,
- struct ap_buffer_s *apb,
- i2s_callback_t callback, void *arg,
- uint32_t timeout);
+ struct ap_buffer_s *apb,
+ i2s_callback_t callback, void *arg,
+ uint32_t timeout);
/****************************************************************************
* Private Data
@@ -319,9 +322,10 @@ static int esp32_i2s_send(struct i2s_dev_s *dev,
static const struct i2s_ops_s g_i2sops =
{
- .i2s_txsamplerate = esp32_i2s_txsamplerate,
- .i2s_txdatawidth = esp32_i2s_txdatawidth,
- .i2s_send = esp32_i2s_send,
+ .i2s_txsamplerate = esp32_i2s_txsamplerate,
+ .i2s_txdatawidth = esp32_i2s_txdatawidth,
+ .i2s_send = esp32_i2s_send,
+ .i2s_mclkfrequency = esp32_i2s_mclkfrequency,
};
#ifdef CONFIG_ESP32_I2S0
@@ -395,7 +399,7 @@ static const struct esp32_i2s_config_s esp32_i2s1_config =
.data_width = CONFIG_ESP32_I2S1_DATA_BIT_WIDTH,
.rate = CONFIG_ESP32_I2S1_SAMPLE_RATE,
.total_slot = 2,
- .mclk_multiple = I2S_MCLK_MULTIPLE_384,
+ .mclk_multiple = I2S_MCLK_MULTIPLE_256,
.tx_en = I2S1_TX_ENABLED,
.rx_en = I2S1_RX_ENABLED,
#ifdef CONFIG_ESP32_I2S1_MCLK
@@ -1132,6 +1136,10 @@ static void i2s_configure(struct esp32_i2s_s *priv)
modifyreg32(I2S_FIFO_CONF_REG(priv->config->port), 0,
I2S_TX_FIFO_MOD_FORCE_EN);
+ esp32_i2s_mclkfrequency((struct i2s_dev_s *)priv,
+ (priv->config->rate *
+ priv->config->mclk_multiple));
+
esp32_i2s_txsamplerate((struct i2s_dev_s *)priv, priv->config->rate);
}
@@ -1225,6 +1233,42 @@ static int esp32_i2s_interrupt(int irq, void *context, void *arg)
return 0;
}
+/****************************************************************************
+ * Name: esp32_i2s_mclkfrequency
+ *
+ * Description:
+ * Set the master clock frequency. Usually, the MCLK is a multiple of the
+ * sample rate. Most of the audio codecs require setting specific MCLK
+ * frequency according to the sample rate.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * frequency - The I2S master clock's frequency
+ *
+ * Returned Value:
+ * Returns the resulting master clock or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+static uint32_t esp32_i2s_mclkfrequency(struct i2s_dev_s *dev,
+ uint32_t frequency)
+{
+ struct esp32_i2s_s *priv = (struct esp32_i2s_s *)dev;
+
+ /* Check if the master clock frequency is beyond the highest possible
+ * value and return an error.
+ */
+
+ if (frequency >= (I2S_LL_BASE_CLK / 2))
+ {
+ return -EINVAL;
+ }
+
+ priv->mclk_freq = frequency;
+
+ return frequency;
+}
+
/****************************************************************************
* Name: esp32_i2s_txsamplerate
*
@@ -1276,7 +1320,7 @@ static uint32_t esp32_i2s_txsamplerate(struct i2s_dev_s *dev, uint32_t rate)
if (priv->config->role == I2S_ROLE_MASTER)
{
bclk = rate * priv->config->total_slot * priv->data_width;
- mclk = rate * priv->config->mclk_multiple;
+ mclk = priv->mclk_freq;
bclk_div = mclk / bclk;
}
else
[incubator-nuttx] 01/04: audio/i2s: add i2s_mclkfrequency method to the I2S lower half
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 6f1fbc29eee746f22e24b57e16e17514fb19b184
Author: Tiago Medicci Serrano <ti...@espressif.com>
AuthorDate: Sun Oct 23 10:18:09 2022 -0300
audio/i2s: add i2s_mclkfrequency method to the I2S lower half
This method allows the codec driver to set a specific mclk
frequency for the I2S lower half. This provides support to change
it on run time according to the supported master clock frequency
of the audio codec, the sample rate and the data width.
---
include/nuttx/audio/i2s.h | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/include/nuttx/audio/i2s.h b/include/nuttx/audio/i2s.h
index 0aab79abc6..22224b27f7 100644
--- a/include/nuttx/audio/i2s.h
+++ b/include/nuttx/audio/i2s.h
@@ -225,6 +225,29 @@
#define I2S_SEND(d,b,c,a,t) \
((d)->ops->i2s_send ? (d)->ops->i2s_send(d,b,c,a,t) : -ENOTTY)
+/****************************************************************************
+ * Name: I2S_MCLKFREQUENCY
+ *
+ * Description:
+ * Set the master clock frequency. Usually, the MCLK is a multiple of the
+ * sample rate. Most of the audio codecs require setting specific MCLK
+ * frequency according to the sample rate. NOTE: this parameter may not
+ * be implemented on I2S driver. If not implemented, the I2S may set
+ * internally any value to the master clock (or even does not support it).
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * frequency - The I2S master clock's frequency
+ *
+ * Returned Value:
+ * Returns the resulting master clock or a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#define I2S_MCLKFREQUENCY(d,f) \
+ ((d)->ops->i2s_mclkfrequency ? \
+ (d)->ops->i2s_mclkfrequency(d,f) : -ENOTTY)
+
/****************************************************************************
* Name: I2S_IOCTL
*
@@ -286,6 +309,11 @@ struct i2s_ops_s
FAR void *arg,
uint32_t timeout);
+ /* Master Clock methods */
+
+ CODE uint32_t (*i2s_mclkfrequency)(FAR struct i2s_dev_s *dev,
+ uint32_t frequency);
+
/* Ioctl */
CODE int (*i2s_ioctl)(FAR struct i2s_dev_s *dev,
[incubator-nuttx] 02/04: drivers/audio: fix CS4344 supported sample rates
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 41475e11e0ebb1738454231c59d24cc4d43bf97c
Author: Tiago Medicci Serrano <ti...@espressif.com>
AuthorDate: Sun Oct 23 10:28:50 2022 -0300
drivers/audio: fix CS4344 supported sample rates
---
drivers/audio/cs4344.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/audio/cs4344.c b/drivers/audio/cs4344.c
index ae956ef222..3c49b9586b 100644
--- a/drivers/audio/cs4344.c
+++ b/drivers/audio/cs4344.c
@@ -272,7 +272,6 @@ static int cs4344_getcaps(FAR struct audio_lowerhalf_s *dev, int type,
/* Report the Sample rates we support */
caps->ac_controls.b[0] =
- AUDIO_SAMP_RATE_8K | AUDIO_SAMP_RATE_11K |
AUDIO_SAMP_RATE_16K | AUDIO_SAMP_RATE_22K |
AUDIO_SAMP_RATE_32K | AUDIO_SAMP_RATE_44K |
AUDIO_SAMP_RATE_48K;