You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/06/05 18:54:29 UTC

[incubator-nuttx] 02/03: boards/arm/stm32/olimex-stm32-p407: Add support for the CS4344 audio driver.

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit d001c82bc6376f411b34e0dbaacd24004d260a40
Author: Ouss4 <ab...@gmail.com>
AuthorDate: Wed Jun 3 15:45:41 2020 +0100

    boards/arm/stm32/olimex-stm32-p407: Add support for the CS4344 audio
    driver.
---
 .../olimex-stm32-p407/configs/audio/defconfig      |  78 ++++++++++
 boards/arm/stm32/olimex-stm32-p407/include/board.h |  18 +++
 boards/arm/stm32/olimex-stm32-p407/src/Make.defs   |   4 +
 .../olimex-stm32-p407/src/olimex-stm32-p407.h      |  34 +++++
 .../stm32/olimex-stm32-p407/src/stm32_bringup.c    |  10 ++
 .../arm/stm32/olimex-stm32-p407/src/stm32_cs4344.c | 169 +++++++++++++++++++++
 6 files changed, 313 insertions(+)

diff --git a/boards/arm/stm32/olimex-stm32-p407/configs/audio/defconfig b/boards/arm/stm32/olimex-stm32-p407/configs/audio/defconfig
new file mode 100644
index 0000000..8dbdbd0
--- /dev/null
+++ b/boards/arm/stm32/olimex-stm32-p407/configs/audio/defconfig
@@ -0,0 +1,78 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="olimex-stm32-p407"
+CONFIG_ARCH_BOARD_OLIMEX_STM32P407=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP="stm32"
+CONFIG_ARCH_CHIP_STM32=y
+CONFIG_ARCH_CHIP_STM32F407ZG=y
+CONFIG_ARCH_IRQBUTTONS=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_AUDIO=y
+CONFIG_AUDIO_CS4344=y
+CONFIG_AUDIO_EXCLUDE_TONE=y
+CONFIG_AUDIO_EXCLUDE_VOLUME=y
+CONFIG_AUDIO_I2S=y
+CONFIG_BOARD_LATE_INITIALIZE=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DRIVERS_AUDIO=y
+CONFIG_FAT_LCNAMES=y
+CONFIG_FAT_LFN=y
+CONFIG_FS_FAT=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MAX_TASKS=16
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_NFILE_DESCRIPTORS=8
+CONFIG_NFILE_STREAMS=8
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_GET=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_DISABLE_PUT=y
+CONFIG_NSH_DISABLE_WGET=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_NXPLAYER_DEFAULT_MEDIADIR="/mnt/music"
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PREALLOC_WDOGS=8
+CONFIG_RAM_SIZE=131072
+CONFIG_RAM_START=0x20000000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_HPWORKPRIORITY=192
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_START_YEAR=2013
+CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
+CONFIG_STM32_DMA1=y
+CONFIG_STM32_I2S3=y
+CONFIG_STM32_I2S3_TX=y
+CONFIG_STM32_I2S_MCK=y
+CONFIG_STM32_JTAG_SW_ENABLE=y
+CONFIG_STM32_OTGFS=y
+CONFIG_STM32_PWR=y
+CONFIG_STM32_SPI3=y
+CONFIG_STM32_SPI3_DMA=y
+CONFIG_STM32_SPI_DMA=y
+CONFIG_STM32_USART3=y
+CONFIG_STM32_USBHOST=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_NSH_CXXINITIALIZE=y
+CONFIG_SYSTEM_NXPLAYER=y
+CONFIG_TASK_NAME_SIZE=32
+CONFIG_USART3_SERIAL_CONSOLE=y
+CONFIG_USBHOST_MSC=y
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_WDOG_INTRESERVE=1
diff --git a/boards/arm/stm32/olimex-stm32-p407/include/board.h b/boards/arm/stm32/olimex-stm32-p407/include/board.h
index e906dd5..e5f5992 100644
--- a/boards/arm/stm32/olimex-stm32-p407/include/board.h
+++ b/boards/arm/stm32/olimex-stm32-p407/include/board.h
@@ -341,4 +341,22 @@
 #define BOARD_DHTXX_GPIO_OUTPUT  GPIO_DHTXX_PIN_OUTPUT
 #define BOARD_DHTXX_FRTIMER      1  /* Free-run timer 1 */
 
