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.

OMAP-L138: EDMA3 Linking/Reloading to same param set repeatedly

Part Number: OMAP-L138

Hi

I have developed a code for audio in loopback mode considering MCASP playback code as a reference. I have made modifications as per my application requirements. 

My scenario involves a single buffered Audio transfer continuously. I am facing some issue regarding EDMA reloading/linking with the same param set repeatedly (as I am not using ping pong buffering).

Like I have done in C6416 DSP:

EDMA_link(hEdma, hEdmaReload);

EDMA_link( hEdmaReload, hEdmaReload);

I am pasting my code below, please tell me how to do EDMA Reloading and linking. As currently, I can't listen audio in this code.

#include "edma_event.h"
#include "interrupt.h"
#include "soc_C6748.h"
#include "hw_syscfg0_C6748.h"
#include "lcdkC6748.h"
#include "codecif.h"
#include "hw_edma3cc.h"
#include "hw_edma3tc.h"
#include "edma.h"
#include "hw_mcasp.h"
#include "mcasp.h"
#include "aic31.h"
#include "psc.h"

#include <string.h>

/****************************************************************************/
/* LOCAL FUNCTION PROTOTYPES. */
/****************************************************************************/
static void registerEdma3Interrupts(void);
static void SetupINTCInt(void);
static void edma3CCComplIsr(void);
static void edma3Test();
static void AIC31I2SConfigure(void);
static void McASPI2SConfigure(void);
static void I2SDataTxRxActivate(void);


/****************************************************************************/
/* GLOBAL VARIABLES */
/****************************************************************************/

/* AIC3106 codec address */
#define I2C_SLAVE_CODEC_AIC31 (0x18u)

#define I2S_SLOTS 3u

/* Interrupt channels to map in AINTC */
#define INT_CHANNEL_I2C (2u)

/* McASP Serializer for Receive */
#define MCASP_XSER_RX (14u)

/* McASP Serializer for Transmit */
#define MCASP_XSER_TX (13u)

/* Sampling Rate which will be used by both transmit and receive sections */
#define SAMPLING_RATE (8000)

/* Slot size to send/receive data */
#define SLOT_SIZE (16u)

/* Word size to send/receive data. Word size <= Slot size */
#define WORD_SIZE (16u)

#define BYTES_PER_SAMPLE (2u)

/* Number of samples in loop buffer */
#define NUM_SAMPLES_TX_BUF (10u)

#define SIZE_PARAMSET (32u)

/* Number of linked parameter set used per tx/rx */
#define NUM_PAR (2u)

/* Specify where the parameter set starting is */
#define PAR_ID_START (40u)

#define PAR_RX_START (PAR_ID_START)
#define PAR_TX_START (PAR_RX_START + NUM_PAR)

#define NUM_SAMPLES_PER_AUDIO_BUF 10

#define AUDIO_BUF_SIZE (NUM_SAMPLES_PER_AUDIO_BUF \
* BYTES_PER_SAMPLE) //2000*4=8000

static short srcBuff[AUDIO_BUF_SIZE ];
static short dstBuff[AUDIO_BUF_SIZE ];

unsigned int evtQ = 0;/* Event Queue used */

/****************************************************************************/
/* LOCAL FUNCTION DEFINITIONS */
/****************************************************************************/

/*
** Default paRAM for Transmit section. This will be transmitting from
** a loop buffer.
*/
static struct EDMA3CCPaRAMEntry const txDefaultPar =
{
//(unsigned int)(EDMA3CC_OPT_DAM | (0x02 << 8u)), /* Opt field */ //Destination addressing Mode

(unsigned int)(EDMA3CC_OPT_DAM | ((EDMA3_CHA_MCASP0_RX << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC)),
(unsigned int)srcBuff, /* source address */
(unsigned short)(BYTES_PER_SAMPLE), /* aCnt */ //4 bytes per sample
(unsigned short)(NUM_SAMPLES_TX_BUF), /* bCnt */
(unsigned int) SOC_MCASP_0_DATA_REGS, /* dest address */
(short) (BYTES_PER_SAMPLE), /* source bIdx */
(short)(0), /* dest bIdx */
(unsigned short)(PAR_TX_START * SIZE_PARAMSET), /* link address */ //42
(unsigned short)(0), /* bCnt reload value */
(short)(0), /* source cIdx */
(short)(0), /* dest cIdx */
(unsigned short)1 /* cCnt */
};

/*
** Default paRAM for Receive section.
*/
static struct EDMA3CCPaRAMEntry const rxDefaultPar =
{
//(unsigned int)(EDMA3CC_OPT_SAM | (0x02 << 8u)), /* Opt field */ //Source addressing Mode
(unsigned int)(EDMA3CC_OPT_SAM | ((EDMA3_CHA_MCASP0_TX << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC)),
(unsigned int)SOC_MCASP_0_DATA_REGS, /* source address */
(unsigned short)(BYTES_PER_SAMPLE), /* aCnt */
(unsigned short)(NUM_SAMPLES_TX_BUF), /* bCnt */
(unsigned int)dstBuff, /* dest address */
(short) (0), /* source bIdx */
(short)(BYTES_PER_SAMPLE), /* dest bIdx */
(unsigned short)(PAR_RX_START * SIZE_PARAMSET), /* link address */
(unsigned short)(0), /* bCnt reload value */
(short)(0), /* source cIdx */
(short)(0), /* dest cIdx */
(unsigned short)1 /* cCnt */
};

int main(void)
{
//volatile unsigned int status = FALSE;

/* Set up pin mux for I2C module 0 */
I2CPinMuxSetup(0);
McASPPinMuxSetup();

/* Power up the McASP module */
PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_MCASP0, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);
/* Power up EDMA3CC_0 and EDMA3TC_0 */
PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_CC0, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);
PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_TC0, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);

