/**********************************************************************
* FILENAME
*   codec_edma.c
*
* DESCRIPTION
*   EDMA version of simple codec test
*
* Rev 2.1	03 Jun	2000	T.J.Dillon - removed SDRAM parameters
*
**********************************************************************/
#include <stdio.h>
#include <csl.h>
#include <csl_emif.h>
#include <csl_edma.h>
#include <csl_mcbsp.h>
#include <csl_irq.h>
#include <bsl.h>
#include <bsl_ad535.h>
#include "codec_edma.h"

#define  DATA_SIZE 2
#define  BLOCK_SIZE 80
#define  NUM_OF_BLOCKS 18
#define  DELAY 5

int pcm_out,pcm_in,edma_index;
int src,dst;
short *in_ptr,*out_ptr;
short in[NUM_OF_BLOCKS*BLOCK_SIZE], out[NUM_OF_BLOCKS*BLOCK_SIZE];

EDMA_Handle hEdma[4];
AD535_Handle hAD535;

EDMA_Config edmaXmitParam, edmaRcvParam;
AD535_Config myConfig = { AD535_LOOPBACK_DISABLE,
                          AD535_MICGAIN_OFF,
                          AD535_GAIN_0DB,
                          AD535_GAIN_0DB
                        };
void main()
{
 
  int i; 
  
  /* Initialize the chip support library, required */
  CSL_init();
  /* Initialize the board support library, required */
  BSL_init();

  /* DSP initialization */
  IRQ_globalDisable();

  IRQ_disable(IRQ_EVT_EDMAINT);        /* Disable and clear EDMA interrupt    */
  IRQ_clear(IRQ_EVT_EDMAINT);

/******************************************************************************\
 * CONFIGURE EMIF                                                             *
\******************************************************************************/  
  EMIF_configArgs(0x00003300,            /* EMIF global control register         */
               0xFFFFFF30,            /* CE0 - SDRAM                          */
               0xFFFFFF03,            /* CE1 - 8-bit asynch                   */
               0xFFFFFF23,            /* CE2 - 32-bit asynch on daughterboard */
               0xFFFFFF23,            /* CE3 - 32-bit asynch on daughterboard */
               0x07117000,            /* SDRAM control register (100 MHz)     */
               0x0000061A,            /* SDRAM Timing register                */
               0x00054519             /* SDRAM Extension register             */
              );

  for (i=0; i<NUM_OF_BLOCKS*BLOCK_SIZE; i++)     /* clear all buffers  */
  {
    in[i]=0;
    out[i]=0xaa;
  }

/******************************************************************************\
 * OPEN and CONFIGURE local codec                                             *
\******************************************************************************/  
  hAD535 = AD535_open(AD535_localId);
  AD535_reset(hAD535);
  AD535_config(hAD535, &myConfig);

/******************************************************************************\
 * Configure EDMA and interrupts                                              *
\******************************************************************************/  
  /* interrupt configuration */
  IRQ_enable(IRQ_EVT_EDMAINT);           /* enable interrupt 8 (EDMA)         */
  IRQ_globalRestore(1);                  /* enable global interrupts          */
  edma_init(); 

  while (1) {}
}


