/*H***************************************************************************
*
* $Archive:: /boards/dsk5509a_v1/examples/test/test.c                         $
* $Revision:: 8                                                               $
* $Date:: 2/01/06 1:37p                                                       $
* $Author:: Vss6admin                                                         $
*
* DESCRIPTION:
*
*   
* (C) Copyright 2005 by Spectrum Digital Incorporated
* All rights reserved
*
*H***************************************************************************/

/*------------------------------------------------------------------------*
 *  This is a test program that uses DSK5509A Board Support Library to
 *  perform a confidence test on a DSK5509A.  While it is running, it
 *  will display the current test index in binary on the LEDs.  If it
 *  fails a test, the test index will blink indefinitely to alert you to
 *  the failure.  If all tests pass, all of the LEDs will blink 3 times
 *  then stay on.
 *
 *  The following tests are performed:
 *
 *  Index    Description
 *    1      Internal memory Version
 *    2      External memory(SDRAM)
 *    3      Flash
 *    4      Codec
 *    5      UserIO
 *    6      MemPattern(Fill pattern)
 *    7      MemPattern(Address Pattern)
 *    8      DSP
 *    9      LED/Swt
 *    10     Codec LoopBack
 *
 *  Please see the DSK5509A BSL Examples for more detailed information.

 *  DSP/BIOS is configured using the DSP/BIOS configuration tool.  Settings
 *  for this example are stored in a configuration file called test.cdb.  At
 *  compile time, Code Composer will auto-generate DSP/BIOS related files
 *  based on these settings.  A header file called testcfg.h contains the
 *  results of the autogeneration and must be included for proper operation.
 *  The name of the file is taken from test.cdb and adding cfg.h.
 *------------------------------------------------------------------------*/

#define test_c


/*****************************************************************************
* INCLUDE FILES
*****************************************************************************/
/*---- system and platform files -------------------------------------------*/

#include "testcfg.h"
/*------------------------------------------------------------------------*
 *  The test uses the Chip Support Library for basic definitions as well as
 *  McBSP manipulation.  Programs that use the CSL must include the
 *  appropriate header files.
 *------------------------------------------------------------------------*/
#include <csl.h>
#include <csl_mcbsp.h>
#include <csl_dma.h>
#include <csl_timer.h>

/*------------------------------------------------------------------------*
 *  The Board Support Library is divided into several modules, each
 *  of which has its own include file.  The file dsk5509.h must be included
 *  in every program that uses the BSL.  This example also includes
 *  BSL header files for each module it uses.
 *------------------------------------------------------------------------*/
#include "dsk5509.h"
#include "dsk5509_led.h"
#include "dsk5509_aic23.h"
#include "dsk5509_flash.h"
#include "dsk5509_dip.h"

/* Length of sine wave table */
#define SINE_TABLE_SIZE  48

/* Number of elements for DMA and McBSP loopback tests */
#define N                16

/* Pre-generated sine wave data, 16-bit signed samples */
int sinetable[SINE_TABLE_SIZE] = {
    0x0000, 0x10b4, 0x2120, 0x30fb, 0x3fff, 0x4dea, 0x5a81, 0x658b,
    0x6ed8, 0x763f, 0x7ba1, 0x7ee5, 0x7ffd, 0x7ee5, 0x7ba1, 0x76ef,
    0x6ed8, 0x658b, 0x5a81, 0x4dea, 0x3fff, 0x30fb, 0x2120, 0x10b4,
    0x0000, 0xef4c, 0xdee0, 0xcf06, 0xc002, 0xb216, 0xa57f, 0x9a75,
    0x9128, 0x89c1, 0x845f, 0x811b, 0x8002, 0x811b, 0x845f, 0x89c1,
    0x9128, 0x9a76, 0xa57f, 0xb216, 0xc002, 0xcf06, 0xdee0, 0xef4c
};

/* Codec configuration settings */
DSK5509_AIC23_Config config = {
    0x0017, // 0 DSK5509_AIC23_LEFTINVOL  Left line input channel volume
    0x0017, // 1 DSK5509_AIC23_RIGHTINVOL Right line input channel volume
    0x00d8, // 2 DSK5509_AIC23_LEFTHPVOL  Left channel headphone volume
    0x00d8, // 3 DSK5509_AIC23_RIGHTHPVOL Right channel headphone volume
    0x0011, // 4 DSK5509_AIC23_ANAPATH    Analog audio path control
    0x0000, // 5 DSK5509_AIC23_DIGPATH    Digital audio path control
    0x0000, // 6 DSK5509_AIC23_POWERDOWN  Power down control
    0x0043, // 7 DSK5509_AIC23_DIGIF      Digital audio interface format
    0x0081, // 8 DSK5509_AIC23_SAMPLERATE Sample rate control
    0x0001  // 9 DSK5509_AIC23_DIGACT     Digital interface activation
};