/* Initialize the I2C 0 interface for the codec AIC31 */
I2CCodecIfInit(SOC_I2C_0_REGS, INT_CHANNEL_I2C, I2C_SLAVE_CODEC_AIC31);

SetupINTCInt();

EDMA3Init(SOC_EDMA30CC_0_REGS, evtQ);

registerEdma3Interrupts();

edma3Test();

/* Configure the Codec for I2S mode */
AIC31I2SConfigure();

/* Configure the McASP for I2S */
McASPI2SConfigure();

/* Activate the audio transmission and reception */
I2SDataTxRxActivate();

//EDMA3Deinit(SOC_EDMA30CC_0_REGS, evtQ);

while(1)
{
/* Copy the buffer */
memcpy((void *)dstBuff,
(void *)srcBuff,
AUDIO_BUF_SIZE);
}
}


/* ============ CODEC CONFIGURATION ============== */

/*
** Function to configure the codec for I2S mode
*/
static void AIC31I2SConfigure(void)
{
volatile unsigned int delay = 0xFFF;

AIC31Reset(SOC_I2C_0_REGS);
while(delay--);

/* Configure the data format and sampling rate */
AIC31DataConfig(SOC_I2C_0_REGS, AIC31_DATATYPE_I2S, SLOT_SIZE, 0);
AIC31SampleRateConfig(SOC_I2C_0_REGS, AIC31_MODE_BOTH, SAMPLING_RATE);

/* Initialize both ADC and DAC */
AIC31ADCInit(SOC_I2C_0_REGS);
AIC31DACInit(SOC_I2C_0_REGS);
}

/*======================= MCASP CONFIGURATIONS ======================*/
/*
** Configures the McASP Transmit Section in I2S mode.
*/
static void McASPI2SConfigure(void)
{
McASPRxReset(SOC_MCASP_0_CTRL_REGS);
McASPTxReset(SOC_MCASP_0_CTRL_REGS);

/* Enable the FIFOs for DMA transfer */
McASPReadFifoEnable(SOC_MCASP_0_FIFO_REGS, 1, 1);
McASPWriteFifoEnable(SOC_MCASP_0_FIFO_REGS, 1, 1);

/* Set I2S format in the transmitter/receiver format units */
McASPRxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE,
MCASP_RX_MODE_DMA);
McASPTxFmtI2SSet(SOC_MCASP_0_CTRL_REGS, WORD_SIZE, SLOT_SIZE,
MCASP_TX_MODE_DMA);

/* Configure the frame sync. I2S shall work in TDM format with 2 slots */
McASPRxFrameSyncCfg(SOC_MCASP_0_CTRL_REGS, 2, MCASP_RX_FS_WIDTH_WORD,
MCASP_RX_FS_EXT_BEGIN_ON_RIS_EDGE);
McASPTxFrameSyncCfg(SOC_MCASP_0_CTRL_REGS, 2, MCASP_TX_FS_WIDTH_WORD,
MCASP_TX_FS_EXT_BEGIN_ON_RIS_EDGE);

/* configure the clock for receiver */
McASPRxClkCfg(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_EXTERNAL, 0, 0);
McASPRxClkPolaritySet(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_POL_RIS_EDGE);
McASPRxClkCheckConfig(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLKCHCK_DIV32,
0x00, 0xFF);

/* configure the clock for transmitter */
McASPTxClkCfg(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_EXTERNAL, 0, 0);
McASPTxClkPolaritySet(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_POL_FALL_EDGE);
McASPTxClkCheckConfig(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLKCHCK_DIV32,
0x00, 0xFF);

/* Enable synchronization of RX and TX sections */
McASPTxRxClkSyncEnable(SOC_MCASP_0_CTRL_REGS);

/* Enable the transmitter/receiver slots. I2S uses 2 slots */
McASPRxTimeSlotSet(SOC_MCASP_0_CTRL_REGS, I2S_SLOTS);
McASPTxTimeSlotSet(SOC_MCASP_0_CTRL_REGS, I2S_SLOTS);

/*
** Set the serializers, Currently only one serializer is set as
** transmitter and one serializer as receiver.
*/
McASPSerializerRxSet(SOC_MCASP_0_CTRL_REGS, MCASP_XSER_RX);
McASPSerializerTxSet(SOC_MCASP_0_CTRL_REGS, MCASP_XSER_TX);