+/* SPI3 DMA -- As used for I2S DMA transfer with the audio configuration */
+
+#define GPIO_SPI3_MISO    GPIO_SPI3_MISO_1
+#define GPIO_SPI3_MOSI    GPIO_SPI3_MOSI_1
+#define GPIO_SPI3_SCK     GPIO_SPI3_SCK_1
+
+#define DMACHAN_SPI3_RX   DMAMAP_SPI3_RX_1
+#define DMACHAN_SPI3_TX   DMAMAP_SPI3_TX_1
+
+/* I2S3 - CS4344 configuration uses I2S3 */
+
+#define GPIO_I2S3_SD      GPIO_I2S3_SD_1
+#define GPIO_I2S3_CK      GPIO_I2S3_CK_1
+#define GPIO_I2S3_WS      GPIO_I2S3_WS_2
+
+#define DMACHAN_I2S3_RX   DMAMAP_SPI3_RX_2
+#define DMACHAN_I2S3_TX   DMAMAP_SPI3_TX_2
+
 #endif /* __BOARDS_ARM_STM32_OLIMEX_STM32_P407_INCLUDE_BOARD_H */
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/Make.defs b/boards/arm/stm32/olimex-stm32-p407/src/Make.defs
index 7272d4b..7274cc9 100644
--- a/boards/arm/stm32/olimex-stm32-p407/src/Make.defs
+++ b/boards/arm/stm32/olimex-stm32-p407/src/Make.defs
@@ -67,6 +67,10 @@ ifeq ($(CONFIG_CAN),y)
   CSRCS += stm32_can.c
 endif
 
+ifeq ($(CONFIG_AUDIO_CS4344),y)
+  CSRCS += stm32_cs4344.c
+endif
+
 DEPPATH += --dep-path board
 VPATH += :board
 CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h b/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h
index f3abd4a..c5e380a 100644
--- a/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h
+++ b/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h
@@ -48,6 +48,7 @@
 #include <nuttx/config.h>
 #include <nuttx/compiler.h>
 #include <stdint.h>
+#include <arch/stm32/chip.h>
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -187,6 +188,18 @@
 #  define GPIO_OTGFS_OVER (GPIO_INPUT|GPIO_FLOAT|GPIO_PORTB|GPIO_PIN10)
 #endif
 
+/* The CS4344 depends on the CS4344 driver and I2S3 support */
+
+#if defined(CONFIG_AUDIO_CS4344) && defined(CONFIG_STM32_I2S3)
+#  define HAVE_CS4344
+#endif
+
+#ifdef HAVE_CS4344
+  /* The CS4344 transfers data on I2S3 */
+
+#  define CS4344_I2S_BUS      3
+#endif
+
 #ifndef __ASSEMBLY__
 
 /****************************************************************************
@@ -290,5 +303,26 @@ int stm32_adc_setup(void);
 int stm32_can_setup(void);
 #endif
 
+/****************************************************************************
+ * Name: stm32_cs4344_initialize
+ *
+ * Description:
+ *   This function is called by platform-specific, setup logic to configure
+ *   and register the CS4344 device.  This function will register the driver
+ *   as /dev/audio/pcm[x] where x is determined by the minor device number.
+ *
+ * Input Parameters:
+ *   minor - The input device minor number
+ *
+ * Returned Value:
+ *   Zero is returned on success.  Otherwise, a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_AUDIO_CS4344
+int stm32_cs4344_initialize(int minor);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_STM32_OLIMEX_STM32_P407_SRC_H */
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c
index 8ba3ae8..7431d87 100644
--- a/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c
+++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c
@@ -213,6 +213,16 @@ int stm32_bringup(void)
     }
 #endif
 
+#ifdef HAVE_CS4344
+  /* Configure CS4344 audio */
+
+  ret = stm32_cs4344_initialize(1);
+  if (ret != OK)
+    {
+      serr("Failed to initialize CS43L22 audio: %d\n", ret);
+    }
+#endif
+
   UNUSED(ret);
   return OK;
 }
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_cs4344.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_cs4344.c
new file mode 100644
index 0000000..9ddac44
--- /dev/null
+++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_cs4344.c
@@ -0,0 +1,169 @@
+/****************************************************************************
+ * boards/arm/stm32/stm32f4discovery/src/stm32_cs4344.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <debug.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/audio/i2s.h>
+#include <nuttx/audio/pcm.h>
+#include <nuttx/audio/cs4344.h>
+
+#include <arch/board/board.h>
+
+#include "stm32.h"
+#include "olimex-stm32-p407.h"
+
+#ifdef HAVE_CS4344
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_cs4344_initialize
+ *
+ * Description:
+ *   This function is called by platform-specific, setup logic to configure
+ *   and register the CS4344 device.  This function will register the driver
+ *   as /dev/audio/pcm[x] where x is determined by the minor device number.
+ *
+ * Input Parameters:
+ *   minor - The input device minor number
+ *
+ * Returned Value:
+ *   Zero is returned on success.  Otherwise, a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int stm32_cs4344_initialize(int minor)
+{
+  FAR struct audio_lowerhalf_s *cs4344;
+  FAR struct audio_lowerhalf_s *pcm;
+  FAR struct i2s_dev_s *i2s;
+  static bool initialized = false;
+  char devname[12];
+  int ret;
+
+  audinfo("minor %d\n", minor);
+  DEBUGASSERT(minor >= 0 && minor <= 25);
+
+  /* Have we already initialized?  Since we never uninitialize we must prevent
+   * multiple initializations.  This is necessary, for example, when the
+   * touchscreen example is used as a built-in application in NSH and can be
+   * called numerous time.  It will attempt to initialize each time.
+   */
+
+  if (!initialized)
+    {
+      /* Get an instance of the I2S interface for the CS4344 data channel */
+
+      i2s = stm32_i2sbus_initialize(CS4344_I2S_BUS);
+      if (!i2s)
+        {
+          auderr("ERROR: Failed to initialize I2S%d\n", CS4344_I2S_BUS);
+          ret = -ENODEV;
+          goto errout;
+        }
+
+      /* Now we can use this I2S interface to initialize the CS4344 which
+       * will return an audio interface.
+       */
+
+      cs4344 = cs4344_initialize(i2s);
+      if (!cs4344)
+        {
+          auderr("ERROR: Failed to initialize the CS4344\n");
+          ret = -ENODEV;
+          goto errout;
+        }
+
+      /* No we can embed the CS4344/I2S conglomerate into a PCM decoder
+       * instance so that we will have a PCM front end for the the CS4344
+       * driver.
+       */
+
+      pcm = pcm_decode_initialize(cs4344);
+      if (!pcm)
+        {
+          auderr("ERROR: Failed create the PCM decoder\n");
+          ret = -ENODEV;
+          goto errout;
+        }
+
+      /* Create a device name */
+
+      snprintf(devname, 12, "pcm%d",  minor);
+
+      /* Finally, we can register the PCM/CS4344/I2S audio device.
+       *
+       * Is anyone young enough to remember Rube Goldberg?
+       */
+
+      ret = audio_register(devname, pcm);
+      if (ret < 0)
+        {
+          auderr("ERROR: Failed to register /dev/%s device: %d\n",
+                 devname, ret);
+          goto errout;
+        }
+
+      /* Now we are initialized */
+
+      initialized = true;
+    }
+
+  return OK;
+
+errout:
+  return ret;
+}
+
+#endif /* HAVE_CS4344 */