Merged in masayuki2009/nuttx.nuttx/lc823450 (pull request #531)

lc823450-xgevk audio support

* arch/arm/src/lc823450: Add IPL2 support

    Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>

* configs/lc823450-xgevk: Add IPL2 support

    Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>

* libc/audio: Fix compilation error in lib_buffer.c

    Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>

* drivers/audio: Add WM8774 support

    Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>

* arch/arm/src/lc823450: Add I2S support

    Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>

* configs/lc823450-xgevk: Add WM8774 support

    Signed-off-by: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>

Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
Masayuki Ishikawa 2017-11-08 12:25:13 +00:00 committed by Gregory Nutt
parent 7c5f329294
commit 51b19d5f38
18 changed files with 2486 additions and 11 deletions

View file

@ -185,6 +185,11 @@ config LC823450_I2C1
default n
depends on I2C
config LC823450_I2S0
bool "I2S0"
default n
depends on I2S
config LC823450_SPI_DMA
bool "DMA for SPI"
default n

View file

@ -181,3 +181,7 @@ ifeq ($(CONFIG_LC823450_MTD),y)
CHIP_CSRCS += lc823450_mtd.c
CHIP_CSRCS += lc823450_mmcl.c
endif
ifeq ($(CONFIG_LC823450_I2S0),y)
CHIP_CSRCS += lc823450_i2s.c
endif

View file

@ -0,0 +1,473 @@
/****************************************************************************
* arch/arm/src/lc823450/lc823450_i2s.c
*
* Copyright (C) 2017 Sony Corporation. All rights reserved.
* Author: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.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 <arch/board/board.h>
#include <nuttx/config.h>
#include <semaphore.h>
#include <nuttx/arch.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
#include <nuttx/semaphore.h>
#include <nuttx/audio/audio.h>
#include <nuttx/audio/i2s.h>
#include "up_arch.h"
#include "lc823450_dma.h"
#include "lc823450_i2s.h"
#include "lc823450_syscontrol.h"
#include "lc823450_clockconfig.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define LC823450_AUDIO_REGBASE 0x40060000
#define ABUF_REGBASE (LC823450_AUDIO_REGBASE + 0x0000)
#define BEEP_REGBASE (LC823450_AUDIO_REGBASE + 0x1200)
#define PCKGEN_REGBASE (LC823450_AUDIO_REGBASE + 0x1600)
#define AUDCTL_REGBASE (LC823450_AUDIO_REGBASE + 0x4000)
#define ABUFCLR (ABUF_REGBASE + 0x0000)
#define ABUFACCEN (ABUF_REGBASE + 0x0004)
#define ABUFACCEN_CDCFEN (1 << 5)
#define ABUFIRQEN0 (ABUF_REGBASE + 0x0008)
#define ABUFIRQEN0_BFULIRQEN (1 << 5)
#define ABUFSTS1 (ABUF_REGBASE + 0x0034)
#define BUF_F_BASE (ABUF_REGBASE + 0x00c0 + (0x4 * 5))
#define BUF_F_SIZE (ABUF_REGBASE + 0x0100 + (0x4 * 5))
#define BUF_F_ULVL (ABUF_REGBASE + 0x0140 + (0x4 * 5))
#define BUF_F_DTCAP (ABUF_REGBASE + 0x01c0 + (0x4 * 5))
#define BUF_F_ACCESS (ABUF_REGBASE + 0x0300 + (0x4 * 5))
#define CLOCKEN (AUDCTL_REGBASE + 0x0000)
#define CLOCKEN_FCE_PCKGEN (1 << 28)
#define CLOCKEN_FCE_PCMPS0 (1 << 17)
#define CLOCKEN_FCE_BEEP (1 << 16)
#define CLOCKEN_FCE_VOLPS0 (1 << 13)
#define AUDSEL (AUDCTL_REGBASE + 0x001c)
#define AUDSEL_PCM0_MODE (1 << 17)
#define AUDSEL_PCM0_MODEM (1 << 16)
#define PSCTL (AUDCTL_REGBASE + 0x0110)
#define PCMOUTEN (AUDCTL_REGBASE + 0x0500)
#define PCMOUTEN_DOUT0EN (1 << 3)
#define PCMOUTEN_LRCK0EN (1 << 2)
#define PCMOUTEN_MCLK0EN (1 << 1)
#define PCMOUTEN_BCK0EN (1 << 0)
#define PCMCTL (AUDCTL_REGBASE + 0x0504)
#define BEEP_CTL (BEEP_REGBASE + 0x0000)
#define BEEP_BYPASS (BEEP_REGBASE + 0x0004)
#define BEEP_COEFF (BEEP_REGBASE + 0x0008)
#define BEEP_TIME (BEEP_REGBASE + 0x000c)
/* Audio PLL */
#define AUDIOPLL_REGBASE (LC823450_OSCSYS_REGBASE + 0x2000)
#define AUDPLLCNT (AUDIOPLL_REGBASE + 0x00)
#define AUDPLLMDIV (AUDIOPLL_REGBASE + 0x04)
#define AUDPLLNDIV (AUDIOPLL_REGBASE + 0x08)
/****************************************************************************
* Private Types
****************************************************************************/
/* The state of the one I2S peripheral */
struct lc823450_i2s_s
{
struct i2s_dev_s dev; /* Externally visible I2S interface */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static uint32_t lc823450_i2s_txsamplerate(struct i2s_dev_s *dev, uint32_t rate);
static uint32_t lc823450_i2s_txdatawidth(struct i2s_dev_s *dev, int bits);
static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
i2s_callback_t callback, void *arg,
uint32_t timeout);
/****************************************************************************
* Private Data
****************************************************************************/
/* I2S device operations */
static const struct i2s_ops_s g_i2sops =
{
/* Transmitter methods */
.i2s_txsamplerate = lc823450_i2s_txsamplerate,
.i2s_txdatawidth = lc823450_i2s_txdatawidth,
.i2s_send = lc823450_i2s_send,
};
static DMA_HANDLE _htxdma;
static sem_t _sem_txdma;
static sem_t _sem_buf_under;
/****************************************************************************
* Public Data
****************************************************************************/
extern unsigned int XT1OSC_CLK;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: _setup_audio_pll
****************************************************************************/
static void _setup_audio_pll(uint32_t freq)
{
ASSERT(24000000 == XT1OSC_CLK);
uint32_t m;
uint32_t n;
switch (freq)
{
case 44100:
m = 625;
n = 3528;
break;
case 48000:
m = 125;
n = 768;
break;
default:
ASSERT(false);
}
/* Set divider */
putreg32(n, AUDPLLNDIV);
putreg32(m, AUDPLLMDIV);
/* Audio PLL standby=off, Audio PLL unreset */
putreg32(0x0503, AUDPLLCNT);
/* TODO: Wait */
usleep(50 * 1000);
/* Switch to the PLL */
modifyreg32(AUDCLKCNT,
0x0,
0x03 /* AUDCLKSEL=Audio PLL */
);
/* TODO: Clock divider settings */
modifyreg32(AUDCLKCNT,
0x0,
0x0200 /* AUDDIV=2 */
);
}
/****************************************************************************
* Name: _i2s_txdma_callback
****************************************************************************/
static void _i2s_txdma_callback(DMA_HANDLE hdma, void *arg, int result)
{
sem_t *waitsem = (sem_t *)arg;
nxsem_post(waitsem);
}
/****************************************************************************
* Name: _i2s_semtake
****************************************************************************/
static void _i2s_semtake(FAR sem_t *sem)
{
int ret;
do
{
/* Take the semaphore (perhaps waiting) */
ret = nxsem_wait(sem);
/* The only case that an error should occur here is if the wait was
* awakened by a signal.
*/
DEBUGASSERT(ret == OK || ret == -EINTR);
}
while (ret == -EINTR);
}
/****************************************************************************
* Name: lc823450_i2s_txsamplerate
****************************************************************************/
static uint32_t lc823450_i2s_txsamplerate(struct i2s_dev_s *dev, uint32_t rate)
{
/* TODO */
return 0;
}
/****************************************************************************
* Name: lc823450_i2s_txdatawidth
****************************************************************************/
static uint32_t lc823450_i2s_txdatawidth(struct i2s_dev_s *dev, int bits)
{
/* TODO */
return 0;
}
/****************************************************************************
* Name: _i2s_isr
****************************************************************************/
static int _i2s_isr(int irq, FAR void *context, FAR void *arg)
{
/* disable interrupt */
up_disable_irq(LC823450_IRQ_AUDIOBUF0);
/* post semaphore for the waiter */
nxsem_post(&_sem_buf_under);
return 0;
}
/****************************************************************************
* Name: lc823450_i2s_send
****************************************************************************/
static int lc823450_i2s_send(struct i2s_dev_s *dev, struct ap_buffer_s *apb,
i2s_callback_t callback, void *arg,
uint32_t timeout)
{
/* Enable IRQ for Audio Buffer */
up_enable_irq(LC823450_IRQ_AUDIOBUF0);
/* Wait for Audio Buffer */
_i2s_semtake(&_sem_buf_under);
volatile uint32_t *ptr = (uint32_t *)&apb->samp[apb->curbyte];
uint32_t n = apb->nbytes;
/* Setup and start DMA for I2S */
lc823450_dmasetup(_htxdma,
LC823450_DMA_SRCINC |
LC823450_DMA_SRCWIDTH_WORD |
LC823450_DMA_DSTWIDTH_WORD,
(uint32_t)ptr, (uint32_t)BUF_F_ACCESS, n / 4);
lc823450_dmastart(_htxdma,
_i2s_txdma_callback,
&_sem_txdma);
_i2s_semtake(&_sem_txdma);
/* Invoke the callback handler */
callback(dev, apb, arg, 0);
return OK;
}
/****************************************************************************
* Name: lc823450_i2s_beeptest
****************************************************************************/
#ifdef BEEP_TEST
static void lc823450_i2s_beeptest(void)
{
/* Set BEEP params */
putreg32(0x0, BEEP_BYPASS);
putreg32(0x123ca6, BEEP_COEFF); /* 1kHz@fs=44.1k */
putreg32(0xffff, BEEP_TIME);
/* Start */
putreg32(0x3, BEEP_CTL);
}
#endif
/****************************************************************************
* Name: lc823450_i2s_configure
****************************************************************************/
static int lc823450_i2s_configure(void)
{
_setup_audio_pll(44100);
/* Unreset Audio Buffer */
putreg32(MRSTCNTEXT3_AUDIOBUF_RSTB,
MRSTCNTEXT3);
/* Enable clock to Audio Buffer */
putreg32(MCLKCNTEXT3_AUDIOBUF_CLKEN,
MCLKCNTEXT3);
/* F Buffer = 32KB */
putreg32(4096 * 8, BUF_F_SIZE);
/* Buffer Under Level = 1KB */
putreg32(1024, BUF_F_ULVL);
/* Enable Buffer F Under Level IRQ */
putreg32(ABUFIRQEN0_BFULIRQEN, ABUFIRQEN0);
/* Clear Audio Buffer */
putreg32(0xffff, ABUFCLR);
/* Access Enable */
putreg32(ABUFACCEN_CDCFEN, ABUFACCEN);
/* PCM0: BCK0/LRCK0=master, MCLK0=master */
putreg32(AUDSEL_PCM0_MODE |
AUDSEL_PCM0_MODEM,
AUDSEL);
/* LRCK0/BCK0: 1/1fs, BCK0:64fs, BCK1:64fs */
putreg32(0x00001010,
PCMCTL);
/* Enable DOUT0/LRCK0/MCL0/BCK0 */
putreg32(PCMOUTEN_DOUT0EN |
PCMOUTEN_LRCK0EN |
PCMOUTEN_MCLK0EN |
PCMOUTEN_BCK0EN,
PCMOUTEN);
/* Stereo, PCMDLY=1, LRCK active low,
* MSB first and left justified, 32bit
*/
putreg32(0x64, PSCTL);
/* Enable PCMPS0 */
putreg32(CLOCKEN_FCE_PCKGEN |
CLOCKEN_FCE_BEEP |
CLOCKEN_FCE_PCMPS0 |
CLOCKEN_FCE_VOLPS0,
CLOCKEN);
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: lc823450_i2sdev_initialize
****************************************************************************/
FAR struct i2s_dev_s *lc823450_i2sdev_initialize(void)
{
FAR struct lc823450_i2s_s *priv = NULL;
/* The support STM32 parts have only a single I2S port */
i2sinfo("port: %d\n", port);
/* Allocate a new state structure for this chip select. NOTE that there
* is no protection if the same chip select is used in two different
* chip select structures.
*/
priv = (struct lc823450_i2s_s *)zalloc(sizeof(struct lc823450_i2s_s));
if (!priv)
{
i2serr("ERROR: Failed to allocate a chip select structure\n");
return NULL;
}
/* Initialize the common parts for the I2S device structure */
priv->dev.ops = &g_i2sops;
(void)lc823450_i2s_configure();
#ifdef BEEP_TEST
lc823450_i2s_beeptest();
#endif
_htxdma = lc823450_dmachannel(DMA_CHANNEL_VIRTUAL);
nxsem_init(&_sem_txdma, 0, 0);
nxsem_init(&_sem_buf_under, 0, 0);
irq_attach(LC823450_IRQ_AUDIOBUF0, _i2s_isr, NULL);
/* Success exit */
return &priv->dev;
}

View file

@ -0,0 +1,76 @@
/****************************************************************************
* arch/arm/src/lc823450/lc823450_i2s.h
*
* Copyright (C) 2017 Sony Corporation. All rights reserved.
* Author: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.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 __ARCH_ARM_SRC_LC823450_LC823450_I2S_H
#define __ARCH_ARM_SRC_LC823450_LC823450_I2S_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/audio/i2s.h>
#include "chip.h"
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
FAR struct i2s_dev_s *lc823450_i2sdev_initialize(void);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __ARCH_ARM_SRC_LC823450_LC823450_I2S_H */

View file

@ -108,6 +108,9 @@
#define MCLKCNTEXT1_PTM1C_CLKEN (1 << 29)
#define MCLKCNTEXT1_PTM2C_CLKEN (1 << 30)
#define MCLKCNTEXT3 (LC823450_SYSCONTROL_REGBASE + 0x0108)
#define MCLKCNTEXT3_AUDIOBUF_CLKEN (1 << 0)
#define MCLKCNTEXT4 (LC823450_SYSCONTROL_REGBASE + 0x010c)
#define MCLKCNTEXT4_SDRAMC_CLKEN0 (1 << 0)
#define MCLKCNTEXT4_SDRAMC_CLKEN1 (1 << 1)
@ -156,6 +159,9 @@
#define MRSTCNTEXT1_SDIF2_RSTB (1 << 10)
#define MRSTCNTEXT1_MSIF_RSTB (1 << 11)
#define MRSTCNTEXT3 (LC823450_SYSCONTROL_REGBASE + 0x011c)
#define MRSTCNTEXT3_AUDIOBUF_RSTB (1 << 0)
#define MRSTCNTEXT4 (LC823450_SYSCONTROL_REGBASE + 0x0120)
#define MRSTCNTEXT4_SDRAMC_RSTB (1 << 0)

View file

@ -21,7 +21,7 @@ MakeIPL2 Tool for eMMC boot is available at
This port is intended to test LC823450 features including SMP.
Supported peripherals:
UART, TIMER, RTC, GPIO, DMA, I2C, SPI, LCD, eMMC, USB, WDT, ADC.
UART, TIMER, RTC, GPIO, DMA, I2C, SPI, LCD, eMMC, USB, WDT, ADC, Audio.
Settings
^^^^^^^^
@ -43,9 +43,6 @@ output into the console because UART operates in FIFO mode.
1. "nsh> smp" works but the result will be corrupted.
2. "nsh> ostest" works but might cause a deadlock or assertion.
Other Status
^^^^^^^^^^^^
@ -187,8 +184,27 @@ then dd the files to the kernel partition (/dev/mtdblock0p4) and the IPL2 partit
nsh> dd if=/mnt/sd0/LC8234xx_17S_start_data.boot_bin of=/dev/mtdblock0p1
nsh> reboot
10. Audio playback (WAV/44.1k/16bit/2ch only)
Firstly, please check the jumper pin settings as follows.
JP1, JP2 => short
JP3, JP4 => open
To play WAV file on uSD card,
nsh> mount -t vfat /dev/mtdblock1 /mnt/sd1
nsh> nxplayer
nxplayer> play /mnt/sd1/sample.wav
nxplayer> volume 50
Currently nxplayer does not work in SMP mode.
up_assert: Assertion failed at file:chip/lc823450_cpupause.c line: 279 task: wm8776
TODO
^^^^
The following features will be supported.
Audio, etc.
LED, Accelerometer, etc.

View file

@ -0,0 +1,143 @@
CONFIG_AQM_1248A=y
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="lc823450-xgevk"
CONFIG_ARCH_BOARD_LC823450_XGEVK=y
CONFIG_ARCH_CHIP_LC823450=y
CONFIG_ARCH_FLOAT_H=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_STDARG_H=y
CONFIG_AUDIO_BUFFER_NUMBYTES=1024
CONFIG_AUDIO_EXCLUDE_BALANCE=y
CONFIG_AUDIO_EXCLUDE_FFORWARD=y
CONFIG_AUDIO_EXCLUDE_TONE=y
# CONFIG_AUDIO_FORMAT_MP3 is not set
CONFIG_AUDIO_WM8776=y
CONFIG_AUDIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_BOARD_LOOPSPERMSEC=12061
CONFIG_BUILTIN=y
CONFIG_C99_BOOL8=y
CONFIG_CODECS_HASH_MD5=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_ERROR=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEBUG_WARN=y
CONFIG_DEV_ZERO=y
CONFIG_DISABLE_POSIX_TIMERS=y
CONFIG_DRIVERS_AUDIO=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_EXAMPLES_NSH=y
CONFIG_EXAMPLES_NXHELLO_BPP=1
CONFIG_EXAMPLES_NXHELLO=y
CONFIG_EXAMPLES_OSTEST=y
CONFIG_EXAMPLES_PIPE=y
CONFIG_EXPERIMENTAL=y
CONFIG_FAT_LCNAMES=y
CONFIG_FAT_LFN=y
CONFIG_FS_FATTIME=y
CONFIG_FS_FAT=y
CONFIG_FS_PROCFS=y
CONFIG_I2C_RESET=y
CONFIG_I2CTOOL_MAXBUS=1
CONFIG_I2C=y
CONFIG_I2S=y
CONFIG_INTELHEX_BINARY=y
CONFIG_LC823450_I2C0=y
CONFIG_LC823450_I2C1=y
CONFIG_LC823450_I2S0=y
CONFIG_LC823450_MTD=y
CONFIG_LC823450_SDIF_SDC=y
CONFIG_LC823450_SPI_DMA=y
CONFIG_LC823450_UART0=y
CONFIG_LCD_ST7565=y
CONFIG_LCD=y
CONFIG_LIB_KBDCODEC=y
CONFIG_LIBM=y
CONFIG_MAX_TASKS=64
CONFIG_MAX_WDOGPARMS=2
CONFIG_MEMSET_OPTSPEED=y
CONFIG_MQ_MAXMSGSIZE=64
CONFIG_MTD=y
CONFIG_NAME_MAX=765
CONFIG_NETUTILS_CODECS=y
CONFIG_NFILE_DESCRIPTORS=45
CONFIG_NFILE_STREAMS=8
CONFIG_NSH_ARCHINIT=y
# CONFIG_NSH_ARGCAT is not set
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_CMDOPT_DD_STATS=y
CONFIG_NSH_DISABLE_BASENAME=y
CONFIG_NSH_DISABLE_DIRNAME=y
CONFIG_NSH_DISABLE_EXEC=y
CONFIG_NSH_DISABLE_GET=y
CONFIG_NSH_DISABLE_LOSETUP=y
CONFIG_NSH_DISABLE_MB=y
CONFIG_NSH_DISABLE_MH=y
CONFIG_NSH_DISABLE_MKFIFO=y
CONFIG_NSH_DISABLE_MKRD=y
CONFIG_NSH_DISABLE_PUT=y
CONFIG_NSH_DISABLE_SH=y
CONFIG_NSH_DISABLE_XD=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=128
CONFIG_NSH_MAXARGUMENTS=10
CONFIG_NSH_READLINE=y
CONFIG_NX_BLOCKING=y
# CONFIG_NX_DISABLE_1BPP is not set
CONFIG_NXFONT_MONO5X8=y
CONFIG_NXPLAYER_DEFAULT_MEDIADIR="/mnt/sd1"
CONFIG_NX=y
CONFIG_PIPES=y
CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=2048
CONFIG_PREALLOC_MQ_MSGS=4
CONFIG_PREALLOC_TIMERS=4
CONFIG_PREALLOC_WDOGS=16
CONFIG_PTHREAD_MUTEX_TYPES=y
CONFIG_PTHREAD_STACK_DEFAULT=3072
CONFIG_RAM_SIZE=1044480
CONFIG_RAM_START=0x02001000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RTC_DATETIME=y
CONFIG_RTC=y
CONFIG_SCHED_ATEXIT=y
CONFIG_SCHED_CHILD_STATUS=y
CONFIG_SCHED_HAVE_PARENT=y
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_ONEXIT_MAX=32
CONFIG_SCHED_ONEXIT=y
CONFIG_SCHED_STARTHOOK=y
CONFIG_SCHED_WAITPID=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_SERIAL_TERMIOS=y
# CONFIG_SPI_EXCHANGE is not set
CONFIG_SPI=y
CONFIG_START_DAY=3
CONFIG_START_MONTH=10
CONFIG_START_YEAR=2013
CONFIG_SYSTEM_I2CTOOL=y
CONFIG_SYSTEM_NXPLAYER=y
CONFIG_SYSTEM_USBMSC_CMD_STACKSIZE=2048
CONFIG_SYSTEM_USBMSC_DEVPATH1="/dev/mtdblock0p10"
CONFIG_SYSTEM_USBMSC_DEVPATH2="/dev/mtdblock1"
CONFIG_SYSTEM_USBMSC_NLUNS=2
CONFIG_SYSTEM_USBMSC=y
CONFIG_TASK_NAME_SIZE=24
CONFIG_UART0_RXBUFSIZE=512
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_UART0_TXBUFSIZE=2048
CONFIG_USBDEV_BUSPOWERED=y
CONFIG_USBDEV_DUALSPEED=y
CONFIG_USBDEV_MAXPOWER=500
CONFIG_USBDEV=y
CONFIG_USBMSC_EPBULKIN=2
CONFIG_USBMSC_EPBULKOUT=1
CONFIG_USBMSC_REMOVABLE=y
CONFIG_USBMSC=y
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_USERMAIN_STACKSIZE=3072
CONFIG_WM8776_SWAP_HPOUT=y

View file

@ -72,4 +72,8 @@ ifeq ($(CONFIG_NETDEVICES),y)
CSRCS += lc823450_netinit.c
endif
ifeq ($(CONFIG_AUDIO_WM8776),y)
CSRCS += lc823450_wm8776.c
endif
include $(TOPDIR)/configs/Board.mk

View file

@ -94,5 +94,9 @@ int lc823450_bringup(void);
int lc823450_bma250initialize(FAR const char *devpath);
#endif
#ifdef CONFIG_AUDIO_WM8776
int lc823450_wm8776initialize(int minor);
#endif
#endif /* __ASSEMBLY__ */
#endif /* __CONFIGS_LC823450_XGEVK_SRC_LC823450_XGEVK_H */

View file

@ -149,11 +149,11 @@
1 << 10 | /* 0: GPIO15, 1:DOUT1 */ \
0 << 12 | /* 0: GPIO16, 1:NLBEXA0 */ \
0 << 14 | /* 0: GPIO17, 1:NRD */ \
0 << 16 | /* 0: GPIO18, 1:MCLK0, 2:MCLK1 */ \
0 << 18 | /* 0: GPIO19, 1:BCK0, 2:DMCKO1 */ \
0 << 20 | /* 0: GPIO1A, 1:LRCK0, 2:DMDIN1 */ \
2 << 22 | /* 0: GPIO1B, 1:DIN0, 2:DMDIN0 */ \
0 << 24 | /* 0: GPIO1C, 1:DOUT0, 2:DMCKO0 */ \
1 << 16 | /* 0: GPIO18, 1:MCLK0, 2:MCLK1 */ \
1 << 18 | /* 0: GPIO19, 1:BCK0, 2:DMCKO1 */ \
1 << 20 | /* 0: GPIO1A, 1:LRCK0, 2:DMDIN1 */ \
1 << 22 | /* 0: GPIO1B, 1:DIN0, 2:DMDIN0 */ \
1 << 24 | /* 0: GPIO1C, 1:DOUT0, 2:DMCKO0 */ \
1 << 26 | /* 0: GPIO1D, 1:SCK0 */ \
0 << 28 | /* 0: GPIO1E, 1:SDI0 */ \
1 << 30 /* 0: GPIO1F, 1:SDO0 */
@ -185,7 +185,7 @@
0 << 10 | /* GPIO15 0:1mA, 1:---, 2:2mA, 3:4mA */ \
0 << 12 | /* GPIO16 0:2mA, 1:---, 2:4mA, 3:8mA */ \
0 << 14 | /* GPIO17 0:2mA, 1:---, 2:4mA, 3:8mA */ \
0 << 16 | /* GPIO18 0:1mA, 1:---, 2:2mA, 3:4mA */ \
3 << 16 | /* GPIO18 0:1mA, 1:---, 2:2mA, 3:4mA */ \
0 << 18 | /* GPIO19 0:1mA, 1:---, 2:2mA, 3:4mA */ \
0 << 20 | /* GPIO1A 0:1mA, 1:---, 2:2mA, 3:4mA */ \
0 << 22 | /* GPIO1B 0:1mA, 1:---, 2:2mA, 3:4mA */ \

View file

@ -85,6 +85,10 @@ int lc823450_bringup(void)
lc823450_bma250initialize("/dev/accel");
#endif
#ifdef CONFIG_AUDIO_WM8776
lc823450_wm8776initialize(0);
#endif
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.

View file

@ -0,0 +1,130 @@
/****************************************************************************
* configs/lc823450-xgevk/src/lc823450_wm8776.c
*
* Copyright (C) 2017 Sony Corporation. All rights reserved.
* Author: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.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 <errno.h>
#include <debug.h>
#include <stdio.h>
#include <nuttx/arch.h>
#include <nuttx/i2c/i2c_master.h>
#include <nuttx/audio/i2s.h>
#include <nuttx/audio/pcm.h>
#include <nuttx/audio/wm8776.h>
#include <arch/board/board.h>
#include "up_arch.h"
#include "lc823450_i2c.h"
#include "lc823450_i2s.h"
#include "lc823450-xgevk.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define WM8776_I2C_PORTNO 0 /* On I2C0 */
#define WM8776_I2C_ADDR 0x1a
/****************************************************************************
* Private Data
****************************************************************************/
static struct wm8776_lower_s g_wm8776info =
{
.address = WM8776_I2C_ADDR,
.frequency = 400000,
};
/****************************************************************************
* Name: lc823450_wm8776initialize
****************************************************************************/
int lc823450_wm8776initialize(int minor)
{
FAR struct audio_lowerhalf_s *wm8776;
FAR struct audio_lowerhalf_s *pcm;
FAR struct i2c_master_s *i2c;
FAR struct i2s_dev_s *i2s;
char devname[12];
int ret;
ainfo("Initializing WM8776 \n");
/* Initialize I2C */
i2c = lc823450_i2cbus_initialize(WM8776_I2C_PORTNO);
if (!i2c)
{
return -ENODEV;
}
i2s = lc823450_i2sdev_initialize();
wm8776 = wm8776_initialize(i2c, i2s, &g_wm8776info);
if (!wm8776)
{
auderr("ERROR: Failed to initialize the WM8904\n");
return -ENODEV;
}
pcm = pcm_decode_initialize(wm8776);
if (!pcm)
{
auderr("ERROR: Failed create the PCM decoder\n");
return -ENODEV;
}
snprintf(devname, 12, "pcm%d", minor);
ret = audio_register(devname, pcm);
if (ret < 0)
{
auderr("ERROR: Failed to register /dev/%s device: %d\n", devname, ret);
}
return 0;
}

View file

@ -155,6 +155,34 @@ config CS43L22_CLKDEBUG
endif # AUDIO_CS43L22
config AUDIO_WM8776
bool "WM8776 audio chip"
default n
depends on AUDIO
---help---
Select to enable support for the WM8776 Audio codec by Wolfson
Microelectonics.
if AUDIO_WM8776
config WM8776_INFLIGHT
int "WM8776 maximum in-flight audio buffers"
default 2
config WM8776_MSG_PRIO
int "WM8776 message priority"
default 1
config WM8776_WORKER_STACKSIZE
int "WM8776 worker thread stack size"
default 768
config WM8776_SWAP_HPOUT
bool "Swap WM8776 HP out signals"
default n
endif # AUDIO_WM8776
config AUDIO_WM8904
bool "WM8904 audio chip"
default n

View file

@ -65,6 +65,10 @@ endif
endif
endif
ifeq ($(CONFIG_AUDIO_WM8776),y)
CSRCS += wm8776.c
endif
ifeq ($(CONFIG_AUDIO_NULL),y)
CSRCS += audio_null.c
endif

1350
drivers/audio/wm8776.c Normal file

File diff suppressed because it is too large Load diff

128
drivers/audio/wm8776.h Normal file
View file

@ -0,0 +1,128 @@
/****************************************************************************
* drivers/audio/wm8776.h
*
* Copyright (C) 2017 Sony Corporation. All rights reserved.
* Author: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.com>
*
* Based on drivers/audio/wm8904.h
*
* 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_WM8776_H
#define __DRIVERS_AUDIO_WM8776_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <pthread.h>
#include <mqueue.h>
#include <nuttx/wqueue.h>
#include <nuttx/fs/ioctl.h>
#ifdef CONFIG_AUDIO
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define WM8776_MASTER_ATT 0x02
#define WM8776_DAC_CC 0x07
#define WM8776_DAC_IF 0x0a
#define WM8776_MASTER_MODE 0x0c
#define WM8776_PWR_DOWN 0x0d
#define WM8776_SOFT_RESET 0x17
#define WM8776_DEFAULT_SAMPRATE 44100 /* Initial sample rate */
#define WM8776_DEFAULT_NCHANNELS 2 /* Initial number of channels */
#define WM8776_DEFAULT_BPSAMP 16 /* Initial bits per sample */
#define WM8776_HPLZCEN (0x1 << 7)
#define WM8776_UPDATE (0x1 << 8)
#define WM8776_HPOUT_VOL_SHIFT (0) /* Bits 0-6: Headphone output volume */
#define WM8776_HPOUT_VOL_MASK (0x7f << WM8776_HPOUT_VOL_SHIFT)
# define WM8776_HPOUT_VOL(n) ((uint16_t)(n) << WM8776_HPOUT_VOL_SHIFT)
/****************************************************************************
* Public Types
****************************************************************************/
struct wm8776_dev_s
{
/* We are an audio lower half driver (We are also the upper "half" of
* the WM8776 driver with respect to the board lower half driver).
*
* Terminology: Our "lower" half audio instances will be called dev for the
* publicly visible version and "priv" for the version that only this driver
* knows. From the point of view of this driver, it is the board lower
* "half" that is referred to as "lower".
*/
struct audio_lowerhalf_s dev; /* WM8776 audio lower half (this device) */
const FAR struct wm8776_lower_s *lower; /* Pointer to the board lower functions */
FAR struct i2c_master_s *i2c; /* I2C driver to use */
FAR struct i2s_dev_s *i2s; /* I2S driver to use */
struct dq_queue_s pendq; /* Queue of pending buffers to be sent */
struct dq_queue_s doneq; /* Queue of sent buffers to be returned */
mqd_t mq; /* Message queue for receiving messages */
char mqname[16]; /* Our message queue name */
pthread_t threadid; /* ID of our thread */
uint32_t bitrate; /* Actual programmed bit rate */
sem_t pendsem; /* Protect pendq */
uint16_t samprate; /* Configured samprate (samples/sec) */
#ifndef CONFIG_AUDIO_EXCLUDE_VOLUME
#ifndef CONFIG_AUDIO_EXCLUDE_BALANCE
uint16_t balance; /* Current balance level (b16) */
#endif /* CONFIG_AUDIO_EXCLUDE_BALANCE */
uint8_t volume; /* Current volume level {0..63} */
#endif /* CONFIG_AUDIO_EXCLUDE_VOLUME */
uint8_t nchannels; /* Number of channels (1 or 2) */
uint8_t bpsamp; /* Bits per sample (8 or 16) */
volatile uint8_t inflight; /* Number of audio buffers in-flight */
bool running; /* True: Worker thread is running */
bool paused; /* True: Playing is paused */
bool mute; /* True: Output is muted */
#ifndef CONFIG_AUDIO_EXCLUDE_STOP
bool terminating; /* True: Stop requested */
#endif
bool reserved; /* True: Device is reserved */
volatile int result; /* The result of the last transfer */
};
#endif /* CONFIG_AUDIO */
#endif /* __DRIVERS_AUDIO_WM8776_H */

View file

@ -0,0 +1,97 @@
/****************************************************************************
* include/nuttx/audio/wm8776.h
*
* Copyright (C) 2017 Sony Corporation. All rights reserved.
* Author: Masayuki Ishikawa <Masayuki.Ishikawa@jp.sony.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_AUDIO_WM8776_H
#define __INCLUDE_NUTTX_AUDIO_WM8776_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <nuttx/irq.h>
#ifdef CONFIG_AUDIO_WM8776
/****************************************************************************
* Public Types
****************************************************************************/
struct wm8776_lower_s;
struct wm8776_lower_s
{
/* I2C characterization */
uint32_t frequency; /* Initial I2C frequency */
uint8_t address; /* 7-bit I2C address (only bits 0-6 used) */
};
/****************************************************************************
* Public Data
****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
struct i2c_master_s;
struct i2s_dev_s;
struct audio_lowerhalf_s;
FAR struct audio_lowerhalf_s *
wm8776_initialize(FAR struct i2c_master_s *i2c,
FAR struct i2s_dev_s *i2s,
FAR const struct wm8776_lower_s *lower);
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_AUDIO_WM8776 */
#endif /* __INCLUDE_NUTTX_AUDIO_WM8776_H */

View file

@ -70,6 +70,8 @@
static void apb_semtake(FAR struct ap_buffer_s *apb)
{
int ret;
/* Take the semaphore (perhaps waiting) */
while (_SEM_WAIT(&apb->sem) < 0)
@ -79,6 +81,7 @@ static void apb_semtake(FAR struct ap_buffer_s *apb)
*/
DEBUGASSERT(_SEM_ERRNO(ret) == EINTR);
UNUSED(ret);
}
}