This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Digital Signal Processing and Applications with OMAPL138 Experimenter : issues porting to TI-RTOS

Hello, Following is an excerpt of the code being used successfully on the LCDK. The code is based on the c6748 experimenter BSL and works well when modified to run on the LCDK6748.

I have tried to port this code to run using the TI-RTOS. My question is about the interrupts and timer. In the above code the INTMUX1 register (highlighted) is used to assign the EDMA Receive/Transmit event(event number 8) to interrupt number 4 and the ICR, CSR and other registers are configured manually (highlighted). If I configure the hardware interrupt statically using the .cfg file, which registers will it affect and which registers will have to be deleted so that their value is not set twice.

Also, would the timer initialization code (highlighted) need to be modified to be compatible with the SYS/BIOS Timer

Hope this is clear enough.

Regards,

Anshul

// L138_LCDK_aic3106_init.c
//

#define DUAL_RATE
#include "L138_LCDK_aic3106_init.h"
#include "evmomapl138_spi.h"


int16_t *pingIN, *pingOUT, *pongIN, *pongOUT;

AIC31_data_type AIC31_data;

spi_config_t spiconf;

extern void vectors(void);


void EDMA3_PaRAM_setup() // sets up PaRAM and enables EDMA events
{
uint32_t *EDMA3_PaRAM_ptr;
// PaRAM sets (channels) 0 and 1, triggered by McASP0
// receive and transmit events respectively, are used
// with linked parameters set up in PaRAM sets (channels) 64, 65, 67, and 68
// the linked parameters differ only in the ping or pong buffers used

// set up PaRAM set 1 (MCASP0 XEVT)

EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04020);

*EDMA3_PaRAM_ptr++ = 0x00000000; // no EDMA3 interrupts on transfer complete
*EDMA3_PaRAM_ptr++ = (unsigned int)pingOUT; // source is one of two output buffers
*EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
 // BCNT = BUFCOUNT/2(arrays per frame), ACNT = 4(bytes per array) writing to a (32-bit) McASP0 serialiser
*EDMA3_PaRAM_ptr++ = 0x01D02000; // destination is DMA port of McASP0
*EDMA3_PaRAM_ptr++ = 0x00000004; // dest address is static, increment source address by ACNT bytes
*EDMA3_PaRAM_ptr++ = 0x00000800; // BCNT reload value is redundant - link to PaRAM set 64
*EDMA3_PaRAM_ptr++ = 0x00000000; // CCNTIDX
*EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT = 1(frame per block)

// set up PaRAM set 64

EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04800);

*EDMA3_PaRAM_ptr++ = 0x00000000; // same as PaRAM set 1
*EDMA3_PaRAM_ptr++ = (unsigned int)pongOUT; // apart from source buffer used
*EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
*EDMA3_PaRAM_ptr++ = 0x01D02000;
*EDMA3_PaRAM_ptr++ = 0x00000004;
*EDMA3_PaRAM_ptr++ = 0x00000820; // BCNT reload value is redundant - link to PaRAM set 65
*EDMA3_PaRAM_ptr++ = 0x00000000;
*EDMA3_PaRAM_ptr++ = 0x00000001;

// set up PaRAM set 65

EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04820);

*EDMA3_PaRAM_ptr++ = 0x00000000; // exactly the same as PaRAM set 1
*EDMA3_PaRAM_ptr++ = (unsigned int)pingOUT;
*EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
*EDMA3_PaRAM_ptr++ = 0x01D02000;
*EDMA3_PaRAM_ptr++ = 0x00000004;
*EDMA3_PaRAM_ptr++ = 0x00000800; // BCNT reload value is redundant - link to PaRAM set 64
*EDMA3_PaRAM_ptr++ = 0x00000000;
*EDMA3_PaRAM_ptr++ = 0x00000001;


// set up PaRAM set 0 (MCASP0 REVT)

EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04000);

*EDMA3_PaRAM_ptr++ = 0x00100000; // OPT interrupt on transfer complete with TCC = 0
*EDMA3_PaRAM_ptr++ = 0x01D02000; // SRC DMA port of McASP0
*EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
*EDMA3_PaRAM_ptr++ = (unsigned int)pingIN; // DST one of two output buffers
*EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX increment dest by 4 bytes, src is static
*EDMA3_PaRAM_ptr++ = 0x00000860; // BCNT reload value is redundant - link to PaRAM set 67
*EDMA3_PaRAM_ptr++ = 0x00000000; //
*EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT 1 frame per block

// set up parameter RAM set 67

EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04860);

*EDMA3_PaRAM_ptr++ = 0x00101000; // OPT similar to PaRAM set 1 but TCC = 1 and different buffer used
*EDMA3_PaRAM_ptr++ = 0x01D02000;    // SRC
*EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
*EDMA3_PaRAM_ptr++ = (unsigned int)pongIN; // DST - single address used for XBUFn, RBUFn if RBSEL = 0
*EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX
*EDMA3_PaRAM_ptr++ = 0x00000880; // BCNT reload value is redundant - link to PaRAM set 68
*EDMA3_PaRAM_ptr++ = 0x00000000; //
*EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT

// set up parameter RAM set 68

EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04880); // exactly the same as PaRAM set 1

*EDMA3_PaRAM_ptr++ = 0x00100000; // OPT
*EDMA3_PaRAM_ptr++ = 0x01D02000;    // SRC
*EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
*EDMA3_PaRAM_ptr++ = (unsigned int)pingIN; // DST - single address used for XBUFn, RBUFn if RBSEL = 0
*EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX
*EDMA3_PaRAM_ptr++ = 0x00000860; // BCNT reload value is redundant - link to PaRAM set 67
*EDMA3_PaRAM_ptr++ = 0x00000000; //
*EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT


  EDMA_3CC_IECRH  = 0xffffffff;   // IERH - Disable high interrupts
  EDMA_3CC_EECRH  = 0xffffffff;   // EERH - Disable high events
  EDMA_3CC_ICRH   = 0xffffffff;   // ICRH - Clear high interrupts
  EDMA_3CC_ECRH   = 0xffffffff;   // ICRH - Clear high events

  EDMA_3CC_IECR   = 0xffffffff;   // IER  - Disable low interrupts
  EDMA_3CC_EECR   = 0xffffffff;   // EER  - Disable low events
  EDMA_3CC_ICR    = 0xffffffff;   // ICR  - Clear low interrupts
  EDMA_3CC_ECR    = 0xffffffff;   // ICRH - Clear low events


EDMA_3CC_EESR = 0x00000003; // enable EDMA3 events 0 and 1, i.e. McASP REVT and XEVT
}

//configure and initialise MCASP0 for edma3-based i/o
void L138_init_mcasp_edma()
{

   // reset mcasp.
   MCASP->GBLCTL  = 0;

   // configure receive registers.
   MCASP->RMASK      = 0x0000FFFF;
      MCASP->RFMT       = 0x00018070;// was 0x000080F0
      MCASP->AFSRCTL    = 0x00000111;// was 0x00000000
      MCASP->ACLKRCTL   = 0x00000080;// was 0x00000000
      MCASP->AHCLKRCTL  = 0x00000000;// was 0x00000000
      MCASP->RTDM       = 0x00000003;// was 0x00000001
      MCASP->RINTCTL    = 0x00000000;
      MCASP->RCLKCHK    = 0x00FF0005;// was 0x00000000

      // configure transmit registers.
      MCASP->XMASK      = 0x0000FFFF;
      MCASP->XFMT       = 0x00018074;// was 0x000080F0
      MCASP->AFSXCTL    = 0x00000110;// was 0x00000000
      MCASP->ACLKXCTL   = 0x00000080;// was 0x00000000
      MCASP->AHCLKXCTL  = 0x00000000;// was 0x00000000
      MCASP->XTDM       = 0x00000003;// was 0x00000001
      MCASP->XINTCTL    = 0x00000000;
      MCASP->XCLKCHK    = 0x00FF0005;// was 0x00000000
      // config serializers (13 = xmit, 14 = rcv).
      MCASP->SRCTL13    = 0x000D;// was 0x000D
      MCASP->SRCTL14    = 0x000E;// was 0x000E

      // config pin function and direction.
      MCASP->PFUNC      = 0;
      MCASP->PDIR       = 0x00002000;

   //
   MCASP->DITCTL     = 0x00000000;
   MCASP->DLBCTL     = 0x00000000;
   MCASP->AMUTE      = 0x00000000;


   // enable the audio clocks, verifying each bit is properly set.
   SETBIT(MCASP->XGBLCTL, XHCLKRST);
   while (!CHKBIT(MCASP->XGBLCTL, XHCLKRST)) {}
   SETBIT(MCASP->RGBLCTL, RHCLKRST);
   while (!CHKBIT(MCASP->RGBLCTL, RHCLKRST)) {}


     EDMA3_PaRAM_setup();

   MCASP->XSTAT = 0x0000FFFF;        // Clear all
   MCASP->RSTAT = 0x0000FFFF;        // Clear all

// if DMA is being used, verify that the XDATA bit (5) in XSTAT
// is cleared to 0. (it should have been cleared y writing 1 to it)
   while ( ( MCASP->XSTAT & 0x00000020 ) != 0x00000000 );

   SETBIT(MCASP->XGBLCTL, XSRCLR);
   while (!CHKBIT(MCASP->XGBLCTL, XSRCLR)) {}
   SETBIT(MCASP->RGBLCTL, RSRCLR);
   while (!CHKBIT(MCASP->RGBLCTL, RSRCLR)) {}

   /* Write a 0, so that no underrun occurs after releasing the state machine */
   MCASP->XBUF13 = 0;
   MCASP->RBUF14 = 0;

   SETBIT(MCASP->XGBLCTL, XSMRST);
   while (!CHKBIT(MCASP->XGBLCTL, XSMRST)) {}
   SETBIT(MCASP->RGBLCTL, RSMRST);
   while (!CHKBIT(MCASP->RGBLCTL, RSMRST)) {}

   SETBIT(MCASP->XGBLCTL, XFRST);
   while (!CHKBIT(MCASP->XGBLCTL, XFRST)) {}
   SETBIT(MCASP->RGBLCTL, RFRST);
   while (!CHKBIT(MCASP->RGBLCTL, RFRST)) {}

   // wait for transmit ready and send a dummy byte.
   while(!CHKBIT(MCASP->SRCTL13, XRDY)) {}
   MCASP->XBUF13 = 0;
}