/*
** Configure the McASP pins
** Input - Frame Sync, Clock and Serializer Rx
** Output - Serializer Tx is connected to the input of the codec
*/
McASPPinMcASPSet(SOC_MCASP_0_CTRL_REGS, 0xFFFFFFFF);
McASPPinDirOutputSet(SOC_MCASP_0_CTRL_REGS, MCASP_PIN_AXR(MCASP_XSER_TX));
McASPPinDirInputSet(SOC_MCASP_0_CTRL_REGS, MCASP_PIN_AFSX
| MCASP_PIN_ACLKX
| MCASP_PIN_AFSR
| MCASP_PIN_ACLKR
| MCASP_PIN_AXR(MCASP_XSER_RX));

/* Enable error interrupts for McASP */
McASPTxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_TX_DMAERROR
| MCASP_TX_CLKFAIL
| MCASP_TX_SYNCERROR
| MCASP_TX_UNDERRUN);

McASPRxIntEnable(SOC_MCASP_0_CTRL_REGS, MCASP_RX_DMAERROR
| MCASP_RX_CLKFAIL
| MCASP_RX_SYNCERROR
| MCASP_RX_OVERRUN);
}

/*
** Activates the data transmission/reception
** The DMA parameters shall be ready before calling this function.
*/
static void I2SDataTxRxActivate(void)
{
/* Start the clocks */
McASPRxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_RX_CLK_EXTERNAL);
McASPTxClkStart(SOC_MCASP_0_CTRL_REGS, MCASP_TX_CLK_EXTERNAL);

/* Enable EDMA for the transfer */
EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_RX,
EDMA3_TRIG_MODE_EVENT);
EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS,
EDMA3_CHA_MCASP0_TX, EDMA3_TRIG_MODE_EVENT);

/* Activate the serializers */
McASPRxSerActivate(SOC_MCASP_0_CTRL_REGS);
McASPTxSerActivate(SOC_MCASP_0_CTRL_REGS);

/* make sure that the XDATA bit is cleared to zero */
while(McASPTxStatusGet(SOC_MCASP_0_CTRL_REGS) & MCASP_TX_STAT_DATAREADY);

/* Activate the state machines */
McASPRxEnable(SOC_MCASP_0_CTRL_REGS);
McASPTxEnable(SOC_MCASP_0_CTRL_REGS);
}

/*======================= EDMA CONFIGURATIONS ======================*/

static void edma3Test()
{

EDMA3CCPaRAMEntry paramSet_tx;
EDMA3CCPaRAMEntry paramSet_rx;

/*
** Request EDMA channels. Channel 0 is used for reception and
** Channel 1 is used for transmission
*/
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
EDMA3_CHA_MCASP0_TX, EDMA3_CHA_MCASP0_TX, 0);
EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA,
EDMA3_CHA_MCASP0_RX, EDMA3_CHA_MCASP0_RX, 0);


memcpy(&paramSet_rx, &rxDefaultPar, SIZE_PARAMSET);
/* Program the TCC */
paramSet_rx.opt |= ((EDMA3_CHA_MCASP0_RX << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
/* Enable Intermediate & Final transfer completion interrupt */
paramSet_rx.opt |= (1 << EDMA3CC_OPT_ITCINTEN_SHIFT);
paramSet_rx.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_RX, &paramSet_rx);


memcpy(&paramSet_tx, &txDefaultPar, SIZE_PARAMSET);
paramSet_tx.opt |= ((EDMA3_CHA_MCASP0_TX << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
paramSet_tx.opt |= (1 << EDMA3CC_OPT_ITCINTEN_SHIFT);
paramSet_tx.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_TX, &paramSet_tx);

/*Linking*/

}


void registerEdma3Interrupts()
{
/* Register Interrupts Here */

/******************** Completion Interrupt ********************************/

IntRegister(4, edma3CCComplIsr);
IntEventMap(4, SYS_INT_EDMA3_0_CC0_INT1);
IntEnable(4);

}

/**
* edma3CCComplIsr
* \brief ISR for successful transfer completion.
*
* \note This function first disables its own interrupt to make it non-
* entrant.
*
* \return None.
*/
void edma3CCComplIsr()
{
volatile unsigned int pendingIrqs;
volatile unsigned int isIPR = 0;

IntEventClear(SYS_INT_EDMA3_0_CC0_INT1);

/* Check if receive DMA completed */
if(EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS) & (1 << EDMA3_CHA_MCASP0_RX))
{
/* Clear the interrupt status for the 0th channel */
EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_RX);

}

/* Check if transmit DMA completed */
if(EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS) & (1 << EDMA3_CHA_MCASP0_TX))
{
/* Clear the interrupt status for the first channel */
EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, EDMA3_CHA_MCASP0_TX);

}
}

/* This function invokes necessary functions to configure the ARM
** processor and ARM Interrupt Controller(AINTC) to receive and
** handle interrupts.
*/
static void SetupINTCInt(void)
{

IntDSPINTCInit();
IntGlobalEnable();

}

/********************************** End of file *****************************/