diff options
author | Harald Welte <laforge@gnumonks.org> | 2011-12-01 19:56:39 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2011-12-01 19:56:39 +0100 |
commit | 70285f225ba32c297756067c8a0e0363df9cdfe6 (patch) | |
tree | fa30f9c31974cc8ee53127169a01cdf27b55a9fd /basic-ssc-i2s-wm8731-project | |
parent | eebb6cc1217260d7b29478a83008ee070d57738e (diff) |
import basic-ssc-i2s-wm8731-project from at91sam3-ek
ported to at91lib-1.9
Diffstat (limited to 'basic-ssc-i2s-wm8731-project')
-rw-r--r-- | basic-ssc-i2s-wm8731-project/.main.c.swp | bin | 0 -> 20480 bytes | |||
-rw-r--r-- | basic-ssc-i2s-wm8731-project/Makefile | 227 | ||||
-rw-r--r-- | basic-ssc-i2s-wm8731-project/bin/.empty_dir | 0 | ||||
-rw-r--r-- | basic-ssc-i2s-wm8731-project/fatfs_config.h | 164 | ||||
-rw-r--r-- | basic-ssc-i2s-wm8731-project/main.c | 538 | ||||
-rw-r--r-- | basic-ssc-i2s-wm8731-project/obj/.empty_dir | 0 | ||||
-rw-r--r-- | basic-ssc-i2s-wm8731-project/sample.wav | bin | 0 -> 281036 bytes |
7 files changed, 929 insertions, 0 deletions
diff --git a/basic-ssc-i2s-wm8731-project/.main.c.swp b/basic-ssc-i2s-wm8731-project/.main.c.swp Binary files differnew file mode 100644 index 0000000..ab46235 --- /dev/null +++ b/basic-ssc-i2s-wm8731-project/.main.c.swp diff --git a/basic-ssc-i2s-wm8731-project/Makefile b/basic-ssc-i2s-wm8731-project/Makefile new file mode 100644 index 0000000..2a59ffc --- /dev/null +++ b/basic-ssc-i2s-wm8731-project/Makefile @@ -0,0 +1,227 @@ +# ----------------------------------------------------------------------------
+# ATMEL Microcontroller Software Support
+# ----------------------------------------------------------------------------
+# Copyright (c) 2008, Atmel Corporation
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the disclaimer below.
+#
+# Atmel's name may not be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+# DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+# ----------------------------------------------------------------------------
+
+# Makefile for compiling basic-ssc-i2s-at73c213-project
+
+#-------------------------------------------------------------------------------
+# User-modifiable options
+#-------------------------------------------------------------------------------
+
+# Chip & board used for compilation
+# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
+CHIP = at91sam3u4
+BOARD = at91sam3u-ek
+
+# Trace level used for compilation
+# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
+# TRACE_LEVEL_DEBUG 5
+# TRACE_LEVEL_INFO 4
+# TRACE_LEVEL_WARNING 3
+# TRACE_LEVEL_ERROR 2
+# TRACE_LEVEL_FATAL 1
+# TRACE_LEVEL_NO_TRACE 0
+TRACE_LEVEL = 5
+
+# Optimization level, put in comment for debugging
+#OPTIMIZATION = -Os
+
+# AT91 library directory
+AT91LIB = ../../at91lib
+
+# External library
+EXT_LIBS= ../external_libs
+
+# Output file basename
+OUTPUT = basic-ssc-i2s-wm8731-project-$(BOARD)-$(CHIP)
+
+# Compile with chip specific features
+include $(AT91LIB)/boards/$(BOARD)/$(CHIP)/chip.mak
+
+# Compile for all memories available on the board (this sets $(MEMORIES))
+include $(AT91LIB)/boards/$(BOARD)/board.mak
+
+# Output directories
+BIN = bin
+OBJ = obj
+
+#-------------------------------------------------------------------------------
+# Tools
+#-------------------------------------------------------------------------------
+
+# Tool suffix when cross-compiling
+CROSS_COMPILE = arm-none-eabi-
+
+# Compilation tools
+CC = $(CROSS_COMPILE)gcc
+SIZE = $(CROSS_COMPILE)size
+STRIP = $(CROSS_COMPILE)strip
+OBJCOPY = $(CROSS_COMPILE)objcopy
+
+# Flags
+INCLUDES += -I$(AT91LIB)/boards/$(BOARD)
+INCLUDES += -I$(AT91LIB)/peripherals
+INCLUDES += -I$(AT91LIB)/components
+INCLUDES += -I$(AT91LIB)/drivers
+INCLUDES += -I$(AT91LIB)
+INCLUDES += -I$(EXT_LIBS)/fat
+INCLUDES += -I$(AT91LIB)/memories
+INCLUDES += -I.
+INCLUDES += -I$(EXT_LIBS)
+INCLUDES += -I$(EXT_LIBS)/cmsis +
+ifeq ($(CHIP_CORE), cortexm3)
+TARGET_OPTS = -mcpu=cortex-m3 -mthumb
+else
+TARGET_OPTS =
+endif
+
+CFLAGS += $(TARGET_OPTS)
+CFLAGS += -Wall -mlong-calls -ffunction-sections
+CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_LEVEL=$(TRACE_LEVEL)
+ASFLAGS = $(TARGET_OPTS) -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
+LDFLAGS = -g $(OPTIMIZATION) -nostartfiles $(TARGET_OPTS) -Wl,--gc-sections
+
+#-------------------------------------------------------------------------------
+# Files
+#-------------------------------------------------------------------------------
+
+# Directories where source files can be found
+PERIPH = $(AT91LIB)/peripherals
+BOARDS = $(AT91LIB)/boards
+UTILITY = $(AT91LIB)/utility
+COMP = $(AT91LIB)/components
+DRIVER = $(AT91LIB)/drivers
+FATFS = $(EXT_LIBS)/fat/fatfs
+MEM = $(AT91LIB)/memories
+
+VPATH += $(COMP)/codec-wm8731
+VPATH += $(UTILITY)
+VPATH += $(PERIPH)/dbgu
+VPATH += $(PERIPH)/pio
+VPATH += $(PERIPH)/irq
+VPATH += $(PERIPH)/ssc
+VPATH += $(PERIPH)/twi
+VPATH += $(PERIPH)/pmc
+VPATH += $(PERIPH)/cp15
+VPATH += $(BOARDS)/$(BOARD)
+VPATH += $(BOARDS)/$(BOARD)/$(CHIP)
+VPATH += $(PERIPH)/mci
+VPATH += $(DRIVER)/twi
+VPATH += $(MEM)/sdmmc
+VPATH += $(PERIPH)/dma
+VPATH += $(DRIVER)/dmad
+VPATH += $(FATFS)/src
+VPATH += $(MEM)
+VPATH += $(EXT_LIBS)/cmsis
+
+# Objects built from C source files
+C_OBJECTS += main.o
+C_OBJECTS += wm8731.o
+C_OBJECTS += wav.o
+C_OBJECTS += stdio.o
+C_OBJECTS += math.o
+C_OBJECTS += dbgu.o
+C_OBJECTS += pio.o
+C_OBJECTS += ssc.o
+C_OBJECTS += twi.o
+C_OBJECTS += pmc.o
+C_OBJECTS += twid.o
+C_OBJECTS += board_lowlevel.o
+C_OBJECTS += trace.o +C_OBJECTS += board_memories.o
+C_OBJECTS += Media.o
+C_OBJECTS += MEDSdcard.o
+C_OBJECTS += diskio.o +C_OBJECTS += ff_util.o
+C_OBJECTS += tff.o
+C_OBJECTS += ff.o
+C_OBJECTS += sdmmc_mci.o
+
+# Objects for different chips
+ifeq ($(CHIP_CORE), cortexm3)
+C_OBJECTS += nvic.o
+C_OBJECTS += exceptions.o
+C_OBJECTS += board_cstartup_gnu.o
+C_OBJECTS += core_cm3.o
+else
+C_OBJECTS += aic.o
+C_OBJECTS += cp15.o
+C_OBJECTS += pit.o
+endif
+
+ifeq ($(CHIP_IP_MCI), MCI_DMA)
+C_OBJECTS += dmad.o
+C_OBJECTS += dma.o
+C_OBJECTS += mci_hs.o
+else
+C_OBJECTS += mci.o
+endif
+
+# Objects built from Assembly source files
+ifneq ($(CHIP_CORE), cortexm3)
+ASM_OBJECTS += board_cstartup.o
+ASM_OBJECTS += cp15_asm.o
+endif
+
+# Append OBJ and BIN directories to output filename
+OUTPUT := $(BIN)/$(OUTPUT)
+
+#-------------------------------------------------------------------------------
+# Rules
+#-------------------------------------------------------------------------------
+
+all: $(BIN) $(OBJ) $(MEMORIES)
+
+$(BIN) $(OBJ):
+ mkdir $@
+
+define RULES
+C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
+ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
+
+$(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
+ $(CC) $(LDFLAGS) -T"$(AT91LIB)/boards/$(BOARD)/$(CHIP)/$$@.lds" -o $(OUTPUT)-$$@.elf $$^
+ $(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
+ $(SIZE) $$^ $(OUTPUT)-$$@.elf
+
+$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
+ $(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
+
+$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
+ $(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
+
+debug_$(1): $(1)
+ perl ../resources/gdb/debug.pl $(OUTPUT)-$(1).elf
+
+endef
+
+$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
+
+clean:
+ -rm -f $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf
+
diff --git a/basic-ssc-i2s-wm8731-project/bin/.empty_dir b/basic-ssc-i2s-wm8731-project/bin/.empty_dir new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/basic-ssc-i2s-wm8731-project/bin/.empty_dir diff --git a/basic-ssc-i2s-wm8731-project/fatfs_config.h b/basic-ssc-i2s-wm8731-project/fatfs_config.h new file mode 100644 index 0000000..41a60bf --- /dev/null +++ b/basic-ssc-i2s-wm8731-project/fatfs_config.h @@ -0,0 +1,164 @@ +/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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 FATFS_CONFIG_H
+#define FATFS_CONFIG_H
+
+//------------------------------------------------------------------------------
+// General Definitions (previously in ff.h)
+//------------------------------------------------------------------------------
+
+#define _FATFS_TINY 1
+/* When _FATFS_TINY is set to 1, fatfs is compiled in Tiny mode
+/ Else, it is compiled in normal mode
+/ Tiny FatFs feature : Very low memory consumption, suitable for small memory
+/ system. (1KB RAM) : Supports only single drive, no disk format,
+/ only read functions, no write functions */
+
+//------------------------------------------------------------------------------
+// Definitions for normal FATFS (previously in ff.h)
+//------------------------------------------------------------------------------
+
+#if _FATFS_TINY == 0
+
+#define _MCU_ENDIAN 2
+/* The _MCU_ENDIAN defines which access method is used to the FAT structure.
+/ 1: Enable word access.
+/ 2: Disable word access and use byte-by-byte access instead.
+/ When the architectural byte order of the MCU is big-endian and/or address
+/ miss-aligned access results incorrect behavior, the _MCU_ENDIAN must be set to 2.
+/ If it is not the case, it can also be set to 1 for good code efficiency. */
+
+#define _FS_READONLY 0
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes
+/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
+/ f_truncate and useless f_getfree. */
+
+#define _FS_MINIMIZE 0
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.
+/ 0: Full function.
+/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename are removed.
+/ 2: f_opendir and f_readdir are removed in addition to level 1.
+/ 3: f_lseek is removed in addition to level 2. */
+
+#define _USE_STRFUNC 0
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
+
+#define _USE_FSINFO 1
+/* To enable FSInfo support on FAT32 volume, set _USE_FSINFO to 1. */
+
+#define _USE_SJIS 1
+/* When _USE_SJIS is set to 1, Shift-JIS code transparency is enabled, otherwise
+/ only US-ASCII(7bit) code can be accepted as file/directory name. */
+
+#define _USE_NTFLAG 1
+/* When _USE_NTFLAG is set to 1, upper/lower case of the file name is preserved.
+/ Note that the files are always accessed in case insensitive. */
+
+#define _USE_MKFS 1
+/* When _USE_MKFS is set to 1 and _FS_READONLY is set to 0, f_mkfs function is
+/ enabled. */
+
+#define _DRIVES 2
+/* Number of logical drives to be used. This affects the size of internal table. */
+
+#define _MULTI_PARTITION 0
+/* When _MULTI_PARTITION is set to 0, each logical drive is bound to same
+/ physical drive number and can mount only 1st primaly partition. When it is
+/ set to 1, each logical drive can mount a partition listed in Drives[]. */
+
+//------------------------------------------------------------------------------
+// Definitions for normal FATFS TINY (previously in tff.h)
+//------------------------------------------------------------------------------
+
+#else
+
+#define _MCU_ENDIAN 2
+/* The _MCU_ENDIAN defines which access method is used to the FAT structure.
+/ 1: Enable word access.
+/ 2: Disable word access and use byte-by-byte access instead.
+/ When the architectural byte order of the MCU is big-endian and/or address
+/ miss-aligned access results incorrect behavior, the _MCU_ENDIAN must be set to 2.
+/ If it is not the case, it can also be set to 1 for good code efficiency. */
+
+#define _FS_READONLY 1
+/* Setting _FS_READONLY to 1 defines read only configuration. This removes
+/ writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
+/ f_truncate, f_getfree and internal writing codes. */
+
+#define _FS_MINIMIZE 0
+/* The _FS_MINIMIZE option defines minimization level to remove some functions.
+/ 0: Full function.
+/ 1: f_stat, f_getfree, f_unlink, f_mkdir, f_chmod, f_truncate and f_rename are removed.
+/ 2: f_opendir and f_readdir are removed in addition to level 1.
+/ 3: f_lseek is removed in addition to level 2. */
+
+#define _USE_STRFUNC 0
+/* To enable string functions, set _USE_STRFUNC to 1 or 2. */
+
+#define _USE_FSINFO 1
+/* To enable FSInfo support on FAT32 volume, set _USE_FSINFO to 1. */
+
+#define _USE_SJIS 1
+/* When _USE_SJIS is set to 1, Shift-JIS code transparency is enabled, otherwise
+/ only US-ASCII(7bit) code can be accepted as file/directory name. */
+
+#define _USE_NTFLAG 1
+/* When _USE_NTFLAG is set to 1, upper/lower case of the file name is preserved.
+/ Note that the files are always accessed in case insensitive. */
+
+#define _USE_FORWARD 0
+/* To enable f_forward function, set _USE_FORWARD to 1. */
+
+#define _FAT32 1
+/* To enable FAT32 support in addition of FAT12/16, set _FAT32 to 1. */
+
+#endif
+
+//------------------------------------------------------------------------------
+// Other definitions
+//------------------------------------------------------------------------------
+
+/*-----------------------------------------------------------------------*/
+/* Correspondence between drive number and physical drive */
+/* Note that Tiny-FatFs supports only single drive and always */
+/* accesses drive number 0. */
+
+#define DRV_MMC 0
+#define DRV_SDRAM 1
+#define DRV_ATA 2
+#define DRV_USB 3
+#define DRV_NAND 4
+
+
+#define SECTOR_SIZE_DEFAULT 512
+#define SECTOR_SIZE_SDRAM 512
+#define SECTOR_SIZE_SDCARD 512
+
+#endif // FATFS_CONFIG_H
diff --git a/basic-ssc-i2s-wm8731-project/main.c b/basic-ssc-i2s-wm8731-project/main.c new file mode 100644 index 0000000..3b1e4b4 --- /dev/null +++ b/basic-ssc-i2s-wm8731-project/main.c @@ -0,0 +1,538 @@ +/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
+ * ----------------------------------------------------------------------------
+ */
+
+
+//-----------------------------------------------------------------------------
+/// \dir "Basic SSC-I2S WM8731 project"
+///
+/// !!!Purpose
+///
+/// This example uses the Synchronous Serial Controller (SSC) of an AT91 microcontroller
+/// to output an audio steam through the on-board WM8731 CODEC.
+///
+///
+/// !!!See
+/// - ssc: SSC driver interface
+///
+/// !!!Description
+///
+/// This program plays a WAV file pre-loaded into the SDcard. The audio stream is sent through
+/// the SSC interface connected to the on-board WM8731, enabling the sound to be audible using a pair of headphones.
+///
+/// Since the WM8731 DAC requires that it be feeded a master clock multiple of the sample rate,
+/// it is difficult to handle any WAV file. As such, this example application is limited to playing files with the following format:
+/// - Format: WAV
+/// - Sample rate: 48 kHz
+///
+/// !!!Usage
+///
+/// -# Build the program and download it inside the evaluation board. Please
+/// refer to the
+/// <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6224.pdf">
+/// SAM-BA User Guide</a>, the
+/// <a href="http://www.atmel.com/dyn/resources/prod_documents/doc6310.pdf">
+/// GNU-Based Software Development</a> application note or to the
+/// <a href="ftp://ftp.iar.se/WWWfiles/arm/Guides/EWARM_UserGuide.ENU.pdf">
+/// IAR EWARM User Guide</a>, depending on your chosen solution.
+/// -# On the computer, open and configure a terminal application
+/// (e.g. HyperTerminal on Microsoft Windows) with these settings:
+/// - 115200 bauds
+/// - 8 bits of data
+/// - No parity
+/// - 1 stop bit
+/// - No flow control
+/// -# Start the application.
+/// -# In the terminal window, the following text should appear:
+/// \code
+/// -- Basic SSC I2S WM8731 Project xxx --
+/// -- AT91xxxxxx-xx
+/// -- Compiled: xxx xx xxxx xx:xx:xx --
+/// Menu :
+/// ------
+/// W: Play the WAV file pre-loaded in SD Card
+/// I: Display the information of the WAV file
+/// \endcode
+/// The user can then choose any of the available options to perform the described action.
+///
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// This file contains all the specific code for the
+/// basic-ssc-i2s-wm8731-project
+///
+/// !Contents
+///
+/// The code can be roughly broken down as follows:
+/// - Enable the clock
+/// - Load WAV file information
+/// - Configure and enable the Codec
+/// - Configure and enable the SSC interrupt
+/// - Play WAV file
+///
+/// Please refer to the list of functions in the #Overview# tab of this unit
+/// for more detailed information.
+//-----------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+#include <board_memories.h>
+#include <pio/pio.h>
+#include <irq/irq.h>
+#include <twi/twid.h>
+#include <twi/twi.h>
+#include <dbgu/dbgu.h>
+#include <ssc/ssc.h>
+#include <codec-wm8731/wm8731.h>
+#include <utility/wav.h>
+#include <utility/assert.h>
+#include <utility/math.h>
+#include <utility/trace.h>
+#include <memories/MEDSdcard.h>
+
+#include "fatfs_config.h"
+#if _FATFS_TINY != 1
+#include <fatfs/src/ff.h>
+#else
+#include <fatfs/src/tff.h>
+#endif
+#include <fatfs/src/ff_util.h>
+
+#include <string.h>
+
+#define AUDIO_USING_DMA
+#if defined (AUDIO_USING_DMA)
+#include <dmad/dmad.h>
+#include <dma/dma.h>
+#endif
+
+//------------------------------------------------------------------------------
+// Local constants
+//------------------------------------------------------------------------------
+
+/// Master clock frequency in Hz
+#define SSC_MCK 49152000
+
+/// Address at which the WAV file is located
+#define WAV_FILE_ADDRESS (0x60000000 + 0x100)//0x8000)
+
+/// Maximum size in bytes of the WAV file.
+#define MAX_WAV_SIZE 0x100000
+
+// TWI clock
+#define TWI_CLOCK 100000
+
+// PMC define
+#define AT91C_CKGR_PLLR AT91C_CKGR_PLLAR
+#define AT91C_PMC_LOCK AT91C_PMC_LOCKA
+
+#define AT91C_CKGR_MUL_SHIFT 16
+#define AT91C_CKGR_OUT_SHIFT 14
+#define AT91C_CKGR_PLLCOUNT_SHIFT 8
+#define AT91C_CKGR_DIV_SHIFT 0
+
+/// Maximum number of LUNs which can be defined.
+/// (Logical drive = physical drive = medium number)
+#define MAX_LUNS 1
+
+/// Available medias.
+Media medias[MAX_LUNS];
+
+#define ID_DRV DRV_MMC
+
+#define SAMPLE_RATE (48000)
+#define SLOT_BY_FRAME (2)
+#define BITS_BY_SLOT (16)
+
+#define AT91C_I2S_MASTER_TX_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\
+ AT91C_SSC_CKS_DIV +\
+ AT91C_SSC_CKO_CONTINOUS +\
+ AT91C_SSC_START_FALL_RF +\
+ ((1<<16) & AT91C_SSC_STTDLY) +\
+ ((((nb_bit_by_slot*nb_slot_by_frame)/2)-1) <<24))
+
+#define AT91C_I2S_TX_FRAME_SETTING(nb_bit_by_slot, nb_slot_by_frame)( +\
+ (nb_bit_by_slot-1) +\
+ AT91C_SSC_MSBF +\
+ (((nb_slot_by_frame-1)<<8) & AT91C_SSC_DATNB) +\
+ (((nb_bit_by_slot-1)<<16) & AT91C_SSC_FSLEN) +\
+ AT91C_SSC_FSOS_NEGATIVE)
+
+//------------------------------------------------------------------------------
+// Local variables
+//------------------------------------------------------------------------------
+
+/// List of pins to configure.
+static const Pin pins[] = {PINS_TWI0, PINS_SSC_CODEC, PIN_PCK0};
+
+/// Pointer to the playback WAV file header.
+static const WavHeader *userWav = (WavHeader *) (0x60000000);
+
+/// Indicates if the WAV file is currently being played.
+static unsigned char isWavPlaying;
+
+#if defined (AUDIO_USING_DMA)
+/// Number of samples which have already been transmitted.
+static unsigned int transmittedSamples;
+/// Number of samples that have not yet been transmitted.
+static unsigned int remainingSamples;
+#endif
+
+#if _FATFS_TINY == 0
+#define STR_ROOT_DIRECTORY "0:"
+#else
+#define STR_ROOT_DIRECTORY ""
+#endif
+
+#if defined(at91cap9stk)
+#define MCI_ID 1 //no connector for MCIO/SPI0
+#else
+#define MCI_ID 0
+#endif
+
+const char* FileName = STR_ROOT_DIRECTORY "sample.wav";
+
+static Twid twid;
+
+//------------------------------------------------------------------------------
+// Local functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Display the information of the WAV file (sample rate, stereo/mono and frame
+/// size) on the DBGU.
+//------------------------------------------------------------------------------
+static void DisplayWavInfo(void)
+{
+ printf("%c[2J", 27);
+ printf( " Wave file header information\n\r");
+ printf( "--------------------------------\n\r");
+ printf( " - Chunk ID = 0x%08X\n\r", userWav->chunkID);
+ printf( " - Chunk Size = %d\n\r", userWav->chunkSize);
+ printf( " - Format = 0x%08X\n\r", userWav->format);
+ printf( " - SubChunk ID = 0x%08X\n\r", userWav->subchunk1ID);
+ printf( " - Subchunk1 Size = %d\n\r", userWav->subchunk1Size);
+ printf( " - Audio Format = 0x%04X\n\r", userWav->audioFormat);
+ printf( " - Num. Channels = %d\n\r", userWav->numChannels);
+ printf( " - Sample Rate = %d\n\r", userWav->sampleRate);
+ printf( " - Byte Rate = %d\n\r", userWav->byteRate);
+ printf( " - Block Align = %d\n\r", userWav->blockAlign);
+ printf( " - Bits Per Sample = %d\n\r", userWav->bitsPerSample);
+ printf( " - Subchunk2 ID = 0x%08X\n\r", userWav->subchunk2ID);
+ printf( " - Subchunk2 Size = %d\n\r", userWav->subchunk2Size);
+ printf("Press a key to return to the menu ...\n\r");
+ DBGU_GetChar();
+}
+
+//------------------------------------------------------------------------------
+/// Displays the user menu on the DBGU.
+//------------------------------------------------------------------------------
+static void DisplayMenu(void)
+{
+ printf("%c[2J-- Basic SSC I2S WM8731 Project xxx --\n\r", 27);
+ printf("Menu :\n\r");
+ printf("------\n\r");
+
+ // Play a WAV file pre-loaded in SDCARD using SAM-BA
+ if (!isWavPlaying) {
+
+ printf(" W: Play the WAV file pre-loaded in SDCARD\n\r");
+ }
+
+ // Display the information of the WAV file (sample rate, stereo/mono and frame size)
+ printf(" I: Display the information of the WAV file\n\r");
+
+ // Stop the current playback (if any)
+ if (isWavPlaying) {
+
+ printf(" S: Stop playback\n\r");
+ }
+}
+
+#if defined(AUDIO_USING_DMA)
+void HDMA_IrqHandler(void)
+{
+ unsigned int size;
+ unsigned intFlag;
+
+ // One buffer sent & more buffers to send
+ if (remainingSamples > 0 ) {
+
+ size = min(remainingSamples / (userWav->bitsPerSample / 8), BOARD_SSC_DMA_FIFO_SIZE * MAX_SSC_LLI_SIZE/2);
+ SSC_WriteBuffer(AT91C_BASE_SSC0, (void *) (WAV_FILE_ADDRESS + transmittedSamples), size);
+ remainingSamples -= size * (userWav->bitsPerSample / 8);
+ transmittedSamples += size * (userWav->bitsPerSample / 8);
+ intFlag = 1 << (BOARD_SSC_DMA_CHANNEL + 8) ;
+ DMA_EnableIt(intFlag);
+ DMA_EnableChannel(BOARD_SSC_DMA_CHANNEL);
+ }
+ else if (remainingSamples == 0){
+ DMA_DisableChannel(BOARD_SSC_DMA_CHANNEL);
+ intFlag = 1 << (BOARD_SSC_DMA_CHANNEL + 8) ;
+ DMA_DisableIt(intFlag);
+ isWavPlaying = 0;
+ DisplayMenu();
+ }
+
+}
+#endif
+
+//------------------------------------------------------------------------------
+/// Play a WAV file pre-loaded in SDCARD.
+//------------------------------------------------------------------------------
+void PlayLoop(unsigned short *pExtMem, unsigned int numSamples)
+{
+ unsigned int i;
+ for (i = 0; i < numSamples; i++) {
+
+ SSC_Write(AT91C_BASE_SSC0, pExtMem[i]);
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Play a WAV file pre-loaded in SDCARD
+//------------------------------------------------------------------------------
+static void PlayWavFile(void)
+{
+#if !defined(AUDIO_USING_DMA)
+ unsigned int size;
+
+ size = userWav->subchunk2Size > MAX_WAV_SIZE ? MAX_WAV_SIZE : userWav->subchunk2Size;
+ SSC_EnableTransmitter(AT91C_BASE_SSC0);
+ PlayLoop((unsigned short *)WAV_FILE_ADDRESS, size >> 1);
+#else
+ unsigned int size;
+ unsigned int intFlag = 0;
+
+ size = userWav->subchunk2Size > MAX_WAV_SIZE ? MAX_WAV_SIZE : userWav->subchunk2Size;
+ SSC_EnableTransmitter(AT91C_BASE_SSC0);
+
+ // Start transmitting WAV file to SSC
+ remainingSamples = userWav->subchunk2Size;
+ transmittedSamples = 0;
+
+ intFlag = 1 << (BOARD_SSC_DMA_CHANNEL + 8) ;
+ DMA_DisableIt(intFlag);
+ DMA_DisableChannel(BOARD_SSC_DMA_CHANNEL);
+
+ // Fill DMA buffer
+ size = min(remainingSamples / (userWav->bitsPerSample / 8), BOARD_SSC_DMA_FIFO_SIZE * MAX_SSC_LLI_SIZE/2);
+ SSC_WriteBuffer(AT91C_BASE_SSC0, (void *) (WAV_FILE_ADDRESS + transmittedSamples), size);
+ remainingSamples -= size * (userWav->bitsPerSample / 8);
+ transmittedSamples += size * (userWav->bitsPerSample / 8);
+
+ intFlag = 1 << (BOARD_SSC_DMA_CHANNEL + 8) ;
+ DMA_EnableIt(intFlag);
+ DMA_EnableChannel(BOARD_SSC_DMA_CHANNEL);
+
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Stop the current playback (if any).
+//------------------------------------------------------------------------------
+static void StopPlayback(void)
+{
+ SSC_DisableTransmitter(AT91C_BASE_SSC0);
+}
+
+//------------------------------------------------------------------------------
+/// Check wav file from sdcard
+//------------------------------------------------------------------------------
+unsigned char CheckWavFile()
+{
+ FRESULT res;
+ FATFS fs; // File system object
+ FIL FileObject;
+
+ unsigned int numRead, pcmSize;
+
+ // Init Disk
+ printf("-I- Init media Sdcard\n\r");
+ MEDSdcard_Initialize(&medias[ID_DRV], MCI_ID);
+
+ // Mount disk
+ printf("-I- Mount disk %d\n\r", ID_DRV);
+ memset(&fs, 0, sizeof(FATFS)); // Clear file system object
+ res = f_mount(ID_DRV, &fs);
+ if( res != FR_OK ) {
+ printf("-E- f_mount pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
+ return 0;
+ }
+
+ res = f_open(&FileObject, FileName, FA_OPEN_EXISTING|FA_READ);
+ if (res == FR_OK) {
+ printf("-I- File Found!\n\r");
+ //f_close(&FileObject);
+ // FilePlay();
+ }
+ else {
+ printf("-E- File Not Found!\n\r");
+ return 1;
+ }
+
+ // Read header
+ f_read(&FileObject, (void*)userWav, sizeof(WavHeader), &numRead);
+ DisplayWavInfo();
+
+ // Load PCM
+ pcmSize = userWav->subchunk2Size;
+ if (pcmSize > MAX_WAV_SIZE) {
+ pcmSize = MAX_WAV_SIZE;
+ }
+ f_read(&FileObject, (void*)WAV_FILE_ADDRESS, pcmSize, &numRead);
+ printf("-I- PCM Load to %x, size %d\n\r", WAV_FILE_ADDRESS, numRead);
+ f_close(&FileObject);
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+/// Main function
+//------------------------------------------------------------------------------
+int main(void)
+{
+ unsigned char key;
+ unsigned char isValid;
+
+ // Configure all pins
+ PIO_Configure(pins, PIO_LISTSIZE(pins));
+
+ // Initialize the DBGU
+ TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
+
+ // Initialize PSRAM
+ BOARD_ConfigurePsram();
+
+ // Switch to Main clock
+ AT91C_BASE_PMC->PMC_MCKR = (AT91C_BASE_PMC->PMC_MCKR & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+
+ // Configure PLL to 98.285MHz
+ *AT91C_CKGR_PLLR = ((1 << 29) | (171 << AT91C_CKGR_MUL_SHIFT) \
+ | (0x0 << AT91C_CKGR_OUT_SHIFT) |(0x3f << AT91C_CKGR_PLLCOUNT_SHIFT) \
+ | (21 << AT91C_CKGR_DIV_SHIFT));
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK) == 0);
+
+ // Configure master clock in two operations
+ AT91C_BASE_PMC->PMC_MCKR = (( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK) & ~AT91C_PMC_CSS) | AT91C_PMC_CSS_MAIN_CLK;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+ AT91C_BASE_PMC->PMC_MCKR = ( AT91C_PMC_PRES_CLK_2 | AT91C_PMC_CSS_PLLA_CLK);
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) == 0);
+
+ // DBGU reconfiguration
+ DBGU_Configure(DBGU_STANDARD, 115200, SSC_MCK);
+
+ // Configure and enable the TWI (required for accessing the DAC)
+ *AT91C_PMC_PCER = (1<< AT91C_ID_TWI0);
+ TWI_ConfigureMaster(AT91C_BASE_TWI0, TWI_CLOCK, SSC_MCK);
+ TWID_Initialize(&twid, AT91C_BASE_TWI0);
+
+ // Enable the DAC master clock
+ AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLLA_CLK | AT91C_PMC_PRES_CLK_8;
+ AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0;
+ while ((AT91C_BASE_PMC->PMC_SR & AT91C_PMC_PCKRDY0) == 0);
+
+ printf("-- Basic SSC I2S WM8731 Project %s --\n\r", SOFTPACK_VERSION);
+ printf("-- %s\n\r", BOARD_NAME);
+ printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
+
+ // Check and load wav file from sdcard
+ isValid = CheckWavFile();
+ if(isValid) {
+ printf("-E- Open wav file fail!\r\n");
+ return 1;
+ }
+ // Load WAV file information
+ isValid = WAV_IsValid(userWav);
+ ASSERT(isValid, "-F- Invalid WAV file provided\n\r");
+ isWavPlaying = 0;
+
+ // Sample rate must be 48kHz
+ printf("-I- Sample rate = %d Hz\n\r", userWav->sampleRate);
+ ASSERT(userWav->sampleRate == 48000, "-F- The WAV file must have a sample rate of 48kHz\n\r");
+
+ // Initialize the audio DAC
+ WM8731_DAC_Init(&twid, WM8731_SLAVE_ADDRESS);
+
+ // Configure SSC
+ SSC_Configure(AT91C_BASE_SSC0,
+ AT91C_ID_SSC0,
+ SAMPLE_RATE * BITS_BY_SLOT * 2,
+ SSC_MCK);
+ SSC_ConfigureReceiver(AT91C_BASE_SSC0, 0, 0);
+ SSC_ConfigureTransmitter(AT91C_BASE_SSC0,
+ AT91C_I2S_MASTER_TX_SETTING(BITS_BY_SLOT, SLOT_BY_FRAME),
+ AT91C_I2S_TX_FRAME_SETTING( BITS_BY_SLOT, SLOT_BY_FRAME));
+ SSC_DisableTransmitter(AT91C_BASE_SSC0);
+
+#if defined(AUDIO_USING_DMA)
+ // Initialize DMA controller.
+ DMAD_Initialize(BOARD_SSC_DMA_CHANNEL, 0);
+ // Configure and enable the SSC interrupt
+ IRQ_ConfigureIT(AT91C_ID_HDMA, 0, HDMA_IrqHandler);
+ IRQ_EnableIT(AT91C_ID_HDMA);
+#endif
+
+ // Enter menu loop
+ while (1) {
+
+ // Display menu
+ DisplayMenu();
+
+ // Process user input
+ key = DBGU_GetChar();
+
+ // Play WAV file
+ if ((key == 'W') && !isWavPlaying) {
+
+ PlayWavFile();
+ isWavPlaying = 1;
+ }
+ // Display WAV information
+ else if (key == 'I') {
+
+ DisplayWavInfo();
+ }
+ // Stop playback
+ else if ((key == 'S') && isWavPlaying) {
+
+ StopPlayback();
+ isWavPlaying = 0;
+ }
+ }
+}
+
diff --git a/basic-ssc-i2s-wm8731-project/obj/.empty_dir b/basic-ssc-i2s-wm8731-project/obj/.empty_dir new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/basic-ssc-i2s-wm8731-project/obj/.empty_dir diff --git a/basic-ssc-i2s-wm8731-project/sample.wav b/basic-ssc-i2s-wm8731-project/sample.wav Binary files differnew file mode 100644 index 0000000..50c0e92 --- /dev/null +++ b/basic-ssc-i2s-wm8731-project/sample.wav |