MCBSP_Config mcbspCfg_loopback = {
    0xa000,        /*  Serial Port Control Register 1   */
    0x0100,        /*  Serial Port Control Register 2   */
    0x0140,        /*  Receive Control Register 1   */
    0x0000,        /*  Receive Control Register 2   */
    0x0140,        /*  Transmit Control Register 1   */
    0x0000,        /*  Transmit Control Register 2   */
    0x0000,        /*  Sample Rate Generator Register 1   */
    0x2000,        /*  Sample Rate Generator Register 2   */
    0x0000,        /*  Multichannel Control Register 1   */
    0x0000,        /*  Multichannel Control Register 2   */
    0x0a03,        /*  Pin Control Register   */
    0x0000,        /*  Receive Channel Enable Register Partition A   */
    0x0000,        /*  Receive Channel Enable Register Partition B   */
    0x0000,        /*  Receive Channel Enable Register Partition C   */
    0x0000,        /*  Receive Channel Enable Register Partition D   */
    0x0000,        /*  Receive Channel Enable Register Partition E   */
    0x0000,        /*  Receive Channel Enable Register Partition F   */
    0x0000,        /*  Receive Channel Enable Register Partition G   */
    0x0000,        /*  Receive Channel Enable Register Partition H   */
    0x0000,        /*  Transmit Channel Enable Register Partition A   */
    0x0000,        /*  Transmit Channel Enable Register Partition B   */
    0x0000,        /*  Transmit Channel Enable Register Partition C   */
    0x0000,        /*  Transmit Channel Enable Register Partition D   */
    0x0000,        /*  Transmit Channel Enable Register Partition E   */
    0x0000,        /*  Transmit Channel Enable Register Partition F   */
    0x0000,        /*  Transmit Channel Enable Register Partition G   */
    0x0000         /*  Transmit Channel Enable Register Partition H   */
    };

/* Define source and destination arrays for DMA and loopback tests */
Uint16 src[N], dst[N], buffer[256];

/* Define buffers for host side communication */
Uint16 *cmdbuf, *databuf;


/* Variables used by the TEST_sleep() funciton */
Uint16 eventId1;
volatile Uint16 sleepCount = 0;

/*--------------------------------ACCESSORY FUNCTIONS-------------------------------------*/
/*F***************************************************************************
* NAME:  sleepIsr() 
*
* DESCRIPTION: Interrupt Service routine
*
* NOTES:
*   
*F***************************************************************************/
void sleepIsr()
{
    sleepCount++;
}
/*F***************************************************************************
* NAME:  TEST_sleep(Int16 sleeptime) 
*
* DESCRIPTION: Accessory Function
*
* NOTES:
*   
*F***************************************************************************/
void TEST_sleep(Int16 sleeptime)
{
	TIMER_Handle hTimer1;
	TIMER_Config timerCfg1 = 
	{
		TIMER_TCR_RMK( TIMER_TCR_IDLEEN_DISABLE,
		               TIMER_TCR_FUNC_OF( 1 ),
		               TIMER_TCR_TLB_NORESET,
		               TIMER_TCR_SOFT_BRKPTNOW,
		               TIMER_TCR_FREE_WITHSOFT,
		               TIMER_TCR_PWID_OF( 0 ),
		               TIMER_TCR_ARB_RESET,
		               TIMER_TCR_TSS_STOP,
		               TIMER_TCR_CP_CLOCK,
		               TIMER_TCR_POLAR_LOW,
		               TIMER_TCR_DATOUT_0 ),
		               TIMER_PRD_RMK(  TIMER_PRD_PRD_OF( 0x4e1f ) ),
		               TIMER_PRSC_RMK( TIMER_PRSC_PSC_OF( 0 ),
		               TIMER_PRSC_TDDR_0F( 9 ) )
	   };
	
	/* Open the timer */
	hTimer1 = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET);
	
	/* Configure the timer in one-shot mode */
	TIMER_config(hTimer1, &timerCfg1);
	
	/* Get Event Id associated with Timer 1, for use with */
	/* CSL interrupt enable functions.                    */
	eventId1 = TIMER_getEventId(hTimer1);
	
	/* Map the logical event to a physical interrupt */
	IRQ_map(eventId1);
	
	/* Clear any pending Timer interrupts */
	IRQ_clear(eventId1);
	
	/* Enable timer interrupt */
	IRQ_enable(eventId1);
	
	/* Make sure global interrupts are enabled */
	IRQ_globalEnable();
	
	/* Clear sleep count */
	sleepCount = 0;
	    
	/* Start timer 1 */
	TIMER_start(hTimer1);
	
	while(sleepCount < sleeptime);
	
	/* Disable timer interrupt */
	IRQ_disable(eventId1);
	    
	TIMER_close(hTimer1);
}
/*----------------------------END ACCESSORY FUNCTIONS-------------------------------------*/
/*-----------------------------LED FUNCTIONS-----------------------------------------------*/
/*F***************************************************************************
* NAME:  LED_binary(Int16 ledmask) 
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
void LED_binary(Int16 ledmask)
{
    Int16 i, bit;

    /* Walk through the bits in num setting corresponding LEDs */
    bit = 1;
    for (i = 0; i < 4; i++)
    {
        if (ledmask & bit)
            DSK5509_LED_on(i);
        else
            DSK5509_LED_off(i);
        bit = bit << 1;
    }

}

/*F***************************************************************************
* NAME:  LED_blink(Int16 ledmask, Int16 count)  
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
void LED_blink(Int16 ledmask, Int16 count)
{
    while (count > 0)
    {
        LED_binary(ledmask);
        TEST_sleep(100);
        LED_binary(0);
        TEST_sleep(150);
        count--;
    }
}

/*F***************************************************************************
* NAME:  void LED_error(Int16 ledmask)  
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
void LED_error(Int16 ledmask)
{
    while(1)
        LED_blink(ledmask, 1);
}
/*-----------------------------END OF LED FUNCTIONS-----------------------------------------------*/

/*-----------------------------MEMORY FUNCTIONS---------------------------------------------------*/
/*F***************************************************************************
* NAME:  MEM_fill(Uint32 start, Uint32 len, Uint32 val) 
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 MEM_fill(Uint32 start, Uint32 len, Uint32 val)
{
    Uint32 i, end;

    /* Calculate end of range */
    end = start + len;

    /* Fill a range with a value */
    for (i = start; i < end; i+=sizeof(Uint32))
    {
        *((Uint32 *)i) = val;
    }

    /* Verify the data */
    for (i = start; i < end; i+=sizeof(Uint32))
    {
        if (*((Uint32 *)i) != val)
            return 1;
    }

    return 0;
}
/*F***************************************************************************
* NAME:  MEM_addr(Uint32 start, Uint32 len)  
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 MEM_addr(Uint32 start, Uint32 len)
{
    Uint32 i, end;

    /* Calculate end of range */
    end = start + len;

    /* Fill the range with its address */
    for (i = start; i < end; i+=sizeof(Uint32))
    {
        *((Uint32 *)i) = i;
    }

    /* Verify the data */
    for (i = start; i < end; i+=sizeof(Uint32))
        if (*((Uint32 *)i) != i)
            return 1;

    return 0;
}
/*F***************************************************************************
* NAME: MEM_addrInv(Uint32 start, Uint32 len)  
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 MEM_addrInv(Uint32 start, Uint32 len)
{
    Uint32 i, end;

    /* Calculate end of range */
    end = start + len;

    /* Fill the range with its address */
    for (i = start; i < end; i+=sizeof(Uint32))
    {
        *((Uint32 *)i) = ~i;
    }

    /* Verify the data */
    for (i = start; i < end; i+=sizeof(Uint32))
        if (*((Uint32 *)i) != (~i))
            return 1;

    return 0;
}

