Audio subystem update from Ken Pettit. Plus moved some header files
This commit is contained in:
parent
3895e0ec4c
commit
801977de7c
|
@ -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).
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_AUDIO
|
||||
# include "nuttx/audio.h"
|
||||
# include "nuttx/audio/audio.h"
|
||||
#endif
|
||||
|
||||
#include "stm32.h"
|
||||
|
@ -181,9 +181,6 @@ int nsh_archinitialize(void)
|
|||
#ifdef CONFIG_STM32_SPI3
|
||||
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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue