cancel
Showing results for 
Search instead for 
Did you mean: 

Using EMI with DMA, possible ?

markmcwired9
Associate II
Posted on September 19, 2007 at 08:17

Using EMI with DMA, possible ?

2 REPLIES 2
markmcwired9
Associate II
Posted on May 17, 2011 at 09:46

Hi,

I want to send a buffer of 76800 bytes to the EMI, using DMA in two modes:

1) sending first the data pointer which indicates the byte's address in the buffer, using a counter for the address

2) sending only the data contained in the buffer with no address

Are both tasks workable or impossible to do with the STR912 ?

Does anyone have a working example to show how to do the previous tasks ?

Thank you,

Mark

lodedeschepper
Associate II
Posted on May 17, 2011 at 09:46

Hi,

I succeeded to write to a display (attached on EMI0) by DMA.

 

void DMA_Setup(void)

 

{

 

// Programming a DMA channel: see page 210 in the STR91xF reference manual

 

 

DMA_Channel0->DES = (ulong)LcdDataRegister; // a fixed destination addres = the dataregister of the screen

 

DMA_Channel0->LLI = 0x0; // we do not have a linked list to send (only one item: VideoBuf)

 

 

// MEM -> PER, FLOW: DMA, DMA INT: EN

 

DMA_Channel0->CC = 0x84000000 | GRAPHIC_BYTE_SIZE; // source increment

 

DMA_Channel0->CCNF = 0x0000C880;

 

 

DMA->CNFR = 0x01; // enable channel

 

}

 

 

void TIM_Setup(void)

 

{

 

// TIMER0: DMA

 

TIM0->CR2 = 0x4400; // OC1IE = 1, resolution = fpclk/1 (increment counter register every 10.41ns)

 

TIM0->OC1R = (u16)(0xFFFC + 0x0400); // 10.41 * 0x0400 = 10.6us (theoretical, (practical: 12.2) may not mutch less - else: last byte not on screen) NOW: 25ms for full screenupdate

 

TIM0->CNTR = 0x0; // reset value to 0xFFFC

 

TIM0->CR1 = 0x1000; // OC1 used as DMA source

 

}

 

 

void TIM0_IRQHandler(void)

 

{

 

TIM0->CNTR = 0x0; // reset counter

 

TIM0->SR = 0x0; // clear status

 

DMA->SBRR = 0x4; // not recomended!!!!

 

 

VIC0->VAR = 0x0;

 

VIC1->VAR = 0x0;

 

}

 

 

void DMA_IRQHandler(void)

 

{

 

TIM0->CR1 &= ~0x8000; // stop timer

 

 

DmaFinished = TRUE;

 

 

if (DMA->TCISR & 0x01)

 

DMA->TCICR |= 0x01;

 

if (DMA->EISR & 0x01)

 

DMA->EICR |= 0x01;

 

 

VIC0->VAR = 0x0;

 

VIC1->VAR = 0x0;

 

}

 

When I start writing to the display:

 

void CopyVideoMemoryToLcd(uchar *buf)

 

{

 

DmaFinished = FALSE;

 

UpdateScreen = FALSE;

 

WatchDog();

 

SetGraphicDisplayInAutoDataMode();

 

 

DMA_Channel0->SRC = (ulong)&VideoBuf; // a buffer with the data in the RAM

 

DMA_Channel0->CC &= 0xFFFFF000;

 

DMA_Channel0->CC |= GRAPHIC_BYTE_SIZE; // nmbr of bytes to transfer

 

DMA_Channel0->CCNF |= 1;

 

 

TIM0->CR1 |= 0x8000; // start DMA

 

}

 

This was the only solution that worked out for me...

Hope this will help,

Louis XIV