Hi guys,
I'm using omap-l138 LCDK and the only thing I'd like to do is to setup EDMA for audio data transfers.
I have no problems setting McASP in interrupt driven mode, when my handler process a sample by sample. But it's not a clear solution. Please have a look at code I'm using - this is my try for ping-pong EDMA transfers:
This is a way I setup McASP :
void L138_initialise_edma(int32_t fs, int16_t adc_gain, int16_t dac_atten, int8_t input_type)
{
// 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;
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();
// 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)
CSR |= 0x01; // enable interrupts globally
L138_init_LCDK_DIP();
}
And this is how I set EDMA PaRAM to handle serializers 13 and 14 respectively :
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 + 0x234; // 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 + 0x234;
*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 + 0x234;
*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 + 0x2B8; // 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 + 0x2B8; // 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 + 0x2B8; // 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
}
And finally I have the following interrupt handler :
interrupt void interrupt4(void) // interrupt service routine
{
switch(EDMA_3CC_IPR)
{
case 1: // TCC = 0
procBuffer = PING; // process ping
EDMA_3CC_ICR = 0x0001; // clear EDMA3 IPR bit TCC
break;
case 2: // TCC = 1
procBuffer = PONG; // process pong
EDMA_3CC_ICR = 0x0002; // clear EDMA3 IPR bit TCC
break;
default: // may have missed an interrupt
EDMA_3CC_ICR = 0x0003; // clear EDMA3 IPR bits 0 and 1
break;
}
EVTCLR0 = 0x00000100;
buffer_full = 1; // flag EDMA3 transfer
return;
}
But I see that it has never been invoked !
Please help me as I'm running out of ideas what could go wrong -the setup seems to be very easy but nothing works. Maybe my eyes are soaped...
Looking forward for any comments
Kindest Regards,
Dmitry