2009-10-20 08:32:11     How to use DMA descriptor array mode for bf533!

Document created by Aaronwu Employee on Aug 22, 2013
Version 1Show Document
  • View in full screen mode

2009-10-20 08:32:11     How to use DMA descriptor array mode for bf533!

steven O (AFGHANISTAN)

Message: 81480   

 

as the topic , i set the tx dma for sport0 as following , but get a dma error .

 

#define DESCRIPTOR_NUM            5

 

unsigned char tx_buf[DESCRIPTOR_NUM][32] ;

 

typedef struct _DMA_CONFIG {

    unsigned short b_DMA_EN:1;    /* Bit 0 : DMA Enable */

    unsigned short b_WNR:1;        /* Bit 1 : DMA Direction */

    unsigned short b_WDSIZE:2;    /* Bit 2 & 3 : DMA Tranfer Word size */

    unsigned short b_DMA2D:1;    /* Bit 4 : DMA Mode 2D or 1D */

    unsigned short b_RESTART:1;    /* Bit 5 : Retain the FIFO */

    unsigned short b_DI_SEL:1;    /* Bit 6 : Data Interrupt Timing Select */

    unsigned short b_DI_EN:1;    /* Bit 7 : Data Interrupt Enable */

    unsigned short b_NDSIZE:4;    /* Bit 8 to 11 : Flex descriptor Size */

    unsigned short b_FLOW:3;    /* Bit 12 to 14 : FLOW */

} DMA_CONFIG_REG;

 

typedef struct _dmasgarray_t {

    unsigned long start_addr;

    DMA_CONFIG_REG cfg;

    unsigned short x_count;

    short x_modify;

    unsigned short y_count;

    short y_modify;

} dmasgarray_t;

 

dmasgarray_t dmasgarray[DESCRIPTOR_NUM];

 

++++++++++ init part ++++++++++++++++++  

 

for (i = 0; i < DESCRIPTOR_NUM; i++) {

        dmasgarray[i].start_addr = (unsigned int) &tx_buf[i][0];

        dmasgarray[i].cfg.b_DMA_EN = 1;

        dmasgarray[i].cfg.b_WNR = 0;

        dmasgarray[i].cfg.b_WDSIZE = 0;

        dmasgarray[i].cfg.b_DMA2D = 0;

        dmasgarray[i].cfg.b_RESTART = 0;

        dmasgarray[i].cfg.b_DI_SEL = 0;

        dmasgarray[i].cfg.b_DI_EN = 1;

        dmasgarray[i].cfg.b_NDSIZE = 7;

        dmasgarray[i].cfg.b_FLOW = 4;

        dmasgarray[i].x_count = 1;

        dmasgarray[i].x_modify = 1;

        dmasgarray[i].y_count = 0;

        dmasgarray[i].y_modify = 0;

    }

 

    *((volatile unsigned short *) &dev->regs->tcr1) &= ~TSPEN;

    *((volatile unsigned short *) &dev->regs->rcr1) &= ~RSPEN;

    *((volatile unsigned short *) &dev->regs->tcr1) = 0;

    *((volatile unsigned short *) &dev->regs->rcr1) = 0;

    *((volatile unsigned short *) &dev->regs->tcr2) = 0x0007;

    *((volatile unsigned short *) &dev->regs->rcr2) = 0x0007;

 

    *((volatile unsigned short *) &dev->regs->mcmc1) = 0x3000;

    *((volatile unsigned short *) &dev->regs->mcmc2) = 0x1010;

 

    *((volatile unsigned int *) &dev->regs->mtcs0) = 0xffffffff;

    *((volatile unsigned int *) &dev->regs->mtcs1) = 0x00000000;

    *((volatile unsigned int *) &dev->regs->mtcs2) = 0x00000000;

    *((volatile unsigned int *) &dev->regs->mtcs3) = 0x00000000;

 

    *((volatile unsigned int *) &dev->regs->mrcs0) = 0xffffffff;

    *((volatile unsigned int *) &dev->regs->mrcs1) = 0x00000000;

    *((volatile unsigned int *) &dev->regs->mrcs2) = 0x00000000;

    *((volatile unsigned int *) &dev->regs->mrcs3) = 0x00000000;

 

    set_dma_x_count (dev->dma_tx_chan, 32);

    set_dma_x_modify (dev->dma_tx_chan, 1);

    set_dma_y_count (dev->dma_tx_chan, 0);

    set_dma_y_modify (dev->dma_tx_chan, 0);

    set_dma_start_addr (dev->dma_tx_chan, (unsigned int) &tx_buf[0][0]);

    set_dma_config (dev->dma_tx_chan, DMAFLOW_ARRAY | NDSIZE_7 | DI_EN);

 

    set_dma_start_addr (dev->dma_rx_chan, (unsigned int) rx_buf);

    set_dma_x_count (dev->dma_rx_chan, 32);

    set_dma_x_modify (dev->dma_rx_chan, 0);

    set_dma_y_count (dev->dma_rx_chan, 0);

    set_dma_y_modify (dev->dma_rx_chan, 0);

    set_dma_config (dev->dma_rx_chan, RESTART | WNR);

 

    enable_dma (dev->dma_tx_chan);

    enable_dma (dev->dma_rx_chan);

 

    *((volatile unsigned short *) &dev->regs->tcr1) |= TSPEN;

    *((volatile unsigned short *) &dev->regs->rcr1) |= RSPEN;

 

    SSYNC();

 

 

 

