📄 digital_audio_test.c
字号:
/*****************************************************************************
** **
** Name: Digital_Audio_test.c **
** **
******************************************************************************
(C) Copyright 2006 - Analog Devices, Inc. All rights reserved.
This software is proprietary and confidential. By using this software you agree
to the terms of the associated Analog Devices License Agreement.
Purpose: Perform a POST digital audio test on the 21364 EZ-Kit Lite
******************************************************************************/
#include <Cdef21262.h>
#include <def21262.h>
#include <sru.h>
#include <sysreg.h>
#include <signal.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "post_common.h"
#include "ad1835.h"
#include "CS8416.h"
//////////////////////////////////////////////////////////////////////////////
//
// COMMON DEFINES
//
//////////////////////////////////////////////////////////////////////////////
#define SPDIF_REQUIRED_SAMPLES ((MAX_SAMPLES) * 100)
#define SPDIF_DESIRED_FREQ ((float)3000.0)
#define SPDIF_SAMPLE_RATE ((float)48000.0)
#define SPDIF_AMPLITUDE ((float)8388607.5)
#define SPDIF_ACCEPTABLE_DEVIATION_AMP ((float)0.15)
#define SPDIF_ACCEPTABLE_DEVIATION_PCT ((float)0.10)
#define SPDIF_MAX_SIGNAL_STRENGTH (float)1000000.0
//////////////////////////////////////////////////////////////////////////////
//
// function prototypes
//
//////////////////////////////////////////////////////////////////////////////
int TEST_DIGITAL_AUDIO(void);
void SPDIF_SPORT0_ISR(int sig_int);
void SetupSPI1835(void);
void DisableSPI1835(void);
void SetupSPICS8416(void);
void DisableSPICS8416(void);
void SetupSPICS8416(void);
void DisableSPICS8416(void);
unsigned int TxCS8416SPI(int val);
void Delay (int i);
void InitDAI(void);
void InitCS8416viaSPI(void);
void Init1835viaSPI(void);
unsigned int ReadCS8416Register (int addr);
void InitSPORT(void);
void Setup_leds(void);
//////////////////////////////////////////////////////////////////////////////
//
// stand alone test jig
//
//////////////////////////////////////////////////////////////////////////////
#ifdef _STANDALONE_ // use this to run standalone tests
int g_loops = 0;
int main(void)
{
int bError = 1; // returning 1 indicates a pass, anything else is a fail
while(1)
{
bError = TEST_DIGITAL_AUDIO();
if( 0 == bError )
{
asm("nop;");
asm("nop;");
asm("nop;");
asm("emuidle;");
asm("nop;");
asm("nop;");
}
g_loops++;
}
}
#endif //#ifdef _STANDALONE_
//////////////////////////////////////////////////////////////////////////////
// int TEST_DIGITAL_AUDIO(void)
//
// PURPOSE: test analog audio interface
//
//////////////////////////////////////////////////////////////////////////////
int TEST_DIGITAL_AUDIO(void)
{
volatile int n, j;
volatile int bError = 0; // returning 1 indicates a pass, anything else is a fail
g_iSampleCount = 0; // reset the sample count
// disable the LED's for this test.
sysreg_bit_clr(sysreg_FLAGS, (FLG8O|FLG9O|FLG10O|FLG11O|FLG12O|FLG13O|FLG14O|FLG15O) ); //Setting flag pins as outputs
*pSYSCTL = 4;
InitDAI();
//--------------------------------------------------------
// A quick sanity check:make sure the SPI communication
// is working by reading the ID#/revision register
// Check ID of SPDIF to verify SPI communication
int CS8416_DevID = ReadCS8416Register (0x7f);
if ( CS8416_DevID != 0x2f)
{ while(1);}
InitCS8416viaSPI();
#ifdef AUDIO_TALKTHROUGH // define this if you want to hear digital audio routed to the analog output
Init1835viaSPI();
#endif
InitSPORT();
//============================================================
//
// Configure SPORTs 1 & 2 for output to DACs 1-4
//
// SPTRAN = Transmit on serial port
// BHD = Buffer hang disable
// OPMODE = I2S mode
// SLEN24 = 24 bit of data in each 32-bit word
// SPEN_A = Enable data channel A
// SPEN_A = Enable data channel B
//
//------------------------------------------------------------
*(volatile int *)SPCTL1 = (SPTRAN | BHD | OPMODE | SLEN24 | SPEN_A | SPEN_B);
*(volatile int *)SPCTL2 = (SPTRAN | BHD | OPMODE | SLEN24 | SPEN_A | SPEN_B);
// reset the buffer indexs
g_iSampleIndex = 0;
g_iSampleCount = 0;
//--------------------------------------------------------
// Enable interrupts (globally)
// Unmask the SPORT0 ISR
interrupt (SIG_SP0,SPDIF_SPORT0_ISR);
// Be in infinite loop and do nothing until done.
while( g_iSampleCount < SPDIF_REQUIRED_SAMPLES )
{
// once the required number of samples has been collected,
// process the signal.
};
// turn off interrupts so that the data is stable.
interrupt(SIG_SP0, SIG_IGN);
// test the left channel
bError = Test_Channel((float*)g_fSineWaveIn_Left, MAX_SAMPLES, SPDIF_SAMPLE_RATE, SPDIF_DESIRED_FREQ, SPDIF_ACCEPTABLE_DEVIATION_PCT, SPDIF_MAX_SIGNAL_STRENGTH, SPDIF_MAX_SIGNAL_STRENGTH);
// now that the test is over, setup the LED's again
Setup_leds();
return bError;
}
void InitDAI(void)
{
//========================================================================
//
// MCLK: Route the MCLK recovered from the SPDIF receiver to the ADC
//
SRU(DAI_PB02_O, DAI_PB06_I);
SRU(LOW,DAI_PB02_I);
SRU(LOW,PBEN02_I );
SRU(HIGH,PBEN06_I );
//========================================================================
//
// Connect the SPDIF: The CS8416 drives a BCLK output into DAI pin 7, a
// LRCLK (a.k.a. frame sync) into DAI pin 8 and data into DAI pin 5.
//
// Connect the SPDIF to SPORT0, using data input A
//
// All three lines are always inputs to the SHARC so tie the pin
// buffer inputs and pin buffer enable inputs all low.
//------------------------------------------------------------------------
// Connect the SPDIF receiver to SPORT0, using data input A
SRU(DAI_PB03_O , SPORT0_CLK_I);
SRU(DAI_PB04_O , SPORT0_FS_I );
SRU(DAI_PB01_O , SPORT0_DA_I );
//------------------------------------------------------------------------
// Tie the pin buffer inputs LOW for DAI pins 1, 3 and 4
SRU(LOW,DAI_PB01_I);
SRU(LOW,DAI_PB03_I);
SRU(LOW,DAI_PB04_I);
//------------------------------------------------------------------------
// Tie the pin buffer enable inputs LOW for DAI pins 1, 3 and 4
SRU(LOW,PBEN01_I );
SRU(LOW,PBEN03_I );
SRU(LOW,PBEN04_I );
//------------------------------------------------------------------------
// Use DAI pin 15 as an SPI device select line for the SPDIF
SRU(HIGH,DAI_PB15_I);
SRU(HIGH,PBEN15_I );
//------------------------------------------------------------------------
// Define the SPDIF "non-audio" signal line as an input
SRU(LOW,PBEN16_I );
//========================================================================
//
// Connect the DACs: The codec accepts a BCLK input from DAI pin 13 and
// a LRCLK (a.k.a. frame sync) from DAI pin 14 and has four
// serial data outputs to DAI pins 12, 11, 10 and 9
//
// Connect DAC1 to SPORT1, using data output A
// Connect DAC2 to SPORT1, using data output B
// Connect DAC3 to SPORT2, using data output A
// Connect DAC4 to SPORT2, using data output B
//
// Connect the clock and frame sync inputs to SPORT1 and SPORT2
// should come from the SPDIF on DAI pins 7 and 8, respectively
//
// Connect the SPDIF BCLK and LRCLK back out to the DAC on DAI
// pins 13 and 14, respectively.
//
// All six DAC connections are always outputs from the SHARC
// so tie the pin buffer enable inputs all high.
//
//------------------------------------------------------------------------
// Connect the pin buffers to the SPORT data lines and ADC BCLK & LRCLK
SRU(SPORT2_DB_O, DAI_PB09_I); //to DAC4
SRU(SPORT2_DA_O, DAI_PB10_I); //to DAC3
SRU(SPORT1_DB_O, DAI_PB11_I); //to DAC2
SRU(SPORT1_DA_O, DAI_PB12_I); //to DAC1
SRU(DAI_PB03_O , SPORT1_CLK_I);//from SPDIF
SRU(DAI_PB03_O , SPORT2_CLK_I);//from SPDIF
SRU(DAI_PB04_O , SPORT1_FS_I); //from SPDIF
SRU(DAI_PB04_O , SPORT2_FS_I); //from SPDIF
SRU(DAI_PB03_O , DAI_PB13_I); //clock (BCLK) input from SPDIF on PB03 fed back to DAC via PB13
SRU(HIGH, PBEN13_I); //enable BCLK to DACs
SRU(DAI_PB04_O , DAI_PB14_I); //FS (LRCLK) input from SPDIF on PB04 fed back to DAC via PB14
SRU(HIGH, PBEN14_I); //enable LRCLK to DACs
SRU(HIGH, PBEN12_I); //enable S1DA output on pin 12
SRU(HIGH, PBEN11_I); //enable S1Db output on pin 11
SRU(HIGH, PBEN10_I); //enable S2Da output on pin 10
SRU(HIGH, PBEN09_I); //enable S2Db output on pin 9
}
// Set up the SPI port to access the CS8416
void SetupSPICS8416 ()
{
// Flush the SPI transceive FIFOs
*(volatile int *)SPICTL = (TXFLSH | RXFLSH);
// Setup the baud rate to 1MHz
*(volatile int *)SPIBAUD = 100;
// Flag pins are not being used as the device select
*(volatile int *)SPIFLG = 0;
// Now configure the SPI control register
*(volatile int *)SPICTL = (SPIEN | SPIMS | MSBF | TIMOD1);
}
// Disable the SPI Port and flush the transceive FIFOs
void DisableSPICS8416 ()
{
*(volatile int *)SPICTL = (TXFLSH | RXFLSH);
}
// Read a register from the CS8416
unsigned int ReadCS8416Register (int addr)
{
SetupSPICS8416 ();
SRU(LOW,DAI_PB15_I);
TxCS8416SPI(SPDIF_WRITE_REG);
TxCS8416SPI(addr);
SRU(HIGH,DAI_PB15_I);
Delay (100) ;
SRU(LOW,DAI_PB15_I);
// Write a dummy value to clock the output
TxCS8416SPI(SPDIF_READ_REG);
TxCS8416SPI(0x00);
SRU(HIGH,DAI_PB15_I);
DisableSPICS8416 ();
return *(volatile int *)RXSPI ;
}
unsigned int TxCS8416SPI(int val)
{
*(volatile int *)TXSPI = val;
Delay (100) ;
while (1) // Wait for the SPI port to finish
{
if ( SPIF & *(volatile int *)SPISTAT)
break;
}
Delay (100) ;
return *(volatile int *)RXSPI;
}
// Send a word to the CS8416 via SPI
void WriteCS8416Register (int add, int val)
{
SRU(LOW,DAI_PB15_I);
TxCS8416SPI(SPDIF_WRITE_REG);
TxCS8416SPI(add);
TxCS8416SPI(val);
SRU(HIGH,DAI_PB15_I);
}
//Set up all CS8416 registers via SPI
void InitCS8416viaSPI()
{
// outputMuted = 0;
SetupSPICS8416 () ;
WriteCS8416Register(SPDIF_CTRL1, (0x00));
WriteCS8416Register(SPDIF_CTRL2, GPO_NON_AUDIO);
WriteCS8416Register(SPDIF_CTRL3, (0xC0));
WriteCS8416Register(SPDIF_CTRL4, (0x81));
WriteCS8416Register(SPDIF_DATA_FORMAT, FRMT_I2S);
WriteCS8416Register(SPDIF_RX_ERR_MASK, (0x00));
WriteCS8416Register(SPDIF_INT_MASK, (0x00));
WriteCS8416Register(SPDIF_INT_MODE_MSB, (0x00));
WriteCS8416Register(SPDIF_INT_MODE_LSB, (0x00));
DisableSPICS8416 () ;
}
//////////////////////////////////////////////////////////////////////////////
// void SPDIF_SPORT0_ISR(int sig_int)
//
// PURPOSE: SPORT0 isr
//
// INPUT: sig_int
// OUTPUT: none
//////////////////////////////////////////////////////////////////////////////
void SPDIF_SPORT0_ISR(int sig_int)
{
int nInValue = *(volatile int *)RXSP0A;
if( nInValue & 0x00800000)
{ // negative sign extend
nInValue |= 0xFF000000;
}
g_fSineWaveIn_Left[g_iSampleIndex] = (float)nInValue;
if( g_bLeftRight )
{ // right side
}
else
{ // left side
g_iSampleIndex++; // only increment the index when both channels have been sent.
}
g_bLeftRight = !g_bLeftRight;
if( g_iSampleIndex > MAX_SAMPLES-1 )
g_iSampleIndex = 0;
g_iSampleCount++;
#ifdef AUDIO_TALKTHROUGH // define this if you want to hear digital audio routed to the analog output
*(volatile int *)TXSP1A = nInValue; // write to DAC1
*(volatile int *)TXSP1B = nInValue; // write to DAC2
*(volatile int *)TXSP2A = nInValue; // write to DAC3
*(volatile int *)TXSP1B = nInValue; // write to DAC4
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -