Skip to main content
Visitor II
September 19, 2007
Question

Using EMI with DMA, possible ?

  • September 19, 2007
  • 2 replies
  • 757 views
Posted on September 19, 2007 at 08:17

Using EMI with DMA, possible ?

    This topic has been closed for replies.

    2 replies

    Visitor II
    May 17, 2011
    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

    Visitor II
    May 17, 2011
    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