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;