import basic-ssc-i2s-wm8731-project from at91sam3-ek
ported to at91lib-1.9
This commit is contained in:
parent
eebb6cc121
commit
70285f225b
Binary file not shown.
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue