2007-09-18 11:17 PM
2011-05-17 12:46 AM
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, Mark2011-05-17 12:46 AM
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