/*F***************************************************************************
* NAME:  MEM_test(Uint32 start, Uint32 len, Int16 patterntype)  
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 MEM_test(Uint32 start, Uint32 len, Int16 patterntype)
{
    Int16 status = 0;

    if (!patterntype)
    {
        /* Run the fill tests */
        status |= MEM_fill(start, len, 0x00000000);
        status |= MEM_fill(start, len, 0x55555555);
        status |= MEM_fill(start, len, 0xAAAAAAAA);
        status |= MEM_fill(start, len, 0xFFFFFFFF);
    } else
    {
        /* Run the address tests */
        status |= MEM_addr(start, len);
        status |= MEM_addrInv(start, len);
    }

    return status;
}
/*F***************************************************************************
* NAME:  MEM_walking(Uint32 add)
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 MEM_walking(Uint32 add)
{
    Int16 i;
    Uint32 mask, *pdata;

    pdata = (Uint32 *)add;

    /* Walking ones and zeros */
    mask = 1;
    for (i = 0; i < 32; i++)
    {
        /* Test one in bit position i */
        *pdata = mask;
        if (*pdata != mask)
            return 1;

        /* Test zero in bit position i */
        *pdata = ~mask;
        if (*pdata != (~mask))
            return 1;

        mask = mask << 1;
    }

    return 0;
}
/*---------------------------END OF MEMORY FUNCTIONS------------------------------------------*/

/*---------------------------FLASH FUNCTIONS--------------------------------------------------*/
/*F***************************************************************************
* NAME:  TEST_flashID()
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 TEST_flashID()
{
    Uint16 MfgId,DevId;
    Int16 i;

    /* Reset Flash */
    *((Uint16 *)DSK5509_FLASH_BASE) = 0xf0;

    /* Read Manufacturer ID */
    *((Uint16 *)DSK5509_FLASH_CTL555) = 0xaa;
    *((Uint16 *)DSK5509_FLASH_CTL2AA) = 0x55;
    *((Uint16 *)DSK5509_FLASH_CTL555) = 0x90;

    /* Insert small delay for device to respond */
    for (i = 0; i < 10; i++);

    /* Read IDs */
    MfgId = *((Uint16 *)DSK5509_FLASH_BASE);
    DevId = *((Uint16 *)DSK5509_FLASH_BASE + 1);

    /* Reset Flash */
    *((Uint16 *)DSK5509_FLASH_BASE) = 0xf0;

    /* Check codes */
    if(    ((MfgId == 0x0001) && (DevId == 0x22b9)) // Amd
	    || ((MfgId == 0x0020) && (DevId == 0x00EE))){ // ST
		return(0); // Pass
	} else {
        return(1); // Fail
	}
}
/*---------------------------END OF FLASH FUNCTIONS-------------------------------------------*/

/*---------------------------DMA FUNCTIONS----------------------------------------------------*/
/*F***************************************************************************
* NAME:  TEST_dma()
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 TEST_dma()
{
    Int16 i;
    DMA_Handle hDma0;
    DMA_Config dmaCfg0 = {
        0x0205, /* Source Destination Register (CSDP) */
        0x5060, /* Control Register (CCR) */
        0x0008, /* Interrupt Control Register (CICR) */
        0,      /* Lower Source Address (CSSA_L) - Symbolic(Byte Address) */
        NULL,   /* Upper Source Address (CSSA_U) - Symbolic(Byte Address) */
        0,      /* Lower Destination Address (CDSA_L) - Symbolic(Byte Address) */
        NULL,   /* Upper Destination Address (CDSA_U) - Symbolic(Byte Address) */
        0x0010, /* Element Number (CEN) */
        0x0001, /* Frame Number (CFN) */
        0x0000, /* Frame Index (CFI) */
        0x0000  /* Element Index (CEI) */
    };

    /* Set src and dst addresses (in bytes instead of 16-bit words) */
    dmaCfg0.dmacssal = (DMA_AdrPtr)(((Uint32)(&src) << 1) & 0xFFFF);
    dmaCfg0.dmacssau = (Uint16)((Uint32)(&src) >> 15);
    dmaCfg0.dmacdsal = (DMA_AdrPtr)(((Uint32)(&dst) << 1) & 0xFFFF);
    dmaCfg0.dmacdsau = (Uint16)((Uint32)(&dst) >> 15);

    /* Set src values and clear destination */
    for (i = 0; i < N; i++) {
        src[i] = i;
        dst[i] = 0;
    }

    /* Open DMA channel */
    hDma0 = DMA_open(DMA_CHA0, DMA_OPEN_RESET);

    /* Configure the DMA */
    DMA_config(hDma0, &dmaCfg0);

    /* Call DMA_start to begin the data transfer */
    DMA_start(hDma0);

    /* Read the status register to clear it */
    i = DMA_RGET(DMACSR0);

    /* Poll DMA status too see if its done */
    while (!DMA_FGETH(hDma0, DMACSR, FRAME))
    {
        ;
    }

    /* We are done, so close DMA channel */
    DMA_close(hDma0);

    /* Check data */
    for (i = 0; i < N; i++)
        if (dst[i] != src[i])
            return 1;

    /* Test passed */
    return 0;
}
/*---------------------------END DMA FUNCTIONS------------------------------------------------*/

