Hi all,
I'd like to do periodic DMA transmission from DARAM to EMIF at 1kHz with the C5509A. Therefore I use a timer and I perform a DMA_start inside of the timer's ISR. When I look at the signals at the EMIF, it seems that very often the DMA doesn't start and that this happens very irregularly. Just to complete the picture: if i symbolize successful transmissions with a T and unsuccessful ones with a X, I get a random pattern e.g. like T T X T T T T T T X T X T X T T T X T X T T T T X etc. with the T's and X's "spaced at 1kHz" (i.e. if I have and X, there's no output).
If I set a breakpoint in the timer ISR, I see a signal every time I continue. I thought it first was due to scope settings but I'm pretty sure that the settings are adapted.
Is there something am I missing or I didn't configure correctly? Here are some snippets from my code :
void main (void) {
volatile Bool first = TRUE;
c5509a_dspclk_init(12,144,0); // PLL
c5509a_intc_init(); // CSL/interrupts
c5509a_emif_init(); // EMIF
c5509a_dma_init(); // DMA
c5509a_timer_init(); // Timer
while (1) {
if (first) {
first = FALSE;
TIMER_start(mhTimer0); // DMA element-by-element transfer is sync to timer0 => 8MHz
TIMER_start(mhTimer1); // DMA_start is sync to timer1 => 1kHz
}
}
}
void c5509a_intc_init() {
/* Initialize CSL library - This is REQUIRED !!! */
CSL_init();
/* Set IVPD/IVPH to start of interrupt vector table */
IRQ_setVecs((Uint32)(&RESET_VEC));
}
void c5509a_dma_init(Uint16 inclk, Uint16 outclk, Uint16 plldiv)
{
// DMA configuration ... => DMA interrupts are turned off
/* Open DMA channels 4 & 5 and set regs to power on defaults */
hDmaRcv = DMA_open(DMA_CHA4,DMA_OPEN_RESET);
hDmaXmt = DMA_open(DMA_CHA5,DMA_OPEN_RESET);
// Get interrupt event associated with DMA receive and transmit
xmtEventId = DMA_getEventId(hDmaXmt);
rcvEventId = DMA_getEventId(hDmaRcv);
// Temporarily disable interrupts and clear any pending interrupts
old_intm = IRQ_globalDisable();
// Clear any pending interrupts for DMA channels
IRQ_clear(xmtEventId);
IRQ_clear(rcvEventId);
// Enable DMA interrupt in IER register
IRQ_enable(xmtEventId);
IRQ_enable(rcvEventId);
// Place DMA interrupt service addresses at associate vector
IRQ_plug(xmtEventId,&dmaXmtIsr);
IRQ_plug(rcvEventId,&dmaRcvIsr);
// Write values from configuration structure to DMA control regs
DMA_config(hDmaRcv,&dmaRcvConfig);
DMA_config(hDmaXmt,&dmaXmtConfig);
// Restore status of global interrupt enable flag
IRQ_globalRestore(old_intm);
}
void c5509a_timer_init() {
/* Open Timer 0, set registers to power on defaults */
mhTimer0 = TIMER_open(TIMER_DEV0, TIMER_OPEN_RESET);
/* Write configuration structure values to Timer control regs */
TIMER_config(mhTimer0, &timer0_cfg);
/* Open Timer 1, set registers to power on defaults */
mhTimer1 = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET);
/* Write configuration structure values to Timer control regs */
TIMER_config(mhTimer1, &timer1_cfg);
/* Get Event Id associated with Timer 0/1, for use with */
/* CSL interrupt enable functions. */
tim0EventId = TIMER_getEventId(mhTimer0);
tim1EventId = TIMER_getEventId(mhTimer1);
/* Temporarily disable interrupts and clear any pending interrupts */
old_intm = IRQ_globalDisable();
/* Clear any pending Timer interrupts */
IRQ_clear(tim0EventId);
IRQ_clear(tim1EventId);
/* Place interrupt service routine address at */
/* associated vector location */
IRQ_plug(tim0EventId,&timer0Isr);
IRQ_plug(tim1EventId,&timer1Isr);
/* Enable Timer interrupt */
//IRQ_enable(timEventId);
IRQ_enable(tim1EventId);
/* Restore status of global interrupt enable flag */
IRQ_globalRestore(old_intm);
IRQ_globalEnable();
}
interrupt void timer1Isr(void) {
// restart DMA
DMA_start(hDmaXmt);
}
For testing purpose I only transmit 8 bytes per DMA transfer, so this should be done in far less than 1 ms!
Nothing more than that. I don't see where the problem is.
I appreciate every help on this.
Best regards,
Andreas