// initialise AIC3106 codec by writing to its control registers
// sampling frequency, ADC gain, and DAC attenuation are set according to parameters passed


void L138_init_aic3106_registers(int32_t fs, int16_t adc_gain, int16_t dac_atten, int8_t input_type)
{
// not every register is set here - some are left with default(reset) values
// each AIC3106 register is 8 bits wide

  AIC3106_writeRegister(  0, 0x00 );  // AIC3106_PAGESELECT is PAGE 0 REG 0
  AIC3106_writeRegister(  1, 0x80 );  // reset AIC3106 using REG 1

switch(fs) // set up sampling rate - default 8kHz
{
	case FS_8000_HZ:
	  AIC3106_writeRegister(  2, 0xAA );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_9600_HZ:
	  AIC3106_writeRegister(  2, 0x88 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_11025_HZ:
	  AIC3106_writeRegister(  2, 0x66 );
      AIC3106_writeRegister(  7, 0x8A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_12000_HZ:
	  AIC3106_writeRegister(  2, 0x66 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_16000_HZ:
	  AIC3106_writeRegister(  2, 0x44 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_19200_HZ:
	  AIC3106_writeRegister(  2, 0x33 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_22050_HZ:
	  AIC3106_writeRegister(  2, 0x22 );
      AIC3106_writeRegister(  7, 0x8A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_24000_HZ:
	  AIC3106_writeRegister(  2, 0x22 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_32000_HZ:
	  AIC3106_writeRegister(  2, 0x11 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_44100_HZ:
	  AIC3106_writeRegister(  2, 0x00 );
      AIC3106_writeRegister(  7, 0x8A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
	case FS_48000_HZ:
	  AIC3106_writeRegister(  2, 0x00 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
#if defined DUAL_RATE
	case FS_96000_HZ:
	  AIC3106_writeRegister(  2, 0x00 );
	  AIC3106_writeRegister(  7, 0x6A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
#endif
	default:
	  AIC3106_writeRegister(  2, 0x00 );
      AIC3106_writeRegister(  7, 0x0A );  // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
	  break;
}

  AIC3106_writeRegister(  3, 0x22 );  // disable PLL and set Q=4(relevant) and P=2(irrelevant)
                                      // fsref will be MCLK/(128*Q) = 48000
                                      // MCLK on eXperimenter is 24.576MHz from on-board Citizen oscillator
  AIC3106_writeRegister(  4, 0x20 );  // J=8 (irrelevant since PLL disabled)
  AIC3106_writeRegister(  5, 0x6E );  // D=7075 MS bits (irrelevant since PLL disabled)
  AIC3106_writeRegister(  6, 0x23 );  // D=7075 LS bits (irrelevant since PLL disabled)
  AIC3106_writeRegister(  8, 0xC0 );  // Audio Interface Control A BCLK=Slave(input), WCLK=Slave(input)
  AIC3106_writeRegister(  9, 0x00 );  // Audio Interface Control B DSP mode (1 slot), 32 bit slot width

  AIC3106_writeRegister( 12, 0x00 );  // Audio Interface Control C Data offset=0


  AIC3106_writeRegister( 10, 0x00 );  // Audio Interface Control C Data offset=0
// WARNING - this assumes that adc_gain is a sensible value
  AIC3106_writeRegister( 15, adc_gain );  // Left ADC Programmable Gain Amplifier Mute=OFF Gain=0dB
  AIC3106_writeRegister( 16, adc_gain );  // Right ADC Programmable Gain Amplifier Mute=OFF Gain=0dB

  if (input_type == LCDK_LINE_INPUT)
  {
    AIC3106_writeRegister( 19, 0x04 );  // power up ADCs
    AIC3106_writeRegister( 22, 0x04 );  // and connect LINE1L/R to ADC
  }
  else
  {
    AIC3106_writeRegister( 19, 0x7C );  // power up ADCs
    AIC3106_writeRegister( 22, 0x7C );  // and do not connect LINE1L/R to ADC
    AIC3106_writeRegister( 17, 0x0F );  // 17 MIC3L to L ADC (default 0xFF, NC) 0x00 0dB
    AIC3106_writeRegister( 18, 0xF0 );  // 18 MIC3R to R ADC (default 0xFF, NC) 0x00 0dB
    AIC3106_writeRegister( 25, 0x40 );  // 25 MICBIAS 0x40 2V, 0x00 OFF
  }

  AIC3106_writeRegister( 37, 0xE0 );  // DAC Power & Output Dvr LeftDAC=ON, RightDAC=ON, HPLCOM=SingleEnd]
// WARNING - this assumes that dac_atten is a sensible value
  AIC3106_writeRegister( 43, dac_atten );  // Left DAC Digital Volume Mute=OFF, Gain=0dB
  AIC3106_writeRegister( 44, dac_atten );  // Right DAC Digital Volume Mute=OFF, Gain=0dB
  AIC3106_writeRegister( 82, 0x80 );  // was 0x80 DAC_L1 to LEFT_LOP/M Volume Routed, Gain=0dB
  AIC3106_writeRegister( 86, 0x09 );  // LEFT_LOP/M Output Mute=OFF bit3 bit0 is REad only ?! must be set!
  AIC3106_writeRegister( 92, 0x80 );  // was 0x80 92 DAC_R1 to RIGHT_LOP/M Volume    <- [Routed]
  AIC3106_writeRegister( 93, 0x09 );  // 93           RIGHT_LOP/M Output    <- [Mute=OFF][Power=ON]
  AIC3106_writeRegister( 101, 0x01 ); // 101 GPIO Control Register B        <- [CODEC_CLKIN = CLKDIV_OUT]
  AIC3106_writeRegister( 102, 0 );
}

// initialisation routine called by example program for edma3-based i/o

void L138_initialise_edma(int32_t fs, int16_t adc_gain, int16_t dac_atten, int8_t input_type)
{

  poll = 0;     // used in input_sample() and output_sample() functions


  // allocate memory for ping pong buffers
  pingOUT = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));
  pongOUT = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));
  pingIN = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));
  pongIN = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));

  USTIMER_init();

  EVMOMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_MCASP0, PSC_ENABLE);
  EVMOMAPL138_pinmuxConfig(PINMUX_MCASP_REG_0, PINMUX_MCASP_MASK_0, PINMUX_MCASP_VAL_0);
  EVMOMAPL138_pinmuxConfig(PINMUX_MCASP_REG_1, PINMUX_MCASP_MASK_1, PINMUX_MCASP_VAL_1);

  // replaces I2C_init();
  *( volatile uint32_t* )(0x01C22024) = 0;
  *( volatile uint32_t* )(0x01C22030) = 2;
  *( volatile uint32_t* )(0x01C2200C) = 5;
  *( volatile uint32_t* )(0x01C22010) = 5;
  *( volatile uint32_t* )(0x01C22024) |= 0x20;
  spiconf.mode = SPI_MODE_MASTER;
  spiconf.pin_option = SPI_4PIN_CS;
  spiconf.cs_active = SPI_CS_ACTIVE_LOW;
  spiconf.shift_dir = SPI_SHIFT_MSB;
  spiconf.polarity = 0;
  spiconf.phase = 0;
  spiconf.freq = 1500000;

  CSR = 0x0000; // disable interrupts globally while initialising
                // GIE is bit 0 of CSR register

  L138_init_aic3106_registers(fs, adc_gain, dac_atten,input_type);

  L138_init_mcasp_edma();
  SPI_init(SPI0,&spiconf);
  // clear any pending interrupts within EDMA3CC
  EDMA_3CC_ICR = 0x0007; // writing to ICR affects IPR
  // associate event n with interrupt 4 by writing n into LSBs of INTMUX1
  // LSBs of INTMUX1 are literally associated with INT4
  // in this case n=8 (EDMA3CC   event)
 INTC_INTMUX1 = 0x00000008;

 ISTP = (unsigned int)vectors;
  // enable TCC = 0 and TCC = 1 EDMA3 interrupts by setting bits 0 and 1 in IESR
  EDMA3_IESR = 0x0003;
  EDMA3_DRAE1 = 0x0003;

  // clear all pending interrupt flags
  // interrupt clear register ICR is used to clear bits in interrupt flag register IFR
 ICR = 0xFFF0;  // ICR bits 3, 2, 1, and 0 are reserved, read as 0, write has no effect
 IER |= 0x12;  //enable NMI (bit 1) and INT4 (bit 4)
 //InitSPI();
  CSR |= 0x01;  // enable interrupts globally

}


  • Hi Anshul,

    Welcome to the TI E2E forum. I hope you will find many good answers here and in the TI.com documents and in the TI Wiki Pages (for processor issues). Be sure to search those for helpful information and to browse for the questions others may have asked on similar topics (e2e.ti.com).

    I am not able to see the code section which you have copy pasted as text (Highlighted).
    You please attach the code.
  • Hi Arvind,

    My Apologies. I didn't realize that the code did not get pasted. Here it is. The code for setting up the interrupts is towards the end of the text (INTMUX1, CSR and other registers)

    Regards,
    Anshul


    // L138_LCDK_aic3106_init.c
    //

    #define DUAL_RATE
    #include "L138_LCDK_aic3106_init.h"
    #include "evmomapl138_spi.h"


    int16_t *pingIN, *pingOUT, *pongIN, *pongOUT;

    AIC31_data_type AIC31_data;

    spi_config_t spiconf;

    extern void vectors(void);


    void EDMA3_PaRAM_setup() // sets up PaRAM and enables EDMA events
    {
    uint32_t *EDMA3_PaRAM_ptr;
    // PaRAM sets (channels) 0 and 1, triggered by McASP0
    // receive and transmit events respectively, are used
    // with linked parameters set up in PaRAM sets (channels) 64, 65, 67, and 68
    // the linked parameters differ only in the ping or pong buffers used

    // set up PaRAM set 1 (MCASP0 XEVT)

    EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04020);

    *EDMA3_PaRAM_ptr++ = 0x00000000; // no EDMA3 interrupts on transfer complete
    *EDMA3_PaRAM_ptr++ = (unsigned int)pingOUT; // source is one of two output buffers
    *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
    // BCNT = BUFCOUNT/2(arrays per frame), ACNT = 4(bytes per array) writing to a (32-bit) McASP0 serialiser
    *EDMA3_PaRAM_ptr++ = 0x01D02000; // destination is DMA port of McASP0
    *EDMA3_PaRAM_ptr++ = 0x00000004; // dest address is static, increment source address by ACNT bytes
    *EDMA3_PaRAM_ptr++ = 0x00000800; // BCNT reload value is redundant - link to PaRAM set 64
    *EDMA3_PaRAM_ptr++ = 0x00000000; // CCNTIDX
    *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT = 1(frame per block)

    // set up PaRAM set 64

    EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04800);

    *EDMA3_PaRAM_ptr++ = 0x00000000; // same as PaRAM set 1
    *EDMA3_PaRAM_ptr++ = (unsigned int)pongOUT; // apart from source buffer used
    *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
    *EDMA3_PaRAM_ptr++ = 0x01D02000;
    *EDMA3_PaRAM_ptr++ = 0x00000004;
    *EDMA3_PaRAM_ptr++ = 0x00000820; // BCNT reload value is redundant - link to PaRAM set 65
    *EDMA3_PaRAM_ptr++ = 0x00000000;
    *EDMA3_PaRAM_ptr++ = 0x00000001;

    // set up PaRAM set 65

    EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04820);

    *EDMA3_PaRAM_ptr++ = 0x00000000; // exactly the same as PaRAM set 1
    *EDMA3_PaRAM_ptr++ = (unsigned int)pingOUT;
    *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
    *EDMA3_PaRAM_ptr++ = 0x01D02000;
    *EDMA3_PaRAM_ptr++ = 0x00000004;
    *EDMA3_PaRAM_ptr++ = 0x00000800; // BCNT reload value is redundant - link to PaRAM set 64
    *EDMA3_PaRAM_ptr++ = 0x00000000;
    *EDMA3_PaRAM_ptr++ = 0x00000001;


    // set up PaRAM set 0 (MCASP0 REVT)

    EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04000);

    *EDMA3_PaRAM_ptr++ = 0x00100000; // OPT interrupt on transfer complete with TCC = 0
    *EDMA3_PaRAM_ptr++ = 0x01D02000; // SRC DMA port of McASP0
    *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
    *EDMA3_PaRAM_ptr++ = (unsigned int)pingIN; // DST one of two output buffers
    *EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX increment dest by 4 bytes, src is static
    *EDMA3_PaRAM_ptr++ = 0x00000860; // BCNT reload value is redundant - link to PaRAM set 67
    *EDMA3_PaRAM_ptr++ = 0x00000000; //
    *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT 1 frame per block

    // set up parameter RAM set 67

    EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04860);

    *EDMA3_PaRAM_ptr++ = 0x00101000; // OPT similar to PaRAM set 1 but TCC = 1 and different buffer used
    *EDMA3_PaRAM_ptr++ = 0x01D02000; // SRC
    *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
    *EDMA3_PaRAM_ptr++ = (unsigned int)pongIN; // DST - single address used for XBUFn, RBUFn if RBSEL = 0
    *EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX
    *EDMA3_PaRAM_ptr++ = 0x00000880; // BCNT reload value is redundant - link to PaRAM set 68
    *EDMA3_PaRAM_ptr++ = 0x00000000; //
    *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT

    // set up parameter RAM set 68

    EDMA3_PaRAM_ptr = (unsigned int *)(0x01C04880); // exactly the same as PaRAM set 1

    *EDMA3_PaRAM_ptr++ = 0x00100000; // OPT
    *EDMA3_PaRAM_ptr++ = 0x01D02000; // SRC
    *EDMA3_PaRAM_ptr++ = (int32_t)((((BUFCOUNT/2)<<16) & 0xFFFF0000) | 0x00000004);
    *EDMA3_PaRAM_ptr++ = (unsigned int)pingIN; // DST - single address used for XBUFn, RBUFn if RBSEL = 0
    *EDMA3_PaRAM_ptr++ = 0x00040000; // DSTBIDX, SRCBIDX
    *EDMA3_PaRAM_ptr++ = 0x00000860; // BCNT reload value is redundant - link to PaRAM set 67
    *EDMA3_PaRAM_ptr++ = 0x00000000; //
    *EDMA3_PaRAM_ptr++ = 0x00000001; // rsvd, CCNT


    EDMA_3CC_IECRH = 0xffffffff; // IERH - Disable high interrupts
    EDMA_3CC_EECRH = 0xffffffff; // EERH - Disable high events
    EDMA_3CC_ICRH = 0xffffffff; // ICRH - Clear high interrupts
    EDMA_3CC_ECRH = 0xffffffff; // ICRH - Clear high events

    EDMA_3CC_IECR = 0xffffffff; // IER - Disable low interrupts
    EDMA_3CC_EECR = 0xffffffff; // EER - Disable low events
    EDMA_3CC_ICR = 0xffffffff; // ICR - Clear low interrupts
    EDMA_3CC_ECR = 0xffffffff; // ICRH - Clear low events


    EDMA_3CC_EESR = 0x00000003; // enable EDMA3 events 0 and 1, i.e. McASP REVT and XEVT
    }

    //configure and initialise MCASP0 for edma3-based i/o
    void L138_init_mcasp_edma()
    {

    // reset mcasp.
    MCASP->GBLCTL = 0;

    // configure receive registers.
    MCASP->RMASK = 0x0000FFFF;
    MCASP->RFMT = 0x00018070;// was 0x000080F0
    MCASP->AFSRCTL = 0x00000111;// was 0x00000000
    MCASP->ACLKRCTL = 0x00000080;// was 0x00000000
    MCASP->AHCLKRCTL = 0x00000000;// was 0x00000000
    MCASP->RTDM = 0x00000003;// was 0x00000001
    MCASP->RINTCTL = 0x00000000;
    MCASP->RCLKCHK = 0x00FF0005;// was 0x00000000

    // configure transmit registers.
    MCASP->XMASK = 0x0000FFFF;
    MCASP->XFMT = 0x00018074;// was 0x000080F0
    MCASP->AFSXCTL = 0x00000110;// was 0x00000000
    MCASP->ACLKXCTL = 0x00000080;// was 0x00000000
    MCASP->AHCLKXCTL = 0x00000000;// was 0x00000000
    MCASP->XTDM = 0x00000003;// was 0x00000001
    MCASP->XINTCTL = 0x00000000;
    MCASP->XCLKCHK = 0x00FF0005;// was 0x00000000
    // config serializers (13 = xmit, 14 = rcv).
    MCASP->SRCTL13 = 0x000D;// was 0x000D
    MCASP->SRCTL14 = 0x000E;// was 0x000E

    // config pin function and direction.
    MCASP->PFUNC = 0;
    MCASP->PDIR = 0x00002000;

    //
    MCASP->DITCTL = 0x00000000;
    MCASP->DLBCTL = 0x00000000;
    MCASP->AMUTE = 0x00000000;


    // enable the audio clocks, verifying each bit is properly set.
    SETBIT(MCASP->XGBLCTL, XHCLKRST);
    while (!CHKBIT(MCASP->XGBLCTL, XHCLKRST)) {}
    SETBIT(MCASP->RGBLCTL, RHCLKRST);
    while (!CHKBIT(MCASP->RGBLCTL, RHCLKRST)) {}


    EDMA3_PaRAM_setup();

    MCASP->XSTAT = 0x0000FFFF; // Clear all
    MCASP->RSTAT = 0x0000FFFF; // Clear all

    // if DMA is being used, verify that the XDATA bit (5) in XSTAT
    // is cleared to 0. (it should have been cleared y writing 1 to it)
    while ( ( MCASP->XSTAT & 0x00000020 ) != 0x00000000 );

    SETBIT(MCASP->XGBLCTL, XSRCLR);
    while (!CHKBIT(MCASP->XGBLCTL, XSRCLR)) {}
    SETBIT(MCASP->RGBLCTL, RSRCLR);
    while (!CHKBIT(MCASP->RGBLCTL, RSRCLR)) {}

    /* Write a 0, so that no underrun occurs after releasing the state machine */
    MCASP->XBUF13 = 0;
    MCASP->RBUF14 = 0;

    SETBIT(MCASP->XGBLCTL, XSMRST);
    while (!CHKBIT(MCASP->XGBLCTL, XSMRST)) {}
    SETBIT(MCASP->RGBLCTL, RSMRST);
    while (!CHKBIT(MCASP->RGBLCTL, RSMRST)) {}

    SETBIT(MCASP->XGBLCTL, XFRST);
    while (!CHKBIT(MCASP->XGBLCTL, XFRST)) {}
    SETBIT(MCASP->RGBLCTL, RFRST);
    while (!CHKBIT(MCASP->RGBLCTL, RFRST)) {}

    // wait for transmit ready and send a dummy byte.
    while(!CHKBIT(MCASP->SRCTL13, XRDY)) {}
    MCASP->XBUF13 = 0;
    }


    // initialise AIC3106 codec by writing to its control registers
    // sampling frequency, ADC gain, and DAC attenuation are set according to parameters passed


    void L138_init_aic3106_registers(int32_t fs, int16_t adc_gain, int16_t dac_atten, int8_t input_type)
    {
    // not every register is set here - some are left with default(reset) values
    // each AIC3106 register is 8 bits wide

    AIC3106_writeRegister( 0, 0x00 ); // AIC3106_PAGESELECT is PAGE 0 REG 0
    AIC3106_writeRegister( 1, 0x80 ); // reset AIC3106 using REG 1

    switch(fs) // set up sampling rate - default 8kHz
    {
    case FS_8000_HZ:
    AIC3106_writeRegister( 2, 0xAA );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_9600_HZ:
    AIC3106_writeRegister( 2, 0x88 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_11025_HZ:
    AIC3106_writeRegister( 2, 0x66 );
    AIC3106_writeRegister( 7, 0x8A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_12000_HZ:
    AIC3106_writeRegister( 2, 0x66 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_16000_HZ:
    AIC3106_writeRegister( 2, 0x44 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_19200_HZ:
    AIC3106_writeRegister( 2, 0x33 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_22050_HZ:
    AIC3106_writeRegister( 2, 0x22 );
    AIC3106_writeRegister( 7, 0x8A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_24000_HZ:
    AIC3106_writeRegister( 2, 0x22 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_32000_HZ:
    AIC3106_writeRegister( 2, 0x11 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_44100_HZ:
    AIC3106_writeRegister( 2, 0x00 );
    AIC3106_writeRegister( 7, 0x8A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    case FS_48000_HZ:
    AIC3106_writeRegister( 2, 0x00 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    #if defined DUAL_RATE
    case FS_96000_HZ:
    AIC3106_writeRegister( 2, 0x00 );
    AIC3106_writeRegister( 7, 0x6A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    #endif
    default:
    AIC3106_writeRegister( 2, 0x00 );
    AIC3106_writeRegister( 7, 0x0A ); // Codec Datapath Setup [LeftDAC=LEFT][RightDAC=RIGHT]
    break;
    }

    AIC3106_writeRegister( 3, 0x22 ); // disable PLL and set Q=4(relevant) and P=2(irrelevant)
    // fsref will be MCLK/(128*Q) = 48000
    // MCLK on eXperimenter is 24.576MHz from on-board Citizen oscillator
    AIC3106_writeRegister( 4, 0x20 ); // J=8 (irrelevant since PLL disabled)
    AIC3106_writeRegister( 5, 0x6E ); // D=7075 MS bits (irrelevant since PLL disabled)
    AIC3106_writeRegister( 6, 0x23 ); // D=7075 LS bits (irrelevant since PLL disabled)
    AIC3106_writeRegister( 8, 0xC0 ); // Audio Interface Control A BCLK=Slave(input), WCLK=Slave(input)
    AIC3106_writeRegister( 9, 0x00 ); // Audio Interface Control B DSP mode (1 slot), 32 bit slot width

    AIC3106_writeRegister( 12, 0x00 ); // Audio Interface Control C Data offset=0


    AIC3106_writeRegister( 10, 0x00 ); // Audio Interface Control C Data offset=0
    // WARNING - this assumes that adc_gain is a sensible value
    AIC3106_writeRegister( 15, adc_gain ); // Left ADC Programmable Gain Amplifier Mute=OFF Gain=0dB
    AIC3106_writeRegister( 16, adc_gain ); // Right ADC Programmable Gain Amplifier Mute=OFF Gain=0dB

    if (input_type == LCDK_LINE_INPUT)
    {
    AIC3106_writeRegister( 19, 0x04 ); // power up ADCs
    AIC3106_writeRegister( 22, 0x04 ); // and connect LINE1L/R to ADC
    }
    else
    {
    AIC3106_writeRegister( 19, 0x7C ); // power up ADCs
    AIC3106_writeRegister( 22, 0x7C ); // and do not connect LINE1L/R to ADC
    AIC3106_writeRegister( 17, 0x0F ); // 17 MIC3L to L ADC (default 0xFF, NC) 0x00 0dB
    AIC3106_writeRegister( 18, 0xF0 ); // 18 MIC3R to R ADC (default 0xFF, NC) 0x00 0dB
    AIC3106_writeRegister( 25, 0x40 ); // 25 MICBIAS 0x40 2V, 0x00 OFF
    }

    AIC3106_writeRegister( 37, 0xE0 ); // DAC Power & Output Dvr LeftDAC=ON, RightDAC=ON, HPLCOM=SingleEnd]
    // WARNING - this assumes that dac_atten is a sensible value
    AIC3106_writeRegister( 43, dac_atten ); // Left DAC Digital Volume Mute=OFF, Gain=0dB
    AIC3106_writeRegister( 44, dac_atten ); // Right DAC Digital Volume Mute=OFF, Gain=0dB
    AIC3106_writeRegister( 82, 0x80 ); // was 0x80 DAC_L1 to LEFT_LOP/M Volume Routed, Gain=0dB
    AIC3106_writeRegister( 86, 0x09 ); // LEFT_LOP/M Output Mute=OFF bit3 bit0 is REad only ?! must be set!
    AIC3106_writeRegister( 92, 0x80 ); // was 0x80 92 DAC_R1 to RIGHT_LOP/M Volume <- [Routed]
    AIC3106_writeRegister( 93, 0x09 ); // 93 RIGHT_LOP/M Output <- [Mute=OFF][Power=ON]
    AIC3106_writeRegister( 101, 0x01 ); // 101 GPIO Control Register B <- [CODEC_CLKIN = CLKDIV_OUT]
    AIC3106_writeRegister( 102, 0 );
    }

    // initialisation routine called by example program for edma3-based i/o

    void L138_initialise_edma(int32_t fs, int16_t adc_gain, int16_t dac_atten, int8_t input_type)
    {

    poll = 0; // used in input_sample() and output_sample() functions


    // allocate memory for ping pong buffers
    pingOUT = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));
    pongOUT = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));
    pingIN = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));
    pongIN = (int16_t *)malloc(BUFCOUNT*sizeof(int16_t));

    USTIMER_init();

    EVMOMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_MCASP0, PSC_ENABLE);
    EVMOMAPL138_pinmuxConfig(PINMUX_MCASP_REG_0, PINMUX_MCASP_MASK_0, PINMUX_MCASP_VAL_0);
    EVMOMAPL138_pinmuxConfig(PINMUX_MCASP_REG_1, PINMUX_MCASP_MASK_1, PINMUX_MCASP_VAL_1);

    // replaces I2C_init();
    *( volatile uint32_t* )(0x01C22024) = 0;
    *( volatile uint32_t* )(0x01C22030) = 2;
    *( volatile uint32_t* )(0x01C2200C) = 5;
    *( volatile uint32_t* )(0x01C22010) = 5;
    *( volatile uint32_t* )(0x01C22024) |= 0x20;
    spiconf.mode = SPI_MODE_MASTER;
    spiconf.pin_option = SPI_4PIN_CS;
    spiconf.cs_active = SPI_CS_ACTIVE_LOW;
    spiconf.shift_dir = SPI_SHIFT_MSB;
    spiconf.polarity = 0;
    spiconf.phase = 0;
    spiconf.freq = 1500000;

    CSR = 0x0000; // disable interrupts globally while initialising
    // GIE is bit 0 of CSR register

    L138_init_aic3106_registers(fs, adc_gain, dac_atten,input_type);

    L138_init_mcasp_edma();
    SPI_init(SPI0,&spiconf);
    // clear any pending interrupts within EDMA3CC
    EDMA_3CC_ICR = 0x0007; // writing to ICR affects IPR
    // associate event n with interrupt 4 by writing n into LSBs of INTMUX1
    // LSBs of INTMUX1 are literally associated with INT4
    // in this case n=8 (EDMA3CC event)
    INTC_INTMUX1 = 0x00000008;

    ISTP = (unsigned int)vectors;
    // enable TCC = 0 and TCC = 1 EDMA3 interrupts by setting bits 0 and 1 in IESR
    EDMA3_IESR = 0x0003;
    EDMA3_DRAE1 = 0x0003;

    // clear all pending interrupt flags
    // interrupt clear register ICR is used to clear bits in interrupt flag register IFR
    ICR = 0xFFF0; // ICR bits 3, 2, 1, and 0 are reserved, read as 0, write has no effect
    IER |= 0x12; //enable NMI (bit 1) and INT4 (bit 4)
    //InitSPI();
    CSR |= 0x01; // enable interrupts globally

    }
  • Hi Anshul,


    Also, would the timer initialization code (highlighted) need to be modified to be compatible with the SYS/BIOS Timer

    I think you can use timer initialization code as-is, no need to modify it for SYS/BIOS.

    If I configure the hardware interrupt statically using the .cfg file, which registers will it affect and which registers will have to be deleted so that their value is not set twice.

    By configuring hardware interrupt statically in .cfg file. INTMUX1 and CSR registers will be affected, so these registers need to be erased from application code.

  • Hi Arvind,

    from what I understand, No changes need to be made to the ICR and IER Registers mentioned in the code.

    Is that correct?.

    Regards,
    Anshul
  • Anshul,

    It would be better to retain the hardware interrupt configuration for EDMA in the application code for ease of use, but if you are particular to move it statically to bios config file, there would be an impact on the piece of code below:

    // clear any pending interrupts within EDMA3CC

    EDMA_3CC_ICR = 0x0007; // writing to ICR affects IPR

    // associate event n with interrupt 4 by writing n into LSBs of INTMUX1

    // LSBs of INTMUX1 are literally associated with INT4

    // in this case n=8 (EDMA3CC event)

    INTC_INTMUX1 = 0x00000008;

    ISTP = (unsigned int)vectors;

    // enable TCC = 0 and TCC = 1 EDMA3 interrupts by setting bits 0 and 1 in IESR

    EDMA3_IESR = 0x0003;

    EDMA3_DRAE1 = 0x0003;

    // clear all pending interrupt flags

    // interrupt clear register ICR is used to clear bits in interrupt flag register IFR

    ICR = 0xFFF0; // ICR bits 3, 2, 1, and 0 are reserved, read as 0, write has no effect

    IER |= 0x12; //enable NMI (bit 1) and INT4 (bit 4)

    //InitSPI();

    CSR |= 0x01; // enable interrupts globally

    Kindly ensure the above piece of code functionality shouldn't be configured twice.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • That's all I needed to know. Thanks

    Regards,
    Anshul