/*---------------------------TIMER FUNCTIONS--------------------------------------------------*/
/*F***************************************************************************
* NAME:  TEST_timer()
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 TEST_timer()
{
    /* Wait for 100 timer interrupts */
    TEST_sleep(100);
    
    return 0;
}
/*---------------------------END TIMER FUNCTIONS----------------------------------------------*/

/*---------------------------McBSP FUNCTIONS--------------------------------------------------*/
/*F***************************************************************************
* NAME:  TEST_mcbsp(Int16 devid, Int16 delayed)
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 TEST_mcbsp(Int16 devid, Int16 delayed)
{
    Int16 i;
    Uint16 receivedata;
    MCBSP_Handle hMcbsp;

    /* Initialize source data, zero dest */
    for (i = 0; i < N; i++) {
        src[i] = (i << 8) | i + 1;
        dst[i] = 0;
    }

    /* Open the McBSP */
    hMcbsp = MCBSP_open(devid, MCBSP_OPEN_RESET);

    /* Configure the McBSP for loopback mode */
    MCBSP_config(hMcbsp, &mcbspCfg_loopback);

    /* Start the McBSP */
    MCBSP_start(hMcbsp,
        MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC |
        MCBSP_RCV_START | MCBSP_XMIT_START, 0x200);

    /* Data transfer loop */
    for (i = 0; i < (N + delayed); i++) {
        /* Wait for XRDY signal before writing data to DXR */
        while (!MCBSP_xrdy(hMcbsp));

        /* Write 16 bit data value to DXR */
        MCBSP_write16(hMcbsp,src[i]);
        DSK5509_waitusec(1);

        /* Wait for RRDY signal to read data from DRR */
        while (!MCBSP_rrdy(hMcbsp));

        /* Read 16 bit value from DRR */
        receivedata = MCBSP_read16(hMcbsp);
        if (i >= delayed)
            dst[i - delayed] = receivedata;
    }

    /* Close the McBSP */
    MCBSP_close(hMcbsp);

    /* Check data to make sure transfer was successful */
    for (i = 0; i < N; i++)
        if (dst[i] != src[i])
            return 1;

    /* Test passed */
    return 0;
}
/*F***************************************************************************
* NAME:  TEST_mcbsp0()
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 TEST_mcbsp0()
{
    /* Do an internal loopback test on McBSP0 */
    return TEST_mcbsp(MCBSP_PORT0, 1);
}
/*F***************************************************************************
* NAME:  TEST_mcbsp1()
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
Int16 TEST_mcbsp1()
{
    /* Do an internal loopback test on McBSP1 */
    return TEST_mcbsp(MCBSP_PORT1, 1);
}
/*---------------------------END McBSP FUNCTIONS----------------------------------------------*/

/*---------------------------DIAGNOSTIC UTILITY FUNCTIONS-------------------------------------*/

/*---------------------OVERALL DIAGNOSTIC TESTS FUNCTIONS-----------------------------*/
/*F***************************************************************************
* NAME:  TEST_intMemVersion()  
*
* DESCRIPTION:Gets the board version and CPLD version for the target.
*
* NOTES:CALLED BY DSP DIAGNOSTICS IN THE DIAGNOSTIC UTILITY
*   
*F***************************************************************************/
Int16 TEST_intMemVersion()
{
    Int16 status = 0;

    /* Store CPLD version */
    databuf[2] = (DSK5509_rget(DSK5509_VERSION) >> 4) & 0xf;
    
    /* Store board version */
    databuf[3] = DSK5509_rget(DSK5509_VERSION) & 0x7;
    
    return status;
}

