AnsweredAssumed Answered

EZ-Lite Dev Kit.

Question asked by khal on Feb 13, 2012
Latest reply on Apr 11, 2012 by Prashant

Hi,

I am trying to loop back my microphone to my speaker using the codec available on the EZ-Lite development board that came with the BF592 DSP chip. While I could send data to the speaker, I could not read from the microphone. My starting point was the power-on example which I found in the BF59x examples. I modified it such that I use on the audio-test (as it is all I need), but unforunately did not get anything useful from the microphone. I followed the readme file to set the switches and jumpers in their right places and double check them. Still nothing. Below is my modified main:

 

/*******************************************************************
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.

Project Name:   Power_On_Self_Test

Hardware:  ADSP-BF592 EZ-KIT Lite

Description: This file tests the audio codec on the EZ-Kit.
*******************************************************************/


/*******************************************************************
*  include files
*******************************************************************/
#include <sysreg.h>
#include <ccblkfn.h>
#include <signal.h>
#include <complex.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <filter.h>
#include <vector.h>


#include "post_common.h"


/*******************************************************************
*  function prototypes
*******************************************************************/
void Reset_TWI(void);
void TWI_MasterMode_Write(unsigned short DeviceAddr, unsigned char *TWI_Data_Pointer, unsigned short Count, unsigned short TWI_Length);
void TWI_MasterMode_Read(unsigned short DeviceAddr, unsigned char *TWI_Data_Pointer, unsigned short Count);


/*******************************************************************
*  global variables and defines
*******************************************************************/
#define LEFT_LINE_IN     0x0000
#define RIGHT_LINE_IN     0x0200
#define LEFT_HEADPHONE_OUT     0x0400
#define RIGHT_HEADPHONE_OUT    0x0600
#define ANALOG_AUDIO_PATH_CONTROL   0x0800
#define DIGITAL_AUDIO_PATH_CONTROL   0x0a00
#define POWER_DOWN_CONTROL     0x0c00
#define DIGITAL_AUDIO_INTERFACE_FORMAT  0x0e00
#define SAMPLING_CONTROL     0x1000
#define ACTIVE_CONTROL      0x1200
#define RESET_CONTROL      0x1E00


/* codec's TWI address, this is the upper 7 bits, the lowest bit will
be 0 for write (0x36), and 1 for read (0x37) */
#define CODEC_TWI_ADDRESS 0x1b

/* size of array sCodecTxRegs */
#define CODEC_REGS_LENGTH 9

/* SPI transfer mode */
#define TIMOD_DMA_TX 0x0003

/* SPORT0 word length */
#define SLEN_32 0x001f
#define SLEN_16 0x000f

/* DMA flow mode */
#define FLOW_1 0x1000

int iChannel0LeftIn, iChannel1LeftIn;  /* left input data */
int iChannel0RightIn, iChannel1RightIn;  /* right input data */
int iChannel0LeftOut, iChannel1LeftOut;  /* left ouput data */
int iChannel0RightOut, iChannel1RightOut; /* right ouput data */

volatile short sCodecResetReg = 0x1E00;
volatile short sCodecTxRegs[CODEC_REGS_LENGTH] =
{
LEFT_LINE_IN     | 0x01b, /* greater than 0db volume */
RIGHT_LINE_IN     | 0x01b, /* greater than 0db volume */
LEFT_HEADPHONE_OUT    | 0x07f, /* gain */
RIGHT_HEADPHONE_OUT    | 0x07f, /* gain */
ANALOG_AUDIO_PATH_CONTROL  | 0x010,
DIGITAL_AUDIO_PATH_CONTROL  | 0x000,
POWER_DOWN_CONTROL    | 0x000,
DIGITAL_AUDIO_INTERFACE_FORMAT | 0x042,
SAMPLING_CONTROL    | 0x000, /* set Normal mode */
};

volatile short sCodecActCtl[] =
{
ACTIVE_CONTROL     | 0x001,  /* last register write to activate the codec */
};


static short Process = 0;
static short PingPongSw = 1;

int ipPing[2*MAX_SAMPLES];
int ipPong[2*MAX_SAMPLES];
int opPing[2*MAX_SAMPLES];
int opPong[2*MAX_SAMPLES];

 


int iTxBuffer1[4]; /* SPORT0 DMA transmit buffer */
int iRxBuffer1[4]; /* SPORT0 DMA receive buffer */

volatile int g_iSampleIndex = 1;
volatile int g_iSampleCount = 0;
volatile int g_iIndex = 0;

 

short g_sSineWaveIn_Left[MAX_SAMPLES];
short g_sSineWaveIn_Right[MAX_SAMPLES];
short g_sInput[MAX_SAMPLES];
int g_sInput_DMA[MAX_SAMPLES*2];

bool bMicInLineOut = false;

#if defined(__DEBUG_FILE__)
extern FILE *pDebugFile;    /* debug file */
#endif


