summaryrefslogtreecommitdiff
path: root/nuttx
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-05-21 13:13:05 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-05-21 13:13:05 -0600
commit801977de7c84d03616329795e1c59929ab948906 (patch)
treeb9d9220000c01cf9aca8e010f43fc488ccc26f26 /nuttx
parent3895e0ec4c2c3057935bbeb7558fa4b815385334 (diff)
downloadnuttx-801977de7c84d03616329795e1c59929ab948906.tar.gz
nuttx-801977de7c84d03616329795e1c59929ab948906.tar.bz2
nuttx-801977de7c84d03616329795e1c59929ab948906.zip
Audio subystem update from Ken Pettit. Plus moved some header files
Diffstat (limited to 'nuttx')
-rw-r--r--nuttx/ChangeLog6
-rw-r--r--nuttx/arch/arm/src/stm32/chip.h2
-rw-r--r--nuttx/audio/Kconfig32
-rw-r--r--nuttx/audio/audio.c177
-rw-r--r--nuttx/audio/buffer.c2
-rw-r--r--nuttx/audio/pcm.c2
-rw-r--r--nuttx/configs/mikroe-stm32f4/src/Makefile4
-rw-r--r--nuttx/configs/mikroe-stm32f4/src/mikroe-stm32f4-internal.h23
-rw-r--r--nuttx/configs/mikroe-stm32f4/src/up_nsh.c21
-rw-r--r--nuttx/configs/mikroe-stm32f4/src/up_spi.c15
-rw-r--r--nuttx/configs/mikroe-stm32f4/src/up_vs1053.c200
-rw-r--r--nuttx/configs/open1788/README.txt30
-rw-r--r--nuttx/drivers/audio/vs1053.c161
-rw-r--r--nuttx/drivers/audio/vs1053.h222
-rw-r--r--nuttx/include/nuttx/audio/audio.h (renamed from nuttx/include/nuttx/audio.h)63
-rw-r--r--nuttx/include/nuttx/audio/vs1053.h122
-rw-r--r--nuttx/include/nuttx/spi.h3
17 files changed, 979 insertions, 106 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 70ae0e381..aaef727c5 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -4761,3 +4761,9 @@
* configs/lm3s6965-ek/discover: Add an example configuration for UDP
discovery tool on the lm3s6965-ek board. From Max Holtberg
(2013-5-21).
+ * audio/, drivers/audio, include/nuttx/audio: Added a callback interface
+ to the Audio upperhalf driver for dequeueing, reporting async events,
+ etc. Also included is some initial work for the VS1053 driver. From
+ Ken Pettit (2013-5-21).
+ * include/nuttx/audio/audio.h: Moved from include/nuttx/ to include/nuttx/audio.
+ (2013-5-21). \ No newline at end of file
diff --git a/nuttx/arch/arm/src/stm32/chip.h b/nuttx/arch/arm/src/stm32/chip.h
index d498162b7..dead451b5 100644
--- a/nuttx/arch/arm/src/stm32/chip.h
+++ b/nuttx/arch/arm/src/stm32/chip.h
@@ -87,7 +87,7 @@
/* STM32F103ZC, STM32F103ZD, and STM32F103ZE are all provided in 144 pin packages and differ
* only in the available FLASH and SRAM.
*/
-# elif defined(CONFIG_ARCH_CHIP_STM32F103ZET6)
+# elif defined(CONFIG_ARCH_CHIP_STM32F103ZET6)
# include "chip/stm32f103ze_pinmap.h"
/* STM32 F105/F107 Connectivity Line */
diff --git a/nuttx/audio/Kconfig b/nuttx/audio/Kconfig
index a666c775f..7ce503aaf 100644
--- a/nuttx/audio/Kconfig
+++ b/nuttx/audio/Kconfig
@@ -27,6 +27,36 @@ config AUDIO_LARGE_BUFFERS
32-bit max sample count for increased samples / buffer capability.
channel capability.
+config AUDIO_CUSTOM_DEV_PATH
+ bool "Use custom device path"
+ default n
+ ---help---
+ By default, all audio devices on the target are are registered in the
+ /dev/audio directory. Select this option to change the default location
+ for the device registration.
+
+if AUDIO_CUSTOM_DEV_PATH
+
+config AUDIO_DEV_ROOT
+ bool "Place audio devices in /dev"
+ default n
+ ---help---
+ This option causes all device entries to appear in /dev with all the
+ other device entries. This option generates the smallest code and
+ RAM footprint.
+
+if !AUDIO_DEV_ROOT
+
+config AUDIO_DEV_PATH
+ string "Base path for Audio devices"
+ default "/dev/audio"
+ ---help---
+ The path on the target where audio devices are registered. The default
+ is to place all audio devices in the /dev/audio/ directory.
+
+endif
+endif
+
menu "Supported Audio Formats"
config AUDIO_FORMAT_PCM
@@ -55,7 +85,7 @@ config AUDIO_FORMAT_OGG_VORBIS
endmenu
-# These are here as placeholders of what could be added
+# These are here as placeholders of what could be added
if CONFIG_AUDIO_PLANNED
diff --git a/nuttx/audio/audio.c b/nuttx/audio/audio.c
index 4457294f9..444412c97 100644
--- a/nuttx/audio/audio.c
+++ b/nuttx/audio/audio.c
@@ -59,7 +59,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/arch.h>
-#include <nuttx/audio.h>
+#include <nuttx/audio/audio.h>
#include <arch/irq.h>
@@ -94,12 +94,14 @@ struct audio_upperhalf_s
* Private Function Prototypes
****************************************************************************/
-static int audio_open(FAR struct file *filep);
-static int audio_close(FAR struct file *filep);
-static ssize_t audio_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
-static ssize_t audio_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
-static int audio_start(FAR struct audio_upperhalf_s *upper, unsigned int oflags);
-static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+static int audio_open(FAR struct file *filep);
+static int audio_close(FAR struct file *filep);
+static ssize_t audio_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
+static ssize_t audio_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
+static int audio_start(FAR struct audio_upperhalf_s *upper, unsigned int oflags);
+static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
+static void audio_callback(FAR void *priv, uint16_t reason,
+ FAR struct ap_buffer_s *apb, uint16_t status);
/****************************************************************************
* Private Data
@@ -169,7 +171,7 @@ static int audio_open(FAR struct file *filep)
errout_with_sem:
sem_post(&upper->exclsem);
-
+
errout:
return ret;
}
@@ -226,7 +228,7 @@ static int audio_close(FAR struct file *filep)
//errout_with_sem:
sem_post(&upper->exclsem);
-
+
errout:
return ret;
}
@@ -264,7 +266,7 @@ static ssize_t audio_write(FAR struct file *filep, FAR const char *buffer, size_
*
* Description:
* Handle the AUDIOIOC_START ioctl command
- *
+ *
************************************************************************************/
static int audio_start(FAR struct audio_upperhalf_s *upper, unsigned int oflags)
@@ -302,7 +304,7 @@ static int audio_start(FAR struct audio_upperhalf_s *upper, unsigned int oflags)
*
* Description:
* The standard ioctl method. This is where ALL of the Audio work is done.
- *
+ *
************************************************************************************/
static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
@@ -351,7 +353,8 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
audvdbg("AUDIOIOC_INITIALIZE: Device=%d", caps->ac_type);
/* Call the lower-half driver configure handler */
- ret = lower->ops->configure(lower, caps);
+
+ ret = lower->ops->configure(lower, caps, &audio_callback, upper);
}
break;
@@ -374,7 +377,7 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
case AUDIOIOC_START:
{
- audvdbg("AUDIOIOC_START\n");
+ audvdbg("AUDIOIOC_START\n");
DEBUGASSERT(lower->ops->start != NULL);
/* Start the pulse train */
@@ -434,8 +437,8 @@ static int audio_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
* Input parameters:
* path - The full path to the driver to be registers in the NuttX pseudo-
* filesystem. The recommended convention is to name Audio drivers
- * based on the function they provide, such as "/dev/pcm0", "/dev/mp31",
- * etc.
+ * based on the function they provide, such as "/dev/pcm0", "/dev/mp31",
+ * etc.
* dev - A pointer to an instance of lower half audio driver. This instance
* is bound to the Audio driver and must persists as long as the driver
* persists.
@@ -450,7 +453,13 @@ int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev)
FAR struct audio_upperhalf_s *upper;
char path[AUDIO_MAX_DEVICE_PATH];
static bool dev_audio_created = false;
+#ifndef CONFIG_AUDIO_CUSTOM_DEV_PATH
const char* devname = "/dev/audio";
+#elif !defined(CONFIG_AUDIO_DEV_ROOT)
+ const char* devname = CONFIG_AUDIO_DEV_PATH;
+ const char* ptr;
+ char* pathptr;
+#endif
/* Allocate the upper-half data structure */
@@ -466,6 +475,80 @@ int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev)
sem_init(&upper->exclsem, 0, 1);
upper->dev = dev;
+#ifdef CONFIG_AUDIO_CUSTOM_DEV_PATH
+
+#ifdef CONFIG_AUDIO_DEV_ROOT
+
+ /* This is the simple case ... No need to make a directory */
+
+ strcpy(path, "/dev/");
+ strcat(path, name);
+
+#else
+ /* Ensure the path begins with "/dev" as we don't support placing device
+ * anywhere but in the /dev directory
+ */
+
+ DEBUGASSERT(strncmp(devname, "/dev", 4) == 0);
+
+ /* Create a /dev/audio directory. */
+
+ if (!dev_audio_created)
+ {
+ /* Get path name after "/dev" */
+
+ ptr = &devname[4];
+ if (*ptr == '/')
+ {
+ ptr++;
+ }
+
+ strcpy(path, "/dev/");
+ pathptr = &path[5];
+
+ /* Do mkdir for each segment of the path */
+
+ while (*ptr != '\0')
+ {
+ /* Build next path segment into path variable */
+
+ while (*ptr != '/' && *ptr != '\0')
+ {
+ *pathptr++ = *ptr++;
+ }
+ *pathptr = '\0';
+
+ /* Make this level of directory */
+
+ mkdir(path, 0644);
+
+ /* Check for another level */
+
+ *pathptr++ = '/';
+ if (*ptr == '/')
+ {
+ ptr++;
+ }
+ }
+
+ /* Indicate we have created the audio dev path */
+
+ dev_audio_created = true;
+ }
+
+ /* Now build the path for registration */
+
+ strcpy(path, devname);
+ if (devname[sizeof(devname)-1] != '/')
+ {
+ strcat(path, "/");
+ }
+ strcat(path, name);
+
+#endif /* CONFIG_AUDIO_DEV_PATH=="/dev" */
+
+#else /* CONFIG_AUDIO_CUSTOM_DEV_PATH */
+
/* Create a /dev/audio directory. */
if (!dev_audio_created)
@@ -485,6 +568,7 @@ int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev)
strcpy(path, devname);
strcat(path, "/");
strncat(path, name, AUDIO_MAX_DEVICE_PATH - 11);
+#endif
audvdbg("Registering %s\n", path);
return register_driver(path, &g_audioops, 0666, upper);
@@ -496,7 +580,7 @@ int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev)
* Description:
* Dequeues a previously enqueued Audio Pipeline Buffer.
*
- * 1. The upper half driver calls the enqueuebuffer method, providing the
+ * 1. The upper half driver calls the enqueuebuffer method, providing the
* lower half driver with the ab_buffer to process.
* 2. The lower half driver's enqueuebuffer will either processes the
* buffer directly, or more likely add it to a queue for processing
@@ -505,13 +589,14 @@ int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev)
* ab_buffer, it will call this routine to indicated processing of the
* buffer is complete.
* 4. When this routine is called, it will check if any threads are waiting
- * to enqueue additional buffers and "wake them up" for further
+ * to enqueue additional buffers and "wake them up" for further
* processing.
*
* Input parameters:
* handle - This is the handle that was provided to the lower-half
* start() method.
* apb - A pointer to the previsously enqueued ap_buffer_s
+ * status - Status of the dequeue operation
*
* Returned Value:
* None
@@ -521,14 +606,66 @@ int audio_register(FAR const char *name, FAR struct audio_lowerhalf_s *dev)
*
****************************************************************************/
-void audio_dequeuebuffer(FAR void *handle, FAR struct ap_buffer_s *apb)
+static inline void audio_dequeuebuffer(FAR struct audio_upperhalf_s *upper,
+ FAR struct ap_buffer_s *apb, uint16_t status)
{
- //FAR struct audio_upperhalf_s *upper = (FAR struct audio_upperhalf_s *)handle;
-
audllvdbg("Entry\n");
/* TODO: Implement the logic */
}
+/****************************************************************************
+ * Name: audio_callback
+ *
+ * Description:
+ * Provides a callback interface for lower-half drivers to call to the
+ * upper-half for buffer dequeueing, error reporting, etc.
+ *
+ * Input parameters:
+ * priv - Private context data owned by the upper-half
+ * reason - The reason code for the callback
+ * apb - A pointer to the previsously enqueued ap_buffer_s
+ * status - Status information associated with the callback
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * This function may be called from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static void audio_callback(FAR void *handle, uint16_t reason,
+ FAR struct ap_buffer_s *apb, uint16_t status)
+{
+ FAR struct audio_upperhalf_s *upper = (FAR struct audio_upperhalf_s *)handle;
+
+ audllvdbg("Entry\n");
+
+ /* Perform operation based on reason code */
+
+ switch (reason)
+ {
+ case AUDIO_CALLBACK_DEQUEUE:
+ {
+ /* Call the dequeue routine */
+
+ audio_dequeuebuffer(upper, apb, status);
+ break;
+ }
+
+ case AUDIO_CALLBACK_IOERR:
+ {
+ }
+ break;
+
+ default:
+ {
+ auddbg("Unknown callback reason code %d\n", reason);
+ break;
+ }
+ }
+}
+
#endif /* CONFIG_AUDIO */
diff --git a/nuttx/audio/buffer.c b/nuttx/audio/buffer.c
index d6c6ac930..3906891f6 100644
--- a/nuttx/audio/buffer.c
+++ b/nuttx/audio/buffer.c
@@ -50,7 +50,7 @@
#include <debug.h>
#include <nuttx/kmalloc.h>
-#include <nuttx/audio.h>
+#include <nuttx/audio/audio.h>
#include <nuttx/usb/audio.h>
#if defined(CONFIG_AUDIO)
diff --git a/nuttx/audio/pcm.c b/nuttx/audio/pcm.c
index 4f77c67c5..aeb1b7b64 100644
--- a/nuttx/audio/pcm.c
+++ b/nuttx/audio/pcm.c
@@ -50,7 +50,7 @@
#include <debug.h>
#include <nuttx/kmalloc.h>
-#include <nuttx/audio.h>
+#include <nuttx/audio/audio.h>
#if defined(CONFIG_AUDIO) && defined(CONFIG_AUDIO_FORMAT_PCM)
diff --git a/nuttx/configs/mikroe-stm32f4/src/Makefile b/nuttx/configs/mikroe-stm32f4/src/Makefile
index c166e1926..5ca1fe3ee 100644
--- a/nuttx/configs/mikroe-stm32f4/src/Makefile
+++ b/nuttx/configs/mikroe-stm32f4/src/Makefile
@@ -94,6 +94,10 @@ ifeq ($(CONFIG_LCD_MIO283QT2),y)
CSRCS += up_mio283qt2.c
endif
+ifeq ($(CONFIG_VS1053),y)
+CSRCS += up_vs1053.c
+endif
+
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
diff --git a/nuttx/configs/mikroe-stm32f4/src/mikroe-stm32f4-internal.h b/nuttx/configs/mikroe-stm32f4/src/mikroe-stm32f4-internal.h
index d1a69547e..0f6894316 100644
--- a/nuttx/configs/mikroe-stm32f4/src/mikroe-stm32f4-internal.h
+++ b/nuttx/configs/mikroe-stm32f4/src/mikroe-stm32f4-internal.h
@@ -92,7 +92,9 @@
GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN3)
#define GPIO_CS_FLASH (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN7)
-#define GPIO_CS_MP3 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
+#define GPIO_CS_MP3_DATA (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
+ GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN9)
+#define GPIO_CS_MP3_CMD (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN8)
#define GPIO_CS_EXP_SPI3 (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
GPIO_OUTPUT_SET|GPIO_PORTD|GPIO_PIN0)
@@ -182,6 +184,13 @@
#define GPIO_TP_XL (GPIO_ANALOG|GPIO_PORTB|GPIO_PIN1)
+/* MP3 Codec control pins */
+
+#define GPIO_VS1053_RST (GPIO_OUTPUT|GPIO_PUSHPULL|GPIO_SPEED_50MHz|\
+ GPIO_OUTPUT_SET|GPIO_PORTC|GPIO_PIN7)
+#define GPIO_VS1053_DREQ (GPIO_INPUT|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN6)
+
+
/****************************************************************************************************
* Public Types
****************************************************************************************************/
@@ -258,5 +267,17 @@ void stm32_lcdinitialize(void);
int up_lcdinitialize(void);
#endif
+/****************************************************************************************************
+ * Name: up_vs1053initialize
+ *
+ * Description:
+ * Initialize the VS1053 Audio CODEC hardware.
+ *
+ ****************************************************************************************************/
+
+#ifdef CONFIG_VS1053
+void up_vs1053initialize(FAR struct spi_dev_s *spi);
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __CONFIGS_MIKROE_STM32F4_SRC_MIKROE_STM32F4_INTERNAL_H */
diff --git a/nuttx/configs/mikroe-stm32f4/src/up_nsh.c b/nuttx/configs/mikroe-stm32f4/src/up_nsh.c
index 648f69c64..366e4e8f6 100644
--- a/nuttx/configs/mikroe-stm32f4/src/up_nsh.c
+++ b/nuttx/configs/mikroe-stm32f4/src/up_nsh.c
@@ -64,7 +64,7 @@
#endif
#ifdef CONFIG_AUDIO
-# include "nuttx/audio.h"
+# include "nuttx/audio/audio.h"
#endif
#include "stm32.h"
@@ -182,9 +182,6 @@ int nsh_archinitialize(void)
FAR struct spi_dev_s *spi;
FAR struct mtd_dev_s *mtd;
#endif
-#ifdef CONFIG_AUDIO
- FAR struct audio_lowerhalf_s *pVs1053;
-#endif
int ret;
/* Configure SPI-based devices */
@@ -351,21 +348,13 @@ int nsh_archinitialize(void)
#endif
- /* Configure the Audio sub-system if enabled */
+ /* Configure the Audio sub-system if enabled and bind it to SPI 3 */
#ifdef CONFIG_AUDIO
- pVs1053 = vs1053_initialize(0);
- if (pVs1053 == NULL)
- {
- message("nsh_archinitialize: Failed to initialize VS1053 Audio module\n");
- }
- else
- {
- /* Bind the vs1053 to the audio upper-half driver */
- audio_register("mp30", pVs1053);
- }
+ up_vs1053initialize(spi);
+
+#endif
-#endif /* CONFIG_AUDIO */
return OK;
}
diff --git a/nuttx/configs/mikroe-stm32f4/src/up_spi.c b/nuttx/configs/mikroe-stm32f4/src/up_spi.c
index 08fa89a9c..448ed966a 100644
--- a/nuttx/configs/mikroe-stm32f4/src/up_spi.c
+++ b/nuttx/configs/mikroe-stm32f4/src/up_spi.c
@@ -114,8 +114,10 @@ void weak_function stm32_spiinitialize(void)
#endif
#ifdef CONFIG_AUDIO_MP3_CODEC
- (void)stm32_configgpio(GPIO_CS_MP3); /* MP3 codec chip select */
- stm32_gpiowrite(GPIO_CS_MP3, 1); /* Ensure the CS is inactive */
+ (void)stm32_configgpio(GPIO_CS_MP3_DATA); /* MP3 codec chip select for DATA */
+ (void)stm32_configgpio(GPIO_CS_MP3_CMD); /* MP3 codec chip select for CMD */
+ stm32_gpiowrite(GPIO_CS_MP3_DATA, 1); /* Ensure the CS is inactive */
+ stm32_gpiowrite(GPIO_CS_MP3_CMD, 1); /* Ensure the CS is inactive */
#endif
/* Configure the EXP I/O cs for SPI3 */
@@ -172,11 +174,16 @@ void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool sele
#endif
#if defined(CONFIG_AUDIO_MP3_CODEC)
- if (devid == SPIDEV_AUDIO)
+ if (devid == SPIDEV_AUDIO_DATA)
{
- stm32_gpiowrite(GPIO_CS_MP3, !selected);
+ stm32_gpiowrite(GPIO_CS_MP3_DATA, !selected);
+ }
+ else if (devid == SPIDEV_AUDIO_CTRL)
+ {
+ stm32_gpiowrite(GPIO_CS_MP3_CMD, !selected);
}
else
+
#endif
/* Must be the expansion header device */
diff --git a/nuttx/configs/mikroe-stm32f4/src/up_vs1053.c b/nuttx/configs/mikroe-stm32f4/src/up_vs1053.c
new file mode 100644
index 000000000..cc7e0f96d
--- /dev/null
+++ b/nuttx/configs/mikroe-stm32f4/src/up_vs1053.c
@@ -0,0 +1,200 @@
+/****************************************************************************
+ * configs/mikroe-stm32f4/src/up_vs1053.c
+ *
+ * Copyright (C) 2013 Ken Pettit. All rights reserved.
+ * Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <debug.h>
+
+#include <nuttx/spi.h>
+#include <nuttx/audio/audio.h>
+#include <nuttx/audio/vs1053.h>
+
+#include <arch/board/board.h>
+
+#include "chip.h"
+#include "up_arch.h"
+#include "mikroe-stm32f4-internal.h"
+
+#ifdef CONFIG_VS1053
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/* VS1053 is on SPI3 */
+
+#ifndef CONFIG_STM32_SPI3
+# error "Need CONFIG_STM32_SPI3 in the configuration"
+#endif
+
+/* SPI Assumptions **********************************************************/
+
+#define VS1053_SPI_PORTNO 3 /* On SPI3 */
+#define VS1053_DEVNO 0 /* Only one VS1053 */
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct stm32_lower_s
+{
+ const struct vs1053_lower_s lower; /* Low-level MCU interface */
+ xcpt_t handler; /* VS1053 interrupt handler */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int up_attach(FAR const struct vs1053_lower_s *lower, xcpt_t handler);
+static void up_enable(FAR const struct vs1053_lower_s *lower);
+static void up_disable(FAR const struct vs1053_lower_s *lower);
+static void up_reset(FAR const struct vs1053_lower_s *lower, bool state);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The VS1053 provides interrupts to the MCU via a GPIO pin. The
+ * following structure provides an MCU-independent mechanixm for controlling
+ * the VS1053 GPIO interrupt.
+ */
+
+static struct stm32_lower_s g_vs1053lower =
+{
+ .lower =
+ {
+ .attach = up_attach,
+ .enable = up_enable,
+ .disable = up_disable,
+ .reset = up_reset
+ },
+ .handler = NULL,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: struct vs1053_lower_s methods
+ ****************************************************************************/
+
+static int up_attach(FAR const struct vs1053_lower_s *lower, xcpt_t handler)
+{
+ FAR struct stm32_lower_s *priv = (FAR struct stm32_lower_s *)lower;
+
+ /* Just save the handler for use when the interrupt is enabled */
+
+ priv->handler = handler;
+ return OK;
+}
+
+static void up_enable(FAR const struct vs1053_lower_s *lower)
+{
+ FAR struct stm32_lower_s *priv = (FAR struct stm32_lower_s *)lower;
+
+ DEBUGASSERT(priv->handler);
+ (void)stm32_gpiosetevent(GPIO_VS1053_DREQ, false, true, true, priv->handler);
+}
+
+static void up_disable(FAR const struct vs1053_lower_s *lower)
+{
+ (void)stm32_gpiosetevent(GPIO_VS1053_DREQ, false, true, true, NULL);
+}
+
+static void up_reset(FAR const struct vs1053_lower_s *lower, bool state)
+{
+ stm32_gpiowrite(GPIO_VS1053_RST, state);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_netinitialize
+ ****************************************************************************/
+
+void up_vs1053initialize(FAR struct spi_dev_s* spi)
+{
+ int ret;
+ int x;
+ char name[8];
+ FAR struct audio_lowerhalf_s *pVs1053;
+
+ /* Assumptions:
+ * 1) SPI pins were configured in up_spi.c early in the boot-up phase.
+ * 2) Clocking for the SPI1 peripheral was also provided earlier in boot-up.
+ */
+
+ /* Take VS1053 out of reset (active low)*/
+
+ (void)stm32_configgpio(GPIO_VS1053_RST);
+ (void)stm32_configgpio(GPIO_VS1053_DREQ);
+
+ stm32_gpiowrite(GPIO_VS1053_RST, 0);
+ for (x = 0; x < 10000; x++);
+ stm32_gpiowrite(GPIO_VS1053_RST, 1);
+
+ /* Bind the SPI port to the VS1053 driver */
+
+ pVs1053 = vs1053_initialize(spi, &g_vs1053lower.lower, VS1053_DEVNO);
+ if (ret < 0)
+ {
+ audlldbg("Failed to bind SPI port %d VS1053 device: %d\n",
+ VS1053_DEVNO, ret);
+ return;
+ }
+
+ /* Now register the audio device */
+
+ sprintf(name, "mp3%d", VS1053_DEVNO);
+ ret = audio_register(name, pVs1053);
+ if (ret < 0)
+ {
+ auddbg("up_vs1053initialize: Failed to register VS1053 Audio device\n");
+ }
+
+ audllvdbg("Bound SPI port to VS1053 device %s\n", name);
+}
+
+#endif /* CONFIG_VS1053 */
diff --git a/nuttx/configs/open1788/README.txt b/nuttx/configs/open1788/README.txt
index 0dc559f02..c15985d16 100644
--- a/nuttx/configs/open1788/README.txt
+++ b/nuttx/configs/open1788/README.txt
@@ -120,7 +120,7 @@ FPU
If you are using a toolchain other than the Atollic toolchain, then to use the FPU
you will also have to modify the CFLAGS to enable compiler support for the ARMv7-M
FPU. As of this writing, there are not many GCC toolchains that will support the
- ARMv7-M FPU.
+ ARMv7-M FPU.
As a minimum you will need to add CFLAG options to (1) enable hardware floating point
code generation, and to (2) select the FPU implementation. You might try the same
@@ -211,7 +211,7 @@ Using OpenOCD with the Olimex ARM-USB-OCD
I have been using the Olimex ARM-USB-OCD debugger. OpenOCD
requires a configuration file. I keep the one I used last here:
-
+
configs/open1788/tools/open1788.cfg
However, the "correct" configuration script to use with OpenOCD may
@@ -240,7 +240,7 @@ Using OpenOCD with the Olimex ARM-USB-OCD
NOTE: These files could also be located under /usr/share in some
installations. They could be most anywhwere if you are using a
windows version of OpenOCD.
-
+
configs/open1788/tools/open1788.cfg
This is simply openocd-usb.cfg, lpc1788.cfg, and lpc17xx.cfg
concatenated into one file for convenience. Don't use it
@@ -249,7 +249,7 @@ Using OpenOCD with the Olimex ARM-USB-OCD
There is also a script on the tools/ directory that I use to start
the OpenOCD daemon on my system called oocd.sh. That script will
probably require some modifications to work in another environment:
-
+
- Possibly the value of OPENOCD_PATH and TARGET_PATH
- It assumes that the correct script to use is the one at
configs/open1788/tools/open1788.cfg
@@ -283,7 +283,7 @@ Using OpenOCD with the Olimex ARM-USB-OCD
use the 'monitor' (or simply 'mon') command to invoke these sub-
commands. These GDB commands will send comments to the OpenOCD monitor.
Here are a couple that you will need to use:
-
+
(gdb) monitor reset
(gdb) monitor halt
@@ -309,17 +309,17 @@ Using OpenOCD with the Olimex ARM-USB-OCD
3. I find that there are often undetected write failures when using
the Olimex ARM-USB-OCD debugber and that if you start the program
- with a bad FLASH failure, it will lock up OpenOCD. I usually
+ with a bad FLASH failure, it will lock up OpenOCD. I usually
oad nuttx twice, restarting OpenOCD in between in order to assure
good FLASH contents:
-
+
(gdb) mon halt
(gdb) load nuttx
(gdb) mon reset
Exit GDB, kill the OpenOCD server, recycle power on the board,
restart the OpenOCD server and GDB, then:
-
+
(gdb) mon halt
(gdb) load nuttx
(gdb) mon reset
@@ -340,12 +340,12 @@ CONFIGURATION
=============
ostest
- ------
+ ------
This configuration directory, performs a simple OS test using
apps/examples/ostest.
NOTES:
-
+
1. This configuration uses the mconf-based configuration tool. To
change this configuration using that tool, you should:
@@ -377,7 +377,7 @@ CONFIGURATION
binaries (pass2)
NOTES:
-
+
1. This configuration uses the mconf-based configuration tool. To
change this configuration using that tool, you should:
@@ -475,7 +475,7 @@ CONFIGURATION
Configuration enables only the serial NSH interface.
NOTES:
-
+
1. This configuration uses the mconf-based configuration tool. To
change this configuration using that tool, you should:
@@ -539,7 +539,7 @@ CONFIGURATION
System Type:
CONFIG_GPIO_IRQ=y : GPIO interrupt support
CONFIG_LPC17_SSP1=y : Enable support for SSP1
-
+
Applicaton Configuration:
CONFIG_EXAMPLES_TOUCHSCREEN=y : Enable the touchscreen built-int test
CONFIG_EXAMPLES_TOUCHSCREEN_BUILTIN=y
@@ -596,7 +596,7 @@ CONFIGURATION
CONFIG_EXAMPLES_BUTTONS_NAME5="JOYSTICK_C"
CONFIG_EXAMPLES_BUTTONS_NAME6="JOYSTICK_D"
CONFIG_EXAMPLES_BUTTONS_NAME7="JOYSTICK_CTR"
-
+
nxlines
-------
Configures the graphics example located at examples/nsh. This
@@ -605,7 +605,7 @@ CONFIGURATION
panel.
NOTES:
-
+
1. This configuration uses the mconf-based configuration tool. To
change this configuration using that tool, you should:
diff --git a/nuttx/drivers/audio/vs1053.c b/nuttx/drivers/audio/vs1053.c
index 6f143acf9..b8aa7e41f 100644
--- a/nuttx/drivers/audio/vs1053.c
+++ b/nuttx/drivers/audio/vs1053.c
@@ -55,12 +55,19 @@
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
-#include <nuttx/audio.h>
+#include <nuttx/audio/audio.h>
+#include <nuttx/audio/vs1053.h>
+
+#include "vs1053.h"
/****************************************************************************
* Private Definitions
****************************************************************************/
+#ifndef CONFIG_VS1053_SPIMODE
+# define CONFIG_VS1053_SPIMODE SPIDEV_MODE0
+#endif
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -70,7 +77,7 @@ struct vs1053_struct_s
FAR struct audio_lowerhalf_s lower; /* We derive the Audio lower half */
/* Our specific driver data goes here */
- int spidevice; /* Placeholder device data */
+ FAR struct spi_dev_s *spi; /* Pointer to the SPI bus */
};
@@ -81,13 +88,16 @@ struct vs1053_struct_s
static int vs1053_getcaps(FAR struct audio_lowerhalf_s *lower, int type,
FAR struct audio_caps_s *pCaps);
static int vs1053_configure(FAR struct audio_lowerhalf_s *lower,
- FAR const struct audio_caps_s *pCaps);
+ FAR const struct audio_caps_s *pCaps, audio_callback_t upper,
+ FAR void *priv);
static int vs1053_shutdown(FAR struct audio_lowerhalf_s *lower);
-static int vs1053_start(FAR struct audio_lowerhalf_s *lower);
+static int vs1053_start(FAR struct audio_lowerhalf_s *lower);
static int vs1053_stop(FAR struct audio_lowerhalf_s *lower);
-static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower,
+static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower,
FAR struct ap_buffer_s *apb);
-static int vs1053_ioctl(FAR struct audio_lowerhalf_s *lower, int cmd,
+static int vs1053_cancelbuffer(FAR struct audio_lowerhalf_s *lower,
+ FAR struct ap_buffer_s *apb);
+static int vs1053_ioctl(FAR struct audio_lowerhalf_s *lower, int cmd,
unsigned long arg);
/****************************************************************************
@@ -102,6 +112,7 @@ static const struct audio_ops_s g_audioops =
vs1053_start, /* start */
vs1053_stop, /* stop */
vs1053_enqueuebuffer, /* enqueue_buffer */
+ vs1053_cancelbuffer, /* cancel_buffer */
vs1053_ioctl /* ioctl */
};
@@ -109,6 +120,73 @@ static const struct audio_ops_s g_audioops =
* Private Functions
****************************************************************************/
+/************************************************************************************
+ * Name: vs1053_spi_lock
+ ************************************************************************************/
+
+static void vs1053_spi_lock(FAR struct spi_dev_s *dev)
+{
+ /* On SPI busses where there are multiple devices, it will be necessary to
+ * lock SPI to have exclusive access to the busses for a sequence of
+ * transfers. The bus should be locked before the chip is selected.
+ *
+ * This is a blocking call and will not return until we have exclusiv access to
+ * the SPI buss. We will retain that exclusive access until the bus is unlocked.
+ */
+
+ (void)SPI_LOCK(dev, true);
+
+ /* After locking the SPI bus, the we also need call the setfrequency, setbits, and
+ * setmode methods to make sure that the SPI is properly configured for the device.
+ * If the SPI buss is being shared, then it may have been left in an incompatible
+ * state.
+ */
+
+ SPI_SETMODE(dev, CONFIG_VS1053_SPIMODE);
+ SPI_SETBITS(dev, 8);
+ (void)SPI_SETFREQUENCY(dev, 20000000);
+}
+
+/************************************************************************************
+ * Name: vs1053_spi_unlock
+ ************************************************************************************/
+
+static inline void vs1053_spi_unlock(FAR struct spi_dev_s *dev)
+{
+ (void)SPI_LOCK(dev, false);
+}
+
+/************************************************************************************
+ * Name: vs1053_readreg - Read the specified 16-bit register from the
+ * VS1053 device. Caller must hold the SPI lock.
+ ************************************************************************************/
+
+static uint16_t vs1053_readreg(FAR struct vs1053_struct_s *dev, uint16_t reg)
+{
+ uint16_t ret;
+ FAR struct spi_dev_s *spi = dev->spi;
+
+ /* Select the AUDIO_CTRL device on the SPI bus */
+
+ SPI_SELECT(spi, SPIDEV_AUDIO_CTRL, true);
+
+ /* Send the WRITE command followed by the address */
+
+ SPI_SEND(spi, VS1053_OPCODE_READ);
+ SPI_SEND(spi, reg);
+
+ /* Now read the 16-bit value */
+
+ ret = SPI_SEND(spi, 0xFF) << 8;
+ ret |= SPI_SEND(spi, 0xFF);
+
+ /* Deselect the CODEC */
+
+ SPI_SELECT(spi, SPIDEV_AUDIO_CTRL, false);
+
+ return ret;
+}
+
/****************************************************************************
* Name: vs1053_getcaps
*
@@ -126,15 +204,24 @@ static int vs1053_getcaps(FAR struct audio_lowerhalf_s *lower, int type,
/****************************************************************************
* Name: vs1053_configure
*
- * Description: Configure the audio device for the specified mode of
+ * Description: Configure the audio device for the specified mode of
* operation.
*
****************************************************************************/
static int vs1053_configure(FAR struct audio_lowerhalf_s *lower,
- FAR const struct audio_caps_s *pCaps)
+ FAR const struct audio_caps_s *pCaps, audio_callback_t upper,
+ FAR void *priv)
{
audvdbg("Entry\n");
+
+ /* Save the binding to the upper level operations and private data */
+
+ lower->upper = upper;
+ lower->priv = priv;
+
+ /* Now process the configure operation */
+
return OK;
}
@@ -163,7 +250,7 @@ static int vs1053_shutdown(FAR struct audio_lowerhalf_s *lower)
static int vs1053_start(FAR struct audio_lowerhalf_s *lower)
{
//struct vs1053_struct_s *dev = (struct vs1053_struct_s *) lower;
-
+
/* Perform the start */
return OK;
@@ -191,7 +278,20 @@ static int vs1053_stop(FAR struct audio_lowerhalf_s *lower)
*
****************************************************************************/
-static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower,
+static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower,
+ FAR struct ap_buffer_s *apb )
+{
+ return OK;
+}
+
+/****************************************************************************
+ * Name: vs1053_cancelbuffer
+ *
+ * Description: Called when an enqueued buffer is being cancelled.
+ *
+ ****************************************************************************/
+
+static int vs1053_cancelbuffer(FAR struct audio_lowerhalf_s *lower,
FAR struct ap_buffer_s *apb )
{
return OK;
@@ -204,7 +304,7 @@ static int vs1053_enqueuebuffer(FAR struct audio_lowerhalf_s *lower,
*
****************************************************************************/
-static int vs1053_ioctl(FAR struct audio_lowerhalf_s *lower, int cmd,
+static int vs1053_ioctl(FAR struct audio_lowerhalf_s *lower, int cmd,
unsigned long arg)
{
return OK;
@@ -226,18 +326,19 @@ static int vs1053_ioctl(FAR struct audio_lowerhalf_s *lower, int cmd,
*
****************************************************************************/
-struct audio_lowerhalf_s *vs1053_initialize(int spidevice)
+struct audio_lowerhalf_s *vs1053_initialize(FAR struct spi_dev_s *spi,
+ FAR const struct vs1053_lower_s *lower,
+ unsigned int devno)
{
struct vs1053_struct_s *dev;
+ uint16_t status;
+ uint8_t id;
/* Sanity check */
-#ifdef CONFIG_DEBUG
- if (spidevice < 0 || spidevice > 3)
- {
- return NULL;
- }
-#endif
+ DEBUGASSERT(spi != NULL);
+ DEBUGASSERT(lower != NULL);
+ DEBUGASSERT(lower->reset != NULL);
/* Allocate a VS1053 device structure */
@@ -247,10 +348,32 @@ struct audio_lowerhalf_s *vs1053_initialize(int spidevice)
/* Initialize the SMART device structure */
dev->lower.ops = &g_audioops;
+ dev->lower.upper = NULL;
+ dev->lower.priv = NULL;
/* Save our specific device data */
- dev->spidevice = spidevice;
+ dev->spi = spi;
+
+ /* Reset the VS1053 chip */
+
+ lower->reset(lower, false);
+ up_udelay(4000);
+ lower->reset(lower, true);
+
+ /* Do device detection to validate the chip is there.
+ * We have to hold the SPI lock during reads / writes.
+ */
+
+ vs1053_spi_lock(spi);
+ status = vs1053_readreg(dev, VS1053_SCI_STATUS);
+ vs1053_spi_unlock(spi);
+
+ id = (status & VS1053_SS_VER) >> VS1053_VER_SHIFT;
+ if (id != VS1053_VER_VS1053)
+ {
+ auddbg("Unexpected VER bits: 0x%0X\n", id);
+ }
}
return &dev->lower;
diff --git a/nuttx/drivers/audio/vs1053.h b/nuttx/drivers/audio/vs1053.h
new file mode 100644
index 000000000..5cdd167ae
--- /dev/null
+++ b/nuttx/drivers/audio/vs1053.h
@@ -0,0 +1,222 @@
+/****************************************************************************
+ * drivers/audio/vs1053.h
+ *
+ * Copyright (C) 2013 Ken Pettit. All rights reserved.
+ * Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_AUDIO_VS1053_H
+#define __DRIVERS_AUDIO_VS1053_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <nuttx/fs/ioctl.h>
+
+#ifdef CONFIG_AUDIO
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+
+/* SCI Instruction Opcodes **************************************************/
+
+#define VS1053_OPCODE_READ 3
+#define VS1053_OPCODE_WRITE 2
+
+/* SCI Registers on the SPI bus *********************************************/
+
+#define VS1053_SCI_MODE 0x00
+#define VS1053_SCI_STATUS 0x01
+#define VS1053_SCI_BASE 0x02
+#define VS1053_SCI_CLOCKF 0x03
+#define VS1053_SCI_DECODE_TIME 0x04
+#define VS1053_SCI_AUDATA 0x05
+#define VS1053_SCI_WRAM 0x06
+#define VS1053_SCI_WRAMADDR 0x07
+#define VS1053_SCI_HDAT0 0x08
+#define VS1053_SCI_HDAT1 0x09
+#define VS1053_SCI_AIADDR 0x0A
+#define VS1053_SCI_VOL 0x0B
+#define VS1053_SCI_AICTRL0 0x0C
+#define VS1053_SCI_AICTRL1 0x0E
+#define VS1053_SCI_AICTRL2 0x0E
+#define VS1053_SCI_AICTRL3 0x0F
+
+/* MODE register bit definitions ********************************************/
+
+#define VS1053_SM_DIFF 0x0001
+#define VS1053_SM_LAYER12 0x0002
+#define VS1053_SM_RESET 0x0004
+#define VS1053_SM_CANCEL 0x0008
+#define VS1053_SM_EARSPEAKER_LO 0x0010
+#define VS1053_SM_TESTS 0x0020
+#define VS1053_SM_STREAM 0x0040
+#define VS1053_SM_EARSPEAKER_HI 0x0080
+#define VS1053_SM_DACT 0x0100
+#define VS1053_SM_SDIORD 0x0200
+#define VS1053_SM_SDISHARE 0x0400
+#define VS1053_SM_SDINEW 0x0800
+#define VS1053_SM_ADPCM 0x1000
+#define VS1053_SM_LINE1 0x4000
+#define VS1053_SM_CLK_RANGE 0x8000
+
+/* STATUS register bit definitions ****************************************/
+
+#define VS1053_SS_DO_NOT_JUMP 0x8000
+#define VS1053_SS_SWING 0x7000
+#define VS1053_SS_VCM_OVERLOAD 0x0800
+#define VS1053_SS_VCM_DISABLE 0x0400
+#define VS1053_SS_VER 0x00F0
+#define VS1053_SS_APDOWN2 0x0008
+#define VS1053_SS_APDOWN1 0x0004
+#define VS1053_SS_AD_CLOCK 0x0002
+#define VS1053_SS_REFERENCE_SEL 0x0001
+
+#define VS1053_VER_SHIFT 4
+#define VS1053_VER_VS1001 0
+#define VS1053_VER_VS1011 1
+#define VS1053_VER_VS1002 2
+#define VS1053_VER_VS1003 3
+#define VS1053_VER_VS1053 4
+#define VS1053_VER_VS1033 5
+#define VS1053_VER_VS1063 6
+#define VS1053_VER_VS1103 7
+
+/* BASE register bit definitions ******************************************/
+
+#define VS1053_ST_AMPLITUDE 0xF000
+#define VS1053_ST_FREQLIMIT 0x0F00
+#define VS1053_SB_AMPLITUDE 0x00F0
+#define VS1053_SB_FREQLIMIT 0x000F
+
+/* CLOCKF register bit definitions ****************************************/
+
+#define VS1053_SC_MULT 0xE000
+#define VS1053_SC_ADD 0x1800
+#define VS1053_SC_FREQ 0x07FF
+
+#define VS1053_SC_MULT_XTALIx10 0
+#define VS1053_SC_MULT_XTALIx20 1
+#define VS1053_SC_MULT_XTALIx25 2
+#define VS1053_SC_MULT_XTALIx30 3
+#define VS1053_SC_MULT_XTALIx35 4
+#define VS1053_SC_MULT_XTALIx40 5
+#define VS1053_SC_MULT_XTALIx45 6
+#define VS1053_SC_MULT_XTALIx50 7
+
+#define VS1053_SC_ADD_NONE 0
+#define VS1053_SC_ADD_XTALIx10 1
+#define VS1053_SC_ADD_XTALIx15 2
+#define VS1053_SC_ADD_XTALIx20 3
+
+/* WRAM Addresses **********************************************************/
+
+#define VS1053_XRAM_BASE 0x1800 /* X data RAM */
+#define VS1053_XRAM_SIZE 256
+
+#define VS1053_YRAM_BASE 0x5800 /* Y data RAM */
+#define VS1053_YRAM_SIZE 256
+
+#define VS1053_IRAM_BASE 0x8040 /* Instruction RAM */
+#define VS1053_IRAM_SIZE 0x460
+
+#define VS1053_IO_BASE 0xC000
+#define VS1053_IO_SIZE 0x4000
+
+/* HDAT1 register values *************************************************/
+
+#define VS1053_HDAT1_WAV 0x7665 /* "ve" (as in Wave) */
+#define VS1053_HDAT1_ADTS 0x4154 /* "AT" */
+#define VS1053_HDAT1_ADIF 0x4144 /* "AD" */
+#define VS1053_HDAT1_AAC 0x4D34 /* "M4" */
+#define VS1053_HDAT1_WMA 0x574D /* "WM" */
+#define VS1053_HDAT1_MIDI 0x4D54 /* "MT" */
+#define VS1053_HDAT1_OGG 0x4F67 /* "Og" */
+
+/* MP3 special definitions for HDAT1 / 0 */
+
+#define VS1053_HDAT1_MP3_SYNC 0xFFE0 /* Stream valid */
+#define VS1053_HDAT1_MP3_ID 0x0018 /* MPG id */
+#define VS1053_HDAT1_MP3_LAYER 0x0006
+#define VS1053_HDAT1_MP3_PROTECT 0x0001 /* CRC Protect bit */
+#define VS1053_HDAT0_MP3_BITRATE 0xF000
+#define VS1053_HDAT0_MP3_SAMPRATE 0x0C00
+#define VS1053_HDAT0_MP3_PAD 0x0200
+#define VS1053_HDAT0_MP3_PRIVATE 0x0100
+#define VS1053_HDAT0_MP3_MODE 0x00C0
+#define VS1053_HDAT0_MP3_EXTENSION 0x0030
+#define VS1053_HDAT0_MP3_COPYRIGHT 0x0008
+#define VS1053_HDAT0_MP3_ORIGINAL 0x0004
+#define VS1053_HDAT0_MP3_EMPHASIS 0x0003
+
+#define VS1053_MP3_ID_SHIFT 7
+#define VS1053_MP3_ID_MPEG1 3
+#define VS1053_MP3_ID_MPEG2 2
+#define VS1053_MP3_ID_MPEG25a 1
+#define VS1053_MP3_ID_MPEG25b 0
+
+#define VS1053_MP3_LAYER_SHIFT 1
+#define VS1053_MP3_LAYER_I 3
+#define VS1053_MP3_LAYER_II 2
+#define VS1053_MP3_LAYER_III 1
+
+#define VS1053_MP3_CRC_NONE 1
+#define VS1053_MP3_CRC_PROTECT 0
+
+#define VS1053_MP3_PAD_SHIFT 9
+#define VS1053_MP3_PAD_ADDITIONAL 1
+#define VS1053_MP3_PAD_NORMAL 0
+
+#define VS1053_MP3_MODE_SHIFT 6
+#define VS1053_MP3_MODE_MONO 3
+#define VS1053_MP3_MODE_DUAL_CH 2
+#define VS1053_MP3_MODE_JSTEREO 1
+#define VS1053_MP3_MODE_STEREO 0
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#endif /* CONFIG_AUDIO */
+#endif /* __DRIVERS_AUDIO_VS1053_H */
diff --git a/nuttx/include/nuttx/audio.h b/nuttx/include/nuttx/audio/audio.h
index 1e6464adc..72b8cb573 100644
--- a/nuttx/include/nuttx/audio.h
+++ b/nuttx/include/nuttx/audio/audio.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * include/nuttx/audio.h
+ * include/nuttx/audio/audio.h
*
* Copyright (C) 2013 Ken Pettit. All rights reserved.
* Author: Ken Pettit <pettitkd@gmail.com>
@@ -33,8 +33,8 @@
*
****************************************************************************/
-#ifndef __INCLUDE_NUTTX_AUDIO_H
-#define __INCLUDE_NUTTX_AUDIO_H
+#ifndef __INCLUDE_NUTTX_AUDIO_AUDIO_H
+#define __INCLUDE_NUTTX_AUDIO_AUDIO_H
/* For the purposes of this driver, an Audio device is any device that
* generates, records, mixes, or otherwise modifies audio data in any format,
@@ -56,6 +56,7 @@
#include <nuttx/compiler.h>
#include <nuttx/fs/ioctl.h>
+#include <nuttx/spi.h>
#ifdef CONFIG_AUDIO
@@ -165,6 +166,12 @@
#define AUDIO_RATE_192K 0x08
#define AUDIO_RATE_320K 0x09
+/* Audio Callback Reasons ***************************************************/
+
+#define AUDIO_CALLBACK_UNDEF 0x00
+#define AUDIO_CALLBACK_DEQUEUE 0x01
+#define AUDIO_CALLBACK_IOERR 0x02
+
/* Audio Pipeline Buffer (AP Buffer) flags **********************************/
#define AUDIO_ABP_ALIGNMENT 0x000F /* Mask to define buffer alignment */
@@ -226,6 +233,11 @@ struct ap_buffer_s
uint8_t samp[0]; /* Offset of the first sample */
} packed_struct;
+/* Typedef for lower-level to upper-level callback for buffer dequeuing */
+
+typedef CODE void (*audio_callback_t)(FAR void *priv, uint16_t reason,
+ FAR struct ap_buffer_s *apb, uint16_t status);
+
/* This structure is a set a callback functions used to call from the upper-
* half, generic Audo driver into lower-half, platform-specific logic that
* supports the low-level functionality.
@@ -245,15 +257,17 @@ struct audio_ops_s
CODE int (*getcaps)(FAR struct audio_lowerhalf_s *dev, int type,
FAR struct audio_caps_s *pCaps);
- /* This method is called to configure the driver for a specific mode of
+ /* This method is called to bind the lower-level driver to the upper-level
+ * driver and to configure the driver for a specific mode of
* operation defined by the parameters selected in supplied device caps
- * strucure. The lower-level device should perform any initialization
+ * structure. The lower-level device should perform any initialization
* needed to prepare for operations in the specified mode. It should not,
* however, process any audio data until the start method is called.
*/
CODE int (*configure)(FAR struct audio_lowerhalf_s *dev,
- FAR const struct audio_caps_s *pCaps);
+ FAR const struct audio_caps_s *pCaps,
+ audio_callback_t upper, FAR void *priv);
/* This method is called when the driver is closed. The lower half driver
* should stop processing audio data, including terminating any active
@@ -280,7 +294,7 @@ struct audio_ops_s
/* Enqueue a buffer for processing. This is a non-blocking enqueue operation.
* If the lower-half driver's buffer queue is full, then it should return an
- * error code of -ENOMEM, and the upper-half driver can decide to either block
+ j* error code of -ENOMEM, and the upper-half driver can decide to either block
* the calling thread or deal with it in a non-blocking manner.
* For each call to enqueuebuffer, the lower-half driver must call
@@ -293,6 +307,11 @@ struct audio_ops_s
CODE int (*enqueuebuffer)(FAR struct audio_lowerhalf_s *dev,
FAR struct ap_buffer_s *apb);
+ /* Cancel a previously enqueued buffer. */
+
+ CODE int (*cancelbuffer)(FAR struct audio_lowerhalf_s *dev,
+ FAR struct ap_buffer_s *apb);
+
/* Lower-half logic may support platform-specific ioctl commands */
CODE int (*ioctl)(FAR struct audio_lowerhalf_s *dev,
@@ -319,6 +338,16 @@ struct audio_lowerhalf_s
FAR const struct audio_ops_s *ops;
+ /* The bind data to the upper-half driver used for callbacks of dequeuing
+ * buffer, reporting asynchronous event, reporting errors, etc.
+ */
+
+ FAR audio_callback_t upper;
+
+ /* The private opaque pointer to be passed to upper-layer during callbacks */
+
+ FAR void *priv;
+
/* The custom Audio device state structure may include additional fields
* after the pointer to the Audio callback structure.
*/
@@ -435,28 +464,10 @@ EXTERN void apb_reference(FAR struct ap_buffer_s *apb);
* Platform-Dependent "Lower-Half" Audio Driver Interfaces
****************************************************************************/
-/****************************************************************************
- * Name: vs1053_initialize
- *
- * Description:
- * This function initializes the driver for the VS1053 codec chip
- *
- * Input parameters:
- * spi - This is a placeholder for now. Actual init parameters will be
- * determined once the audio interface is "finalized".
- *
- * Returned Value:
- * Zero on success; a negated errno value on failure.
- *
- ****************************************************************************/
-#ifdef CONFIG_VS1053
-EXTERN FAR struct audio_lowerhalf_s *vs1053_initialize(int spidevice);
-#endif
-
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_AUDIO */
-#endif /* __INCLUDE_NUTTX_AUDIO_H */
+#endif /* __INCLUDE_NUTTX_AUDIO_AUDIO_H */
diff --git a/nuttx/include/nuttx/audio/vs1053.h b/nuttx/include/nuttx/audio/vs1053.h
new file mode 100644
index 000000000..5b791c023
--- /dev/null
+++ b/nuttx/include/nuttx/audio/vs1053.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+ * include/nuttx/audio/vs1053.h
+ *
+ * Copyright (C) 2013 Ken Pettit. All rights reserved.
+ * Author: Ken Pettit <pettitkd@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_NET_VS1053_H
+#define __INCLUDE_NUTTX_NET_VS1053_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <nuttx/irq.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* VS1053 Configuration Settings:
+ *
+ * CONFIG_VS1053 - Enabled VS1053 support
+ * CONFIG_VS1053_SPIMODE - Controls the SPI mode
+ */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* The VS1053 provides Data Request (DREQ) interrupts to the MCU via a GPIO
+ * pin and also has a chip reset GPIO. The following structure provides an
+ * MCU-independent mechanism for controlling the VS1053 GPIOs.
+ */
+
+struct vs1053_lower_s
+{
+ int (*attach)(FAR const struct vs1053_lower_s *lower, xcpt_t handler);
+ void (*enable)(FAR const struct vs1053_lower_s *lower);
+ void (*disable)(FAR const struct vs1053_lower_s *lower);
+ void (*reset)(FAR const struct vs1053_lower_s *lower, bool state);
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: vs1053_initialize
+ *
+ * Description:
+ * Initialize the VS1053 driver. This will perform a chip reset of the
+ * device as part of initialization.
+ *
+ * Parameters:
+ * spi - A reference to the platform's SPI driver for the VS1053
+ * lower - The MCU-specific interrupt used to control low-level MCU
+ * functions (i.e., VS1053 GPIO interrupts).
+ * devno - If more than one VS1053 is supported, then this is the
+ * zero based number that identifies the VS1053;
+ *
+ * Returned Value:
+ * OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+struct spi_dev_s; /* see nuttx/spi.h */
+struct audio_lowerhalf_s; /* see nutt/audio.h */
+EXTERN FAR struct audio_lowerhalf_s *vs1053_initialize(FAR struct spi_dev_s *spi,
+ FAR const struct vs1053_lower_s *lower,
+ unsigned int devno);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_NET_VS1053_H */
diff --git a/nuttx/include/nuttx/spi.h b/nuttx/include/nuttx/spi.h
index 7eb7fb908..4816e7d8b 100644
--- a/nuttx/include/nuttx/spi.h
+++ b/nuttx/include/nuttx/spi.h
@@ -358,7 +358,8 @@ enum spi_dev_e
SPIDEV_TOUCHSCREEN, /* Select SPI touchscreen device */
SPIDEV_EXPANDER, /* Select SPI I/O expander device */
SPIDEV_MUX, /* Select SPI multiplexer device */
- SPIDEV_AUDIO /* Select SPI audio codec device */
+ SPIDEV_AUDIO_DATA, /* Select SPI audio codec device data port */
+ SPIDEV_AUDIO_CTRL, /* Select SPI audio codec device control port */
};
/* Certain SPI devices may required differnt clocking modes */