/*F***************************************************************************
* NAME:  TEST_extMem()  
*
* DESCRIPTION:Test SDRAM by filling with both pattern and address values.
*
* NOTES:CALLED BY EXTERNAL MEMORY IN THE DIAGNOSTIC UTILITY
*   
*F***************************************************************************/
Int16 TEST_extMem()
{
    Int16 status = 0;

    /* Check external memory (byte 0x40000 to byte 0x400000) */
    status |= MEM_test(0x20000, 0x1E0000, 0);
    status |= MEM_test(0x20000, 0x1E0000, 1);
    status |= MEM_walking(0x20000);

    return status;
}
/*F***************************************************************************
* NAME:  TEST_flash()  
*
* DESCRIPTION:
*
* NOTES:CALLED BY FLASH DIAGNOSTICS IN THE DIAGNOSTIC UTILITY
*   
*F***************************************************************************/
Int16 TEST_flash()
{
    Uint16 i, j, k;
    Uint32 startaddr, addr;
    
    /* Check Flash IDs */
    if (TEST_flashID())
        return 1;
        
    /* Erase all of the Flash but first page */
    DSK5509_FLASH_erase(DSK5509_FLASH_BASE + DSK5509_FLASH_PAGESIZE,
        DSK5509_FLASH_PAGESIZE * 7);

    /* Program the Flash page by page, 256 words at a time */
    addr = DSK5509_FLASH_BASE + DSK5509_FLASH_PAGESIZE;
    for (i = 1; i < 8; i++)
    {
        for (j = 0; j < 128; j++)
        {
            startaddr = addr;
            for (k = 0; k < 256; k++)
            {
                buffer[k] = addr + i;
                addr++;
            }
            DSK5509_FLASH_write((Uint32)buffer, startaddr, 256);
        }
    }

    /* Verify the Flash page by page, 256 bytes at a time */
    addr = DSK5509_FLASH_BASE + DSK5509_FLASH_PAGESIZE;
    for (i = 1; i < 8; i++)
    {
        for (j = 0; j < 128; j++)
        {
            startaddr = addr;
            DSK5509_FLASH_read(startaddr, (Uint32)buffer, 256);
            for (k = 0; k < 256; k++)
            {
                if (buffer[k] != ((addr + i) & 0xffff))
                    return 2;
                addr++;
            }
        }
    }

    return 0;
}
/*F***************************************************************************
* NAME:  TEST_codec()  
*
* DESCRIPTION:
*
* NOTES:CALLED BY CODEC DIAGNOSTICS IN THE DIAGNOSTIC UTILITY
*   
*F***************************************************************************/
Int16 TEST_codec()
{
    DSK5509_AIC23_CodecHandle hCodec;
    Int16 i, j;

    /* Start the codec */
    hCodec = DSK5509_AIC23_openCodec(0, &config);

    /* Generate a 1KHz sine wave for 1 second */
    for (i = 0; i < 1000; i++)
    {
        for (j = 0; j < SINE_TABLE_SIZE; j++)
        {
            while (!DSK5509_AIC23_write16(hCodec, sinetable[j]));
            while (!DSK5509_AIC23_write16(hCodec, sinetable[j]));
        }
    }

    /* Close codec */
    DSK5509_AIC23_closeCodec(hCodec);

    return 0;
}
/*F***************************************************************************
* NAME:  TEST_userIO()  
*
* DESCRIPTION:
*
* NOTES:CALLED BY LED AND DIP SWITCH DIAGNOSTICS IN THE DIAGNOSTIC UTILITY
*   
*F***************************************************************************/
Int16 TEST_userIO()
{
    int i, j;
    
    for (j = 0; j < 1; j++)
    {
        for (i = 0; i < 4; i++)
        {
            if (DSK5509_DIP_get(i) == 1)
                DSK5509_LED_on(i);
            else
                DSK5509_LED_off(i);
        }
        TEST_sleep(10);        
    }
    
    return 0;
}
/*---------------------END OVERALL DIAGNOSTIC TESTS FUNCTIONS-------------------------*/

/*---------------------ADVANCED DIAGNOSTIC TESTS FUNCTIONS-----------------------------*/
/*F***************************************************************************
* NAME:  TEST_memPat()  
*
* DESCRIPTION:Test SDRAM by filling with pattern values.
*
* NOTES:CALLED WHEN TESTING MEMORY IN THE ADVANCED TAB
*   
*F***************************************************************************/
Int16 TEST_memPat()
{
    Int16 status = 0;
    
    /* Test external memory (SDRAM) */
    status |= MEM_test(0x28000, 0x1D8000, 0);
        
    return status;
}
/*F***************************************************************************
* NAME:  TEST_memAddr()  
*
* DESCRIPTION:Test SDRAM by filling with address values.
*
* NOTES:CALLED WHEN TESTING MEMORY IN THE ADVANCED TAB 
*   
*F***************************************************************************/
Int16 TEST_memAddr()
{
    Int16 status = 0;
      
    /* Test external memory (SDRAM) */
    status |= MEM_test(0x28000, 0x1D8000, 1);

    return status;
}
/*F***************************************************************************
* NAME:  TEST_dsp()  
*
* DESCRIPTION:Tests Timer,DMA,McBSP0 & McBSP1
*
* NOTES:CALLED WHEN TESTING DSP IN THE ADVANCED TAB 
*   
*F***************************************************************************/
Int16 TEST_dsp()
{
    Int16 status = 0;
    
    /* Call sub-tests */
    if (TEST_dma())
        status |= 0x01;
    
    if (TEST_timer())
        status |= 0x02;
  
    if (TEST_mcbsp0())
        status |= 0x04;
    
    if (TEST_mcbsp1())
        status |= 0x08;

    return status;
}
/*F***************************************************************************
* NAME:  TEST_readSwitch()  
*
* DESCRIPTION:
*
* NOTES:CALLED WHEN TESTING LED/SWT IN THE ADVANCED TAB 
*   
*F***************************************************************************/
Int16 TEST_readSwitch()
{
    Int16 i, n;
    
    n = 0;

    for (i = 3; i >= 0; i--)
        n = (n << 1) | DSK5509_DIP_get(i);

    LED_binary(n);        
 
    databuf[2] = n;
    
    return 0;
}
/*F***************************************************************************
* NAME:  TEST_codecLoopBack()  
*
* DESCRIPTION:
*
* NOTES:CALLED WHEN TESTING CODEC IN THE ADVANCED TAB 
*   
*F***************************************************************************/
Int16 TEST_codecLoopBack()
{
    DSK5509_AIC23_CodecHandle hCodec;
    Int16 i, j, data;
    Uint16 *pbuf;
        
    /* Start the codec */
    hCodec = DSK5509_AIC23_openCodec(0, &config);

    if (cmdbuf[3])
    {
        /* Mute the AIC23 */
        DSK5509_AIC23_rset(hCodec, DSK5509_AIC23_DIGPATH, 0x08);
        
	    /* Re-configure the McBSP for loopback mode */
	    MCBSP_config(DSK5509_AIC23_DATAHANDLE, &mcbspCfg_loopback);
	    
        /* Clear any garbage from the codec data port */
        if (MCBSP_rrdy(DSK5509_AIC23_DATAHANDLE))
            MCBSP_read16(DSK5509_AIC23_DATAHANDLE);
            
	    /* Start the McBSP */
	    MCBSP_start(DSK5509_AIC23_DATAHANDLE, 
	        MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC |
	        MCBSP_RCV_START | MCBSP_XMIT_START, 0x200);

        /* Prepare to collect data */
	    pbuf = databuf + 4; 
	                    
	    /* Data transfer loop */
	    for (i = 0; i < SINE_TABLE_SIZE; i++)
	    {
            for (j = 0; j < 2; j++)
	        {
		        /* Wait for XRDY signal before writing data to DXR */
		        while (!MCBSP_xrdy(DSK5509_AIC23_DATAHANDLE));  

                /* Write the data */
      	        MCBSP_write(DSK5509_AIC23_DATAHANDLE, sinetable[(i << j) % SINE_TABLE_SIZE]);

		        /* Wait for RRDY signal to read data from DRR */
		        while (!MCBSP_rrdy(DSK5509_AIC23_DATAHANDLE));
		
		        /* Read 16 bit value from DRR */
		        *pbuf++ = MCBSP_read16(DSK5509_AIC23_DATAHANDLE);
	        }       
	    }
    } else {	
	    /* Set volume */
	    DSK5509_AIC23_outGain(hCodec, cmdbuf[1] & 0x7f);
	
	    /* Set mute */
	    if (cmdbuf[2])
	    {
	        DSK5509_AIC23_mute(hCodec, TRUE);
	    } else
	    {
	        DSK5509_AIC23_mute(hCodec, FALSE);
	    }
	
	    /* Run for a second */
	    for (i = 0; i < 1000; i++)
	    {
	        pbuf = databuf + 2;    
	        for (j = 0; j < SINE_TABLE_SIZE; j++)
	        {
	            while (!DSK5509_AIC23_write16(hCodec, sinetable[j]));
	            while (!DSK5509_AIC23_read16(hCodec, &data));
	            *pbuf++ = data;
	            while (!DSK5509_AIC23_write16(hCodec, sinetable[(j << 1) % SINE_TABLE_SIZE]));
	            while (!DSK5509_AIC23_read16(hCodec, &data));
	            *pbuf++ = data;
	        }        
	    }
    }

    /* Close codec */
    DSK5509_AIC23_closeCodec(hCodec);
    
    return 0;
}
/*--------------------- END ADVANCED DIAGNOSTIC TESTS FUNCTIONS--------------------------*/

/*------------------------END OF DIAGNOSTIC UTILITY FUNCTIONS---------------------------------*/

/*F***************************************************************************
* NAME:  TEST_execute()  
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
void TEST_execute(Int16 (*funchandle)(), Int16 ledmask, Int16 insertdelay)
{
    Int16 status;

    /* Display test ID */
    LED_binary(ledmask);

    /* Call test function */
    status = funchandle();

    /* Pause so LEDs can be read */
    if (insertdelay)
        TEST_sleep(100);

    /* Check for test fail */
    if (status)
        LED_error(ledmask);
}
/*F***************************************************************************
* NAME:  TEST_executeDiag()  
*
* DESCRIPTION:
*
* NOTES:
*   
*F***************************************************************************/
void TEST_executeDiag(Int16 (*funchandle)(), Int16 ledmask, Int16 insertdelay)
{
    Int16 status;

    /* Call test function */
    status = funchandle();

    databuf[0] = 0x1234;
    databuf[1] = status;
}

/*------------------------------START OF MAIN FUNCTION--------------------------------*/
main()
{
    /* Call BSL init */
    DSK5509_init();

    /* Initialize DIP switch and LEDs */
    DSK5509_LED_init();
    DSK5509_DIP_init();
    
#if defined( BUILD_DSK_DIAGS )

    /* Set up host communication buffers */
    cmdbuf = (Uint16 *)0x200;
    databuf = (Uint16 *)0x300;

#if(0)
    /* Iniitalize the command buffer for debug purposes */
    cmdbuf[0] = 3;
    cmdbuf[1] = 0x79;
    cmdbuf[2] = 0;
    cmdbuf[3] = 0;
#endif
  
    /* Execute command for host */
    switch(*cmdbuf)
    {
        case 0:  /* Internal memory */
            TEST_executeDiag(TEST_intMemVersion, 0, 0);
            break;
            
        case 1:  /* External memory (typical) */
            TEST_executeDiag(TEST_extMem, 0, 0);
            break;

        case 2:  /* External memory (special); */
            TEST_executeDiag(TEST_flashID, 0, 0);
            break;
            
        case 3:  /* Codec test */
            TEST_executeDiag(TEST_codec, 0, 0);        
            break;
            
        case 4:  /* LED and timer test */
            TEST_executeDiag(TEST_timer, 0, 0);
            break;
            
        case 5:  /* DIP switch test */
            TEST_executeDiag(TEST_userIO, 0, 0);
            break;

        case 6:  /* Test codec external loopback */
            TEST_executeDiag(TEST_codecLoopBack, 0, 0);
            break;

        case 7:   /* Test memory (fill pattern) */
            TEST_executeDiag(TEST_memPat, 0, 0);
            break;

        case 8:  /* Test DSP */
            TEST_executeDiag(TEST_dsp, 0, 0);
            break;

        case 9:  /* DIP switch read */
            TEST_executeDiag(TEST_readSwitch, 0, 0);
            break;
                              
        case 10:  /* Test memory (address pattern) */
            TEST_executeDiag(TEST_memAddr, 0, 0);
            break;

        case 11:  /* External Flash */
            TEST_executeDiag(TEST_flash, 0, 0);
            break;
            
        default:
            break;
    }
#endif


#if defined(_DEBUG)
    TEST_execute(TEST_intMemVersion, 1, 0);
    TEST_execute(TEST_extMem,        2, 0);
    TEST_execute(TEST_flash,         3, 0);
    TEST_execute(TEST_codec,         4, 0);
    TEST_execute(TEST_userIO,        5, 0);        
    TEST_execute(TEST_memPat,        6, 0);    
    TEST_execute(TEST_memAddr,       7, 0);
    TEST_execute(TEST_dsp,           8, 0);
    TEST_execute(TEST_readSwitch,    9, 0);
    TEST_execute(TEST_codecLoopBack, 10, 0); 
    
        /* All tests complete, board passes */
    LED_blink(0xf, 3);

    /* Leave all LEDs on */
    LED_binary(0xf);
#endif   
        /* Disable interrupts */
    IRQ_globalDisable();

    asm(" estop_1()");
    
    while(1);   
        
}
/*------------------------------END OF MAIN FUNCTION--------------------------------*/

