Hi,
I'm trying to setup EDMA3 with CSL for the DSP side of the OMAP L138 in order to gather samples into buffers from the onboard TLV320AIC3106 of my experimenter kit.
Two DSP examples from http://processors.wiki.ti.com/index.php/QuickStartOMAPL1x_rCSL were used for this EDMA 3 project as a starting point:
- Audio example (mcasp directory)
- EDMA_ping_pong_dspL138 (edma directory)
Both projects were executed on the DSP without any issue. So the audio project was a good starting point for my EDMA3 project to echo back samples from the input lines to output lines.
- First of all, I add to the PSC_Init() function the below two lines in the psc.c file:
CSL_FINST(psc0Regs->MDCTL[EDMA3_0CC_LPSC], PSC_MDCTL_NEXT, ENABLE);
CSL_FINST(psc0Regs->MDCTL[EDMA3_0TC0_LPSC], PSC_MDCTL_NEXT, ENABLE);
- Then enable the EDMA3 interrupt into DSPInit() function in the dspmm.c file:
CSL_FINST(IER, CHIP_IER_IE08, ENABLE ); // Enable Interrupt 8
- Select the EDMA3 Interrupt by adding the below line into the DSPIntCtrlInit
CSL_FINS(dspintcRegs->INTMUX2, DSPINTC_INTMUX2_INTSEL8, CSL_INTC_EVENTID_EDMA3_0_CC0_INT1);
- Change _INT8_ISR function by the one below:
Uint32 u32_EDMA_Xmt_Interrupt_Counter = 0u;
Uint32 u32_EDMA_Rcv_Interrupt_Counter = 0u;
interrupt void INT8_ISR(void)
{
Uint32 regIPR, IxBitMask, IxCounter;
while(edma3ccRegs->IPR != 0)
{
// Read Interrupt Pending Register
regIPR = edma3ccRegs->IPR;
// Loop for Set Interrupt Pending Bit
for(IxCounter = 0; IxCounter < 32; IxCounter++)
{
IxBitMask = 1 << IxCounter;
if(regIPR & IxBitMask)
{
// Exit Example on Correct Interrupt
if(IxCounter == EDMA_EVENT0)
{
// Interrupt Rcv counter increment
u32_EDMA_Rcv_Interrupt_Counter++;
}
else if(IxCounter == EDMA_EVENT1)
{
// Interrupt Xmit counter increment
u32_EDMA_Xmt_Interrupt_Counter++;
}
else
{
// No operation
asm(" NOP");
}
// Clear Pending Interrupt
edma3ccRegs->ICR = IxBitMask;
break;
}
}
}
}
- Setup EDMA3 channels with functions below:
#define NUM_OF_BYTES_PER_WORD 4u // ACNT
#define NUM_OF_WORD_PER_BUFFER 128u // BCNT
#define NUM_OF_BUFFER 1u // CCNT
#define BUFSIZE NUM_OF_WORD_PER_BUFFER * NUM_OF_BUFFER
#define EDMA_EVENT0 (Uint8)0u
#define EDMA_EVENT1 (Uint8)1u
#define EDMA_PARAMETER_SET0 (Uint8)0u
#define EDMA_PARAMETER_SET1 (Uint8)1u
#define EDMA_PARAMETER_SET64 (Uint8)64u
#define EDMA_PARAMETER_SET65 (Uint8)65u
// Data alignment for both receive and transmit buffers
#pragma DATA_ALIGN(u32_Rcv_Buffer, 256u);
#pragma DATA_ALIGN(u32_Xmt_Buffer, 256u);
// Buffers
volatile Uint32 u32_Rcv_Buffer[BUFSIZE] = { 0u };
volatile Uint32 u32_Xmt_Buffer[BUFSIZE] = { 0u };
CSL_Edma3ccRegsOvly edma3ccRegs = (CSL_Edma3ccRegsOvly)(CSL_EDMA30CC_0_REGS);
// Function called just before calling McASPInit() function
void MAT_EDMA_Init(void)
{
Uint32 u32_Edma_Init_Counter = 0u;
// Setup EDMA
MAT_EDMA_Config();
// Init buffers
for(u32_Edma_Init_Counter = 0u; u32_Edma_Init_Counter < BUFSIZE; u32_Edma_Init_Counter++)
{
U32_Rcv_Buffer[u32_Edma_Init_Counter] = 0u;
U32_Xmt_Buffer[u32_Edma_Init_Counter] = 0u;
}
}
void MAT_EDMA_Config(void)
{
// Clear registers
CSL_FINST(edma3ccRegs->ECR, EDMA3CC_ECR_REG, MASK);
CSL_FINST(edma3ccRegs->SECR, EDMA3CC_SECR_REG, MASK);
CSL_FINST(edma3ccRegs->IECR, EDMA3CC_IPR_REG, MASK);
CSL_FINST(edma3ccRegs->ICR, EDMA3CC_IPR_REG, MASK);
// Enable channels - Region 1 (Region 0: ARM / Region 1: DSP)
edma3ccRegs->DRA[CSL_EDMA3_REGION_1].DRAE =
CSL_FMKT(EDMA3CC_DRAE_E0, ENABLE) |
CSL_FMKT(EDMA3CC_DRAE_E1, ENABLE);
// Assign Channel 0 - 1 to Queue 0
edma3ccRegs->DMAQNUM[0u] =
CSL_FMKT(EDMA3CC_DMAQNUM_E0, Q0) |
CSL_FMKT(EDMA3CC_DMAQNUM_E1, Q0);
// Initialize PaRAM Transfer Context for Events 0 - 1
MAT_EDMA_Config_Rcv_Param();
MAT_EDMA_Config_Xmt_Param();
// Enable channel 0 and 1
CSL_FINST(edma3ccRegs->EESR, EDMA3CC_EESR_E0, SET);
CSL_FINST(edma3ccRegs->EESR, EDMA3CC_EESR_E1, SET);
// Enable interrupt 0 and 1
CSL_FINST(edma3ccRegs->IESR, EDMA3CC_IESR_I0, SET);
CSL_FINST(edma3ccRegs->IESR, EDMA3CC_IESR_I1, SET);
}
void MAT_EDMA_Config_Rcv_Param (void)
{
//************** Parameter Set 0 *******************//
// Reset EDMA PaRAM OPT Register
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].OPT = CSL_EDMA3CC_OPT_RESETVAL;
// Config PaRAM OPT
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].OPT =
CSL_FMKT(EDMA3CC_OPT_ITCINTEN, DISABLE) |
CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE) |
CSL_FMKT(EDMA3CC_OPT_SYNCDIM, ASYNC) |
CSL_FMK(EDMA3CC_OPT_TCC, EDMA_EVENT0);
// Initialize EDMA Event Src and Dst Addresses
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].SRC = (Uint32)&mcaspRegs->RBUF12;
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].DST = (Uint32)&u32_Rcv_Buffer[0u];
// Set EDMA Event PaRAM A,B,C CNT
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].A_B_CNT =
CSL_FMK(EDMA3CC_A_B_CNT_ACNT, NUM_OF_BYTES_PER_WORD) |
CSL_FMK(EDMA3CC_A_B_CNT_BCNT, NUM_OF_WORD_PER_BUFFER);
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].CCNT = NUM_OF_BUFFER;
// Set EDMA Event PaRAM SRC/DST BIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].SRC_DST_BIDX =
CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX, 0u) |
CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, NUM_OF_BYTES_PER_WORD);
// Set EDMA Event PaRAM SRC/DST CIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].SRC_DST_CIDX =
CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, 0u) |
CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0u);
// Set EDMA Event PaRAM LINK and BCNTRLD
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET0].LINK_BCNTRLD =
CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64] & 0xFFFFu) |
CSL_FMK(EDMA3CC_LINK_BCNTRLD_BCNTRLD, NUM_OF_WORD_PER_BUFFER);
//************** Parameter Set 64 *******************//
// Reset EDMA PaRAM OPT Register
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].OPT = CSL_EDMA3CC_OPT_RESETVAL;
// Config PaRAM OPT (Enable TC & ITC Chaining; Set TCC)
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].OPT =
CSL_FMKT(EDMA3CC_OPT_ITCINTEN, DISABLE) |
CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE) |
CSL_FMKT(EDMA3CC_OPT_SYNCDIM, ASYNC) |
CSL_FMK(EDMA3CC_OPT_TCC, EDMA_EVENT0);
// Initialize EDMA Event Src and Dst Addresses
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].SRC = (Uint32)&mcaspRegs->RBUF12;
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].DST = (Uint32)&u32_Rcv _Buffer[0u];
// Set EDMA Event PaRAM A,B,C CNT
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].A_B_CNT =
CSL_FMK(EDMA3CC_A_B_CNT_ACNT, NUM_OF_BYTES_PER_WORD) |
CSL_FMK(EDMA3CC_A_B_CNT_BCNT, NUM_OF_WORD_PER_BUFFER);
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].CCNT = NUM_OF_BUFFER;
// Set EDMA Event PaRAM SRC/DST BIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].SRC_DST_BIDX =
CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX, 0u) |
CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, NUM_OF_BYTES_PER_WORD);
// Set EDMA Event PaRAM SRC/DST CIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].SRC_DST_CIDX =
CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, 0u) |
CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0u);
// Set EDMA Event PaRAM LINK and BCNTRLD
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64].LINK_BCNTRLD =
CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET64] & 0xFFFFu) |
CSL_FMK(EDMA3CC_LINK_BCNTRLD_BCNTRLD, NUM_OF_WORD_PER_BUFFER);
}
void MAT_EDMA_Config_Xmt_ Param(void)
{
//************** Link to parameter set 1 *******************//
// Reset EDMA PaRAM OPT Register
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].OPT = CSL_EDMA3CC_OPT_RESETVAL;
// Config PaRAM OPT
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].OPT =
CSL_FMKT(EDMA3CC_OPT_ITCINTEN, DISABLE) |
CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE) |
CSL_FMKT(EDMA3CC_OPT_SYNCDIM, ASYNC) |
CSL_FMK(EDMA3CC_OPT_TCC, EDMA_EVENT1);
// Initialize EDMA Event Src and Dst Addresses
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].SRC = (Uint32)&u32_Xmt_Buffer[0u];
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].DST = (Uint32)&mcaspRegs->XBUF11;
// Set EDMA Event PaRAM A,B,C CNT
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].A_B_CNT =
CSL_FMK(EDMA3CC_A_B_CNT_ACNT, NUM_OF_BYTES_PER_WORD) |
CSL_FMK(EDMA3CC_A_B_CNT_BCNT, NUM_OF_WORD_PER_BUFFER);
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].CCNT = NUM_OF_BUFFER;
// Set EDMA Event PaRAM SRC/DST BIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].SRC_DST_BIDX =
CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX, NUM_OF_BYTES_PER_WORD) |
CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, 0u);
// Set EDMA Event PaRAM SRC/DST CIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].SRC_DST_CIDX =
CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, 0) |
CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0);
// Set EDMA Event PaRAM LINK and BCNTRLD
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].LINK_BCNTRLD =
CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65] & 0xFFFFu) |
CSL_FMK(EDMA3CC_LINK_BCNTRLD_BCNTRLD, NUM_OF_WORD_PER_BUFFER);
//************** Link to parameter set 65 *******************//
// Reset EDMA PaRAM OPT Register
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65].OPT = CSL_EDMA3CC_OPT_RESETVAL;
// Config PaRAM OPT
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65].OPT =
CSL_FMKT(EDMA3CC_OPT_ITCINTEN, DISABLE) |
CSL_FMKT(EDMA3CC_OPT_TCINTEN, ENABLE) |
CSL_FMKT(EDMA3CC_OPT_SYNCDIM, ASYNC) |
CSL_FMK(EDMA3CC_OPT_TCC, EDMA_EVENT1);
// Initialize EDMA Event Src and Dst Addresses
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].SRC = (Uint32)&u32_Xmt_Buffer[0u];
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET1].DST = (Uint32)&mcaspRegs->XBUF11;
// Set EDMA Event PaRAM A,B,C CNT
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65].A_B_CNT =
CSL_FMK(EDMA3CC_A_B_CNT_ACNT, NUM_OF_BYTES_PER_WORD) |
CSL_FMK(EDMA3CC_A_B_CNT_BCNT, NUM_OF_WORD_PER_BUFFER);
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65].CCNT = NUM_OF_BUFFER;
// Set EDMA Event PaRAM SRC/DST BIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65].SRC_DST_BIDX =
CSL_FMK(EDMA3CC_SRC_DST_BIDX_SRCBIDX, NUM_OF_BYTES_PER_WORD) |
CSL_FMK(EDMA3CC_SRC_DST_BIDX_DSTBIDX, 0u);
// Set EDMA Event PaRAM SRC/DST CIDX
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65].SRC_DST_CIDX =
CSL_FMK(EDMA3CC_SRC_DST_CIDX_SRCCIDX, 0) |
CSL_FMK(EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0);
// Set EDMA Event PaRAM LINK and BCNTRLD
edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65].LINK_BCNTRLD =
CSL_FMK(EDMA3CC_LINK_BCNTRLD_LINK, (Uint32)&edma3ccRegs->PARAMSET[EDMA_PARAMETER_SET65] & 0xFFFFu) |
CSL_FMK(EDMA3CC_LINK_BCNTRLD_BCNTRLD, NUM_OF_WORD_PER_BUFFER);
}
- At the end, I add the MAT_EDMA_Init() call into the main() routine just after the CodecInit() function call.
I can see both receive and transmit interrupt counters increasing synchonized but unfortunately nothing into the receive buffer when halting the CPU?
I hope someone can tell me what is missing into my code.
Thanks in advance,
Térence
P.S. I also toggle a GPIO into the EDMA3 interrupt receive and transmit event and I can mesure the period which is the codec sampling period multiplies of the by the buffer size!