/***********************************************************/
/* Program: edma_sines.c                                   */
/***********************************************************/

/*************************************************************/
/* Program: edma_sines.c                                     */
/*                                                           */
/* This program generates a 1 kHz sine wave on the left      */
/* channel and a 2 kHz sine wave on the right channel by     */
/* repetitively sending words stored in the 512-word array,  */
/* table[], to the McBSP1 DXR using the EDMA. At the end of  */
/* each 512-word array transfer, the edma is set to link     */
/* back to the beginning of the table[] array. This is like  */
/* the autoinitialization for the TMS320C6701. Transfers are */
/* synchronized to the XRDY transition from 0 to 1. The      */
/* codec sampling frequency is set to 16 kHz. Left and right */
/* samples are packed into a single 32-bit word in table[].  */
/* The left sample is in the upper 16 bits and the right     */
/* sample in the lower 16 bits. McBSP1 is configured to use  */
/* a single phase, a frame length of 1 word, and a 32-bit    */
/* word. The main routine sits in an infinite while(1) loop  */
/* during the EDMA transfers.                                */
/*                                                           */
/* The C6713 EDMA has 16 channels. Each channel is tied to a */
/* specific event.  See Table 6-7 in the TMS320C6000         */
/* Peripehals Reference Guide for details. Channel 14 is     */
/* tied to XEVT1 (McBSP1 transmit event) and channel 15 is   */
/* tied to REVT1 (McBSP1 receive event) by default.          */
/*                                                           */
/* The codec can be set to the sampling rates shown in the   */
/* table below by using the function                         */
/*    DSK6713_AIC23_setFreq(handle, freq ID)                 */
/*                                                           */
/*      freq ID                Value  Frequency              */
/*   DSK6713_AIC23_FREQ_8KHZ,  0x06,    8000 Hz              */
/*   DSK6713_AIC23_FREQ_16KHZ, 0x2c,   16000 Hz              */
/*   DSK6713_AIC23_FREQ_24KHZ, 0x20,   24000 Hz              */
/*   DSK6713_AIC23_FREQ_32KHZ, 0x0c,   32000 Hz              */
/*   DSK6713_AIC23_FREQ_44KHZ, 0x11,   44100 Hz              */
/*   DSK6713_AIC23_FREQ_48KHZ, 0x00,   48000 Hz              */
/*   DSK6713_AIC23_FREQ_96KHZ, 0x0e,   96000 Hz              */
/*************************************************************/

/*************************************************************/
/*  SETTING THE PROJECT BUILD OPTIONS

     Right click on the project name in the Project Explorer window
   and then select "Build Options...". (Alternatively, you can first
   left click on the project name to highlight it. Then left click on
   "Project" and then "Build Options.") Expand the "C6000 Compiler"
   menu.

   1. Select "Basic Options" and fill in as follows:
      Configuration:             Debug [ Active ]
      Target processor version   6713
      Debugging model            Full symbolic debug
      Optimization level         leave blank for now
      Optimize for code size     leave blank for now

   2. Select "Command Files" and on the right after "Read options ..."
   click on the icon of the page with the green plus sign. In the
   "Add file path" window enter
      C:\c6713dsk\compiler.cmd
   and click on "OK". This file contains the include search path
   directives: 
       -I="C:\c6713dsk\dsk6713bsl32\include"
       -I="c:\Program Files\C6xCSL\include"
 
   3. Select "Directory Specifier" and change any of the paths to the
   ones you need.

   4. Optionally, select "Include Options."  You will not normally have
   to do this since the most often used search paths are set by step 2.
   Add any additional include #include search paths needed.

   5. Select "Predefined Symbols." In the "Pre-define NAME" box, click on
   the icon with the green plus sign and enter:
      CHIP_6713
   This is used by the Chip Support Library (CSL).

   6.  Expand the "C6000 Linker" menu and select "Basic Options." Accept
   the default entries or change them to your preferences.

   7.  Select "File Search Path" in the linker menu.  In the "Include
   library file or command ..." window, click on the page with a green
   plus sign icon and enter:
     C:\c6713dsk\dsk6713.cmd
   This linker command file contains the paths and names of the libraries
   needed for your ENEE 428 projects. It also defines the memory map
   and code sections.

   8.  Select "Runtime Environment" and make sure the "Initialization
   Model" is "Link using ROM autoinitialization model (-rom_model, -c)".
************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <dsk6713.h>
#include <dsk6713_aic23.h>
#include <csl_edma.h>
#include <DSKintr.h>

#include <math.h>  

/* NOTE:  The TI compiler gives warnings if math.h is moved up
          under stdlib.h  */

#define  sampling_rate 16000.
#define SZ_TABLE 512
#define f_left  1000.
#define f_right 2000.
#define scale 15000.
#define pi 3.141592653589

int table[512];

/* Codec configuration settings */
/* See dsk6713_aic23.h and the TLV320AIC23 Stereo Audio CODEC Data Manual */
/* for a detailed description of the bits in each of the 10 AIC23 control */
/* registers in the following configuration structure.                    */

DSK6713_AIC23_Config config = { \
    0x0017,  /* 0 DSK6713_AIC23_LEFTINVOL  Left line input channel volume */ \
    0x0017,  /* 1 DSK6713_AIC23_RIGHTINVOL Right line input channel volume */\
    0x00d8,  /* 2 DSK6713_AIC23_LEFTHPVOL  Left channel headphone volume */  \
    0x00d8,  /* 3 DSK6713_AIC23_RIGHTHPVOL Right channel headphone volume */ \
    0x0011,  /* 4 DSK6713_AIC23_ANAPATH    Analog audio path control */      \
    0x0000,  /* 5 DSK6713_AIC23_DIGPATH    Digital audio path control */     \
    0x0000,  /* 6 DSK6713_AIC23_POWERDOWN  Power down control */             \
    0x0043,  /* 7 DSK6713_AIC23_DIGIF      Digital audio interface format */ \
    0x0081,  /* 8 DSK6713_AIC23_SAMPLERATE Sample rate control (48 kHz) */   \
    0x0001   /* 9 DSK6713_AIC23_DIGACT     Digital interface activation */   \
};

EDMA_Handle hEdmaXmt;            // EDMA channel handles
EDMA_Handle hEdmaReloadXmt;

Int16 gXmtChan;                  // TCC code (see initEDMA()) 

/* Transmit side EDMA configuration */
EDMA_Config gEdmaConfigXmt = {  
    EDMA_FMKS(OPT, PRI, HIGH)          |  // Priority
    EDMA_FMKS(OPT, ESIZE, 32BIT)       |  // Element size
    EDMA_FMKS(OPT, 2DS, NO)            |  // 1 dimensional source
    EDMA_FMKS(OPT, SUM, INC)           |  // Src update mode
    EDMA_FMKS(OPT, 2DD, NO)            |  // 1 dimensional dest
    EDMA_FMKS(OPT, DUM, NONE)          |  // Dest update mode
    EDMA_FMKS(OPT, TCINT, NO)          |  // Cause EDMA interrupt?
    EDMA_FMKS(OPT, TCC, OF(0))         |  // Transfer complete code
    EDMA_FMKS(OPT, LINK, YES)          |  // Enable link parameters?
    EDMA_FMKS(OPT, FS, NO),               // Use frame sync?

    (Uint32) table,                       // Src address

    EDMA_FMK (CNT, FRMCNT, NULL)       |  // Frame count
    EDMA_FMK (CNT, ELECNT, SZ_TABLE),     // Element count
    
    EDMA_FMKS(DST, DST, OF(0)),           //Dest address

    EDMA_FMKS(IDX, FRMIDX, DEFAULT)    |  // Frame index value
    EDMA_FMKS(IDX, ELEIDX, DEFAULT),      // Element index value

    EDMA_FMK (RLD, ELERLD, NULL)       |  // Reload element
    EDMA_FMK (RLD, LINK, NULL)            // Reload link
};

/*  Function Prototypes */
void initEdma(void);
void create_table(void);

void main(void){
  DSK6713_AIC23_CodecHandle hCodec;

  /* Initialize the interrupt system */
  intr_reset(); /*Reset interrupt regs to defaults, set ISTP */

  /* dsk6713_init() must be called before other BSL functions */
  DSK6713_init(); /* In the BSL library */

  /* Start the codec. McBSP1 uses 32-bit words, 1 phase, 1 word frame */
  hCodec = DSK6713_AIC23_openCodec(0, &config);

  /* Change the sampling rate to 16 kHz */
  DSK6713_AIC23_setFreq(hCodec, DSK6713_AIC23_FREQ_16KHZ); 
  
  create_table(); /* You must write the function to generate sine table. */
                  /* Put it in the spot shown below. */

  initEdma();  // Initialize the EDMA controller (See below)
 
   while(1); /* infinite loop  */

} /* end of main() */


/*******************************************************/
/* Create a table where upper 16-bits are samples of   */
/* a sine wave with frequency f_left, and the lower 16 */
/* bits are samples of a sine wave with frequency      */
/* f_right.                                            */
/*******************************************************/

void create_table(void){
  Put your code to generate the sine table here.
}

/*
 *  initEdma() - Initialize the DMA controller.  Use linked transfers to 
 *               automatically restart at beginning of sine table.
 */
 
void initEdma(void)
{
 /* Configure transmit channel */

  // get hEdmaXmt handle and reset channel for McBSP1 writes
    hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET);
    
  // get handle for reload table
    hEdmaReloadXmt = EDMA_allocTable(-1);
 
  // Get the address of DXR for McBSP1   
    gEdmaConfigXmt.dst = MCBSP_getXmtAddr(DSK6713_AIC23_DATAHANDLE);
  
  // then configure the Xmt table        
    EDMA_config(hEdmaXmt, &gEdmaConfigXmt); 
    
  // Configure the Xmt reload table
    EDMA_config(hEdmaReloadXmt, &gEdmaConfigXmt);       

  // link back to table start    
    EDMA_link(hEdmaXmt,hEdmaReloadXmt);
    EDMA_link(hEdmaReloadXmt, hEdmaReloadXmt);

  // enable EDMA channel
    EDMA_enableChannel(hEdmaXmt); 
 
    /* Do a dummy write to generate the first McBSP transmit event */
    MCBSP_write(DSK6713_AIC23_DATAHANDLE, 0);
}