Somebody can tell wthere is wrong for the confgiuration ? thanks

QuoteReplyEditDelete

 

 

2009-10-20 11:01:41     Re: How to use DMA descriptor array mode for bf533!

Frank Van Hooft (CANADA)

Message: 81485   

 

Three thoughts.

 

1) I can see where you're creating your array of DMA descriptors, which you call dmasgarray[]. But I don't see where you point the DMA controller to those descriptors.

 

2) Unless you're endlessly looping, usually your last descriptor will want to disable the controller.

 

3) Generally, I do the SSYNC() before enabling the DMA controller. That way you can be confident the various configuration registers are properly setup before enabling the port. That's just my preference and unlikely to be your problem.

QuoteReplyEditDelete

 

 

2009-10-22 03:44:59     Re: How to use DMA descriptor array mode for bf533!

steven O (AFGHANISTAN)

Message: 81580   

 

Sorry , the descriptors will be used in the tx dma channel,. the setting as foloowing :

 

set_dma_start_addr (dev->dma_tx_chan, (unsigned int) &dmasgarray[0]);

 

but also get a dma error.

QuoteReplyEditDelete

 

 

2010-05-18 03:03:54     Re: How to use DMA descriptor array mode for bf533!

Bhanuprakash Reddy (INDIA)

Message: 89492   

 

Some thoughts here.

 

In descriptor array mode, the last descriptor should have the DMA mode as stop mode. But, I don't see that. To verify that, please check where you see the DMA error. Is this DMA error is seen while processing the last descriptor (or) while processing the descriptor before.

 

If it is after processing the last descriptor, you can set the last descriptor mode set to stop mode and see.

QuoteReplyEditDelete

 

 

2010-09-17 08:31:34     Re: How to use DMA descriptor array mode for bf533!

Alexandre Morris (CANADA)

Message: 93556   

 

Hi,

 

I had an issue also configuring DMA using Array descriptor. I surely found one problem in your code. There may be more, but at least here is one:

 

The struct _dmasgarray_t has a size of 14 bytes. When you create an array of _dmasgarray_t, each instance takes 16 bytes in the memory (leaving 2 last bytes unused in order to perform aligned memory reads afterwards).

 

 

 

You then configure the DMA NDSIZE for 14 bytes (NDSIZE_7). The DMA will then increment the CURR_DESC_PTR with 14 bytes, but it should have incremented of 16 bytes in order to perform the fetch correctly.

 

 

 

To solve this problem, I created a char buffer and simply copied _dmasgarray_t to the char buffer using memecpy. This way there is no unused bytes between descriptors.

 

 

 

Hope this helps.

 

Alex

QuoteReplyEditDelete

 

 

2010-09-18 06:31:20     Re: How to use DMA descriptor array mode for bf533!

steven O (AFGHANISTAN)

Message: 93612   

 

Thanks dor your help , i will change it at once.

Attachments

    Outcomes