/*******************************************************************
*  function prototypes
*******************************************************************/
void Init_Codec(void);
void Init_Sport0_Audio(bool tx, bool rx);
void Init_DMA_Audio(bool tx, bool rx);
void Enable_DMA_Sport0_Audio(bool tx, bool rx);
void Disable_DMA_Sport0_Audio(bool tx, bool rx);
void Init_Interrupts_Audio(void);
void Init_Flags_Audio(void);
EX_INTERRUPT_HANDLER(Sport0_RX_ISR);
int Test_Channel(short* psRealIn);
int TEST_AUDIO(void);


/****************************************************************************
*   Function:    Init_Flags_Audio
*   Description: Configure PORTG and PORTH flags to control CODEC
******************************************************************************/
void Init_Flags_Audio(void)
{
/* DT0PRI, DR0PRI, RFS0, RSCLK0, TFS0, TSCLK0 */
*pPORTG_MUX &= ~(PG1 | PG2 | PG3 | PG5 | PG6 | PG7);
ssync();
    *pPORTG_FER |= (PG1 | PG2 | PG3 | PG5 | PG6 | PG7);
ssync();
}


/****************************************************************************
*   Function:    Init_Interrupts_Audio
*   Description: Init Sport 0 interrupt
******************************************************************************/
void Init_Interrupts_Audio(void)
{
/* assign ISRs to interrupt vectors, sport0 RX ISR -> IVG 9 */
register_handler(ik_ivg9, Sport0_RX_ISR);

/* enable Sport0 RX interrupt */
*pSIC_IMASK0 |= 0x200;
}


/****************************************************************************
*   Function:    Init_Codec
*   Description: This function sends all values in the array sCodecResetReg[]
*      to the codec. Different configurations can be set up by
*      modifiying the values in this array.
******************************************************************************/
void Init_Codec(void)
{
int i;
int j;

unsigned char ResetControl[] =  { 0x1e, 0x00};

unsigned char LeftLineIn[] =   { 0x00, 0x01b};
unsigned char RightLineIn[] =   { 0x02, 0x01b};
unsigned char LeftHpOut[] =   { 0x04, 0x07f};
unsigned char RightHpOut[] =   { 0x06, 0x07f};
unsigned char AnalogControl[] =  { 0x08, 0x010};
unsigned char DigitalControl[] =  { 0x0a, 0x000};
unsigned char PowerDownControl[] =  { 0x0c, 0x000};
unsigned char DigitalAudioFormat[] ={ 0x0e, 0x042};
unsigned char SamplingControl[] =  { 0x10, 0x000};

unsigned char ActiveControl[] =  { 0x12, 0x001};


Reset_TWI();  /* reset the TWI interface */

TWI_MasterMode_Write( CODEC_TWI_ADDRESS, ResetControl, 1, 2);

TWI_MasterMode_Write( CODEC_TWI_ADDRESS, LeftLineIn, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, RightLineIn, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, LeftHpOut, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, RightHpOut, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, AnalogControl, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, DigitalControl, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, PowerDownControl, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, DigitalAudioFormat, 1, 2);
TWI_MasterMode_Write( CODEC_TWI_ADDRESS, SamplingControl, 1, 2);

/* wait until dma transfers for spi are finished but we also have to give extra
    time for the codec to charge:

  - Writing 0x0 to POWER_DOWN_CONTROL internally powers the codec and it begins
    to charge to AVDD/2.
  - We cannot write 0x1 to ACTIVE_CONTROL until the codec is charged over 10% of
    AVDD or else the codec may not work properly.
  - The charge time is based on the internals of the codec and is calculated as
    follows: T = C*25K/3.5, where C is the capacitor value on VMID.  The EZ-KIT
    uses C = 10.1 uF, so our expected charge time is T = (10.1 uF)*(25K)/3.5
    which equals 72ms.
  - So we must delay at least 72ms before setting the ACTIVE_CONTROL register
  - Since the processor clock is running at 400MHz we are setting the delay
    value to 0x1ffffff.  This is a delay of ~84 ms 2.5ns * 0x1ffffff) 
*/

for (j=0; j<0x1ffffff; j++) asm("nop;");

/*** lastly activate the digital engine *******************/

TWI_MasterMode_Write( CODEC_TWI_ADDRESS, ActiveControl, 1, 2);

}


/****************************************************************************
*   Function:    Init_Sport0_Audio
*   Description: Configure SPORT0 for I2S mode, to transmit/receive data
*                to/from the codec. Configure Sport for ext clock and
*                internal frame sync.
******************************************************************************/
void Init_Sport0_Audio(bool tx, bool rx)
{
if ( rx )
{
  /* sport0 receive configuration */
  *pSPORT0_RCR1 = RFSR | RCKFE;
  *pSPORT0_RCR2 = SLEN_32 | RSFSE;
}

if ( tx )
{
  /* sport0 transmit configuration */
  *pSPORT0_TCR1 = TFSR | TCKFE;
  *pSPORT0_TCR2 = SLEN_32 | TSFSE;
}
}


/****************************************************************************
*   Function:    Init_DMA_Audio
*   Description: DMA Controller Programming For SPORT0
*                Sets up DMA1 and DMA2 in autobuffer mode to receive and
*     transmit SPORT data
******************************************************************************/
void Init_DMA_Audio(bool tx, bool rx)
{
if ( rx )
{
  /* configure DMA1 */

  /* 32-bit transfers, interrupt on completion, autobuffer mode */
  *pDMA1_CONFIG = WNR | WDSIZE_32 | DI_EN | FLOW_1;
  *pDMA1_START_ADDR = ipPing;  /* start address of data buffer */
  *pDMA1_X_COUNT = (2 * MAX_SAMPLES);     /* DMA loop count */
  *pDMA1_X_MODIFY = 4;    /* DMA loop address increment */
}

if ( tx )
{
  /* configure DMA2 */

  *pDMA2_CONFIG = WDSIZE_32 | FLOW_1; /* 32-bit transfers, autobuffer mode */
  *pDMA2_START_ADDR = opPong; /* start address of data buffer */
  *pDMA2_X_COUNT = (2 * MAX_SAMPLES);
  *pDMA2_X_MODIFY = 4;    /* DMA loop address increment */
}
}


/****************************************************************************
*   Function:    Enable_DMA_Sport0_Audio
*   Description: Enable DMA1, DMA2, Sport0 TX and Sport0 RX
******************************************************************************/
void Enable_DMA_Sport0_Audio(bool tx, bool rx)
{
if ( rx )
{
  *pDMA1_CONFIG = (*pDMA1_CONFIG | DMAEN); /* enable DMA for RX */
  *pSPORT0_RCR1  = (*pSPORT0_RCR1 | RSPEN); /* enable sport0 RX */
}

if ( tx )
{
  *pDMA2_CONFIG = (*pDMA2_CONFIG | DMAEN); /* enable DMA for TX */
  *pSPORT0_TCR1  = (*pSPORT0_TCR1 | TSPEN); /* enable sport0 TX */
}
}


/****************************************************************************
*   Function:    Disable_DMA_Sport0_Audio
*   Description: Disable DMA1, DMA2, Sport0 TX and Sport0 RX
******************************************************************************/
void Disable_DMA_Sport0_Audio(bool tx, bool rx)
{
if ( rx )
{
  *pDMA1_CONFIG &= ~0x1; /* disable DMA for RX */
  *pSPORT0_RCR1 &= ~0x1; /* disable sport0 RX */
}

if ( tx )
{
  *pDMA2_CONFIG &= ~0x1; /* disable DMA for TX */
  *pSPORT0_TCR1 &= ~0x1; /* disable sport0 TX */
}
}


/****************************************************************************
*   Function:    Sport0_RX_ISR
*   Description: This ISR is executed after a complete frame of input data
*     has been received. The ISR will output the sine wave data
*     and when the data is received it is stored in a buffer
******************************************************************************/
EX_INTERRUPT_HANDLER(Sport0_RX_ISR)
{

/* confirm interrupt handling */
*pDMA1_IRQ_STATUS = 0x0001;
*pDMA2_IRQ_STATUS = 0x0001;


*pDMA1_START_ADDR = (PingPongSw == 1)? ipPong:ipPing;  /* start address of data buffer */
*pDMA2_START_ADDR = (PingPongSw == 1)? opPing:opPong;  /* start address of data buffer */

PingPongSw = (PingPongSw == 1)? 0:1;

*pDMA1_CONFIG |= DMAEN; /* 32-bit transfers, autobuffer mode */
*pDMA2_CONFIG |= DMAEN; /* 32-bit transfers, autobuffer mode */
Process = 1;

}

/*******************************************************************
*   Function:    TEST_AUDIO
*   Description: Main test routine will get launched from the POST
*     framework.
*******************************************************************/
int TEST_AUDIO(void)
{
int nResult = 1;
int i = 0, j = 0, n = 0;

 

  Init_Flags_Audio();
  Init_Codec();
  Init_Sport0_Audio(true, true);
  Init_DMA_Audio(true, true);
  Init_Interrupts_Audio();
  Enable_DMA_Sport0_Audio(true, true);

 

    return;
}


void main()
{
int i,j;
#if 1
for( i = 0; i < MAX_SAMPLES; i++ )
{
     g_sInput[i] = (int)(AMPLITUDE * sin( (2.0 * PI * DESIRED_FREQ * ( i / SAMPLE_RATE))) );
}
for( i = 0, j = 0; i < (2 * MAX_SAMPLES); i++, j++ )
{
     opPing[i] = opPong[i] = g_sInput[j] << 16;
     i++;
     opPing[i] = opPong[i] = g_sInput[j] << 16;
}
#endif
TEST_AUDIO();
while(1)
{
  if(Process == 1)
  {
#if 1
   if(PingPongSw == 1)
    for(i=0; i< 2*MAX_SAMPLES;i++)
     opPong[i] = ipPing[i];
   else
    for(i=0; i< 2*MAX_SAMPLES;i++)
     opPing[i] = ipPong[i];
#endif
   Process = 0;
  }
  asm("nop;");
}
return;
}

Outcomes