Tool/software:
Hi,
I've been trying to use DMA for large data transfers at high speed and i came accross an issue when using DMA's interrupts.
My program is trying to send a buffer (9638 bytes) to the eUSCI A0 module configured in uart mode. The uart configuration in itself
is working as i'm able to send data through it to my PC with a serial cable.
I made two simple test functions to send the same buffer with DMA, one function uses flag polling and the other uses DMA's interrupts. Here is the code :
static void dma_send(const uint8_t *buf, size_t len)
{
DMACTL0 = DMA0TSEL_17; // UCA0TXIFG
DMA0SA = (uint32_t)buf;
DMA0DA = (uint32_t)(&UCA0TXBUF);
DMA0SZ = len;
DMA0CTL = (
DMADT_0 // single transfer mode
| DMADSTINCR_0 // destination addess fixed
| DMASRCINCR_3 // source address incremented
| DMADSTBYTE
| DMASRCBYTE
| DMALEVEL // trigger type: level detection
);
hw_toggle_led1();
DMA0CTL |= DMAEN;
while (!(DMA0CTL & DMAIFG));
hw_toggle_led1();
}
PLACE_INTERRUPT(isr_dma)
#pragma vector=DMA_VECTOR
static void __interrupt isr_dma(void)
{
__low_power_mode_off_on_exit();
switch (__even_in_range(DMAIV, DMAIV_DMA0IFG)) {
case DMAIV_DMA0IFG: {
DMA0CTL &= ~DMAIE;
break;
}
}
}
static void dma_send_irq(const uint8_t *buf, size_t len)
{
DMACTL0 = DMA0TSEL_17; // UCA0TXIFG
DMA0SA = (uint32_t)buf;
DMA0DA = (uint32_t)(&UCA0TXBUF);
DMA0SZ = len;
DMA0CTL = (
DMADT_0 // single transfer mode
| DMADSTINCR_0 // destination address fixed
| DMASRCINCR_3 // source address incremented
| DMADSTBYTE
| DMASRCBYTE
| DMALEVEL // trigger type: level detection
| DMAIE // enable interrupts
);
hw_toggle_led1();
DMA0CTL |= DMAEN;
__low_power_mode_0();
hw_toggle_led1();
}