void edma_init()
{ 
  EDMA_RSET(CIPR,0xFFFF);         /* clear all pending EDMA interrupts         */
  EDMA_RSET(CIER,0x0100);         /* enable channel interrupt 8 (EDMA)         */

  pcm_in = (int)&in;
  pcm_out = (int)&out;
  in_ptr = (short *)pcm_in;
  out_ptr = (short *)( pcm_out + DELAY*BLOCK_SIZE*DATA_SIZE);

  edma_index = 1;

  /* 0 - open and enable EDMA channel for mcbsp0 transmitter          */
  /* 1 - open and enable EDMA channel for mcbsp0 receiver             */
  /* 2 - allocate EDMA reload parameter table for mcbsp0 transmitter  */
  /* 3 - allocate EDMA reload parameter table for mcbsp0 reciever     */
  hEdma[0] = EDMA_open(EDMA_CHA_XEVT0, EDMA_OPEN_ENABLE);
  hEdma[1] = EDMA_open(EDMA_CHA_REVT0, EDMA_OPEN_ENABLE);
  hEdma[2] = EDMA_allocTable(0);
  hEdma[3] = EDMA_allocTable(1);


  /* set up config structures */
  /* OPT - options                         */
    edmaXmitParam.opt = EDMA_OPT_RMK( 
                          EDMA_OPT_PRI_LOW,
                          EDMA_OPT_ESIZE_16BIT,
                          EDMA_OPT_2DS_NO,
                          EDMA_OPT_SUM_INC,
                          EDMA_OPT_2DD_NO,
                          EDMA_OPT_DUM_NONE,
                          EDMA_OPT_TCINT_NO,
                          EDMA_OPT_TCC_OF(0),
                          EDMA_OPT_LINK_YES,
                          EDMA_OPT_FS_NO
                        );
    edmaXmitParam.src = pcm_out;     /* SRC - source address                  */
    edmaXmitParam.cnt = BLOCK_SIZE;  /* CNT - transfer count                  */
    /* address of the specified mcbsp channel transmitter register            *\
    \* DST - destination address                                              */
    edmaXmitParam.dst = MCBSP_getXmtAddr(hAD535->Obj.hMcbsp);
    edmaXmitParam.idx = 0;           /* IDX - index                           */
    /* address of EDMA reload param table for mcbsp0 transmitter              *\
    \* RLD - element count and link address                                   */
    edmaXmitParam.rld = EDMA_getTableAddress(hEdma[2]);
  
    edmaRcvParam.opt = EDMA_OPT_RMK( /* OPT - options                                                   */
                          EDMA_OPT_PRI_LOW,
                          EDMA_OPT_ESIZE_16BIT,
                          EDMA_OPT_2DS_NO,
                          EDMA_OPT_SUM_NONE,
                          EDMA_OPT_2DD_NO,
                          EDMA_OPT_DUM_INC,
                          EDMA_OPT_TCINT_YES,
                          EDMA_OPT_TCC_OF(8),
                          EDMA_OPT_LINK_YES,
                          EDMA_OPT_FS_NO
                        );
    /* address of the specified mcbsp channel receiver register               *\
    \* SRC - source address                                                   */
    edmaRcvParam.src = MCBSP_getRcvAddr(hAD535->Obj.hMcbsp);
    edmaRcvParam.cnt = BLOCK_SIZE;  /* CNT - transfer count                   */
    edmaRcvParam.dst = pcm_in;      /* DST - destination address              */
    edmaRcvParam.idx = 0;           /* IDX - index                            */
    /* address of EDMA reload param table for mcbsp0 transmitter              *\
    \* RLD - element count and link address                                   */
    edmaRcvParam.rld = EDMA_getTableAddress(hEdma[3]);
  
  /* configure EDMA parameter tables and EDMA reload parameter tables */
  EDMA_config(hEdma[0], &edmaXmitParam);
  EDMA_config(hEdma[1], &edmaRcvParam);

  src = pcm_out+BLOCK_SIZE*DATA_SIZE;
  dst = pcm_in+BLOCK_SIZE*DATA_SIZE;
  edmaXmitParam.src = src;
  edmaRcvParam.dst  = dst;

  EDMA_config(hEdma[2], &edmaXmitParam);
  EDMA_config(hEdma[3], &edmaRcvParam);
  
  EDMA_enableChannel(hEdma[0]);
  EDMA_enableChannel(hEdma[1]);
  /* NOTE: do not close or free the EDMA channels or parameter tables, */
  /* otherwise the configuration will be lost.                          */
}

interrupt void edma_isr(){
  int i,temp;
  if ( edma_index  == NUM_OF_BLOCKS -1) {
    edma_index =0;
    dst = pcm_in;	 
    src =  pcm_out;
  }
  else {
    edma_index++;		
    src += BLOCK_SIZE*DATA_SIZE;
    dst += BLOCK_SIZE*DATA_SIZE;
  }

  EDMA_CIPR |= 0x0100;         /* clear pending EDMA interrupt 8            */
  edmaXmitParam.src = src;
  edmaRcvParam.dst  = dst;

  /* reconfigure EDMA reload link parameter table */
  EDMA_config(hEdma[2], &edmaXmitParam);
  EDMA_config(hEdma[3], &edmaRcvParam);

  temp = (int)in_ptr - pcm_in - NUM_OF_BLOCKS*BLOCK_SIZE*DATA_SIZE;
  if (temp >= 0) {
    in_ptr = (short *)pcm_in;  
  }
      
  temp = (int)out_ptr - pcm_out - NUM_OF_BLOCKS*BLOCK_SIZE*DATA_SIZE;
  if (temp >= 0){
    out_ptr = (short *)pcm_out;  
  }

  for (i=0;i<BLOCK_SIZE;i++) *out_ptr++ = *in_ptr++ & 0xfffe;
}