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.