Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
21 years ago

DMA transfer length problem

http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/wink.gif

There is a problem in transferring data from SDRAM to my device ( avalon slave device ) .

I use the DMA component provided by SOPC Builder (QuartusII 4.0 + sp1 ) .

My system use the Nios II processor and my soft program write with the HAL .

The problem :

When the transferring data size is bigger than 574720 byte , the program come to a halt situation.

But , when the data size is smaller than 574720 byte , the program work normally.

I have set the width of DMA length register for 30 bits .The program still has the problem .

Is there a idea to solve the problem ? http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/tongue.gif

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I have next assume.

    Maybe your device sets "endofpacket" signal before ending of transferring.

    In this case disable bit REEN or WEEN, it depends on a direction or transferring.

    Other case there is an increment of write address. Disable WCON in this case.

    I hope it helps you http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    My slave device use the basic avalon signals and I don&#39;t use the end of packet .

    I have no experience to disable REEN or WEEN or WCON.

    How to do this work ?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You can use IOWR(DMA_BASE, some_value_of_control_register_dma);

    See description of dma control register in n2cpu_nii51006.pdf.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I still can not solve the problem.

    I read the DMA control register and the length register .

    The results of the two register are normal.

    This is my soft program :

    int main(void)

    {

    printf("Hello from Nios II!\n");

    //perform the DMA test

    unsigned int* data_source ;

    data_source = (unsigned int*) alt_uncached_malloc(258624);

    //fill the source memory

    int m;

    for(m=0 ; m < 258624 ; m++ )

    {

    *(data_source+m)=0x00111111;

    }

    //test the DMA

    alt_dma_txchan tx;

    tx = alt_dma_txchan_open("/dev/dma_0");

    if(tx== NULL)

    {

    printf("\n DMA Test: DMA ERROR ");

    }

    // perform dma transfer

    void* tx_data =(void*) data_source ;

    int rc;

    alt_dma_txchan_ioctl(tx,ALT_DMA_RX_STREAM_ON,(void *)(USER_DEFINED_ME_BASE));

    if((rc=alt_dma_txchan_send(tx,tx_data, (1796*80*4) ,tx_done, NULL ))<0)

    {

    printf("\n Failed to post transmit request ,reason %i",rc);

    exit(1);

    }

    printf("\n Wait for DMA Transfer ... ");

    while(!tx_complete){}

    printf("\n DMA Transaction complete ! ");

    return 0;

    }
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Try to use io.h&#39;s functions IOWR and IORD as next:

    unsigned int *p = (unsigned int*)(SDRAM_BASE + 0xF4240);

    void *pdma = (void*) SD_DMA_BASE;

    //Interrupt function if need

    void isr_dma(void* context, alt_u32 id)

    {

    if ((IORD_ALTERA_AVALON_DMA_STATUS(SD_DMA_BASE))&&ALTERA_AVALON_DMA_STATUS_DONE_MSK) {

    IOWR_ALTERA_AVALON_DMA_STATUS(SD_DMA_BASE, 0);

    IOWR_ALTERA_AVALON_DMA_RADDRESS(SD_DMA_BASE, (int)p);

    IOWR_ALTERA_AVALON_DMA_WADDRESS(SD_DMA_BASE, SD_BASE);

    IOWR_ALTERA_AVALON_DMA_LENGTH(SD_DMA_BASE, 40);

    IOWR_ALTERA_AVALON_DMA_CONTROL(SD_DMA_BASE, 0x02DC);

    }

    }

    int main(void)

    {

    unsigned int *p = (unsigned int*)(SDRAM_BASE + 0xF4240);

    .............

    //Write to memory something (in this case 10 words)

    for (i=0, pattern=0xFFAAFFAA; i<10; i++)

    {

    IOWR_32DIRECT(p+i, 0, pattern);

    }

    //Registration of interrupt function if it need

    alt_irq_register(SD_DMA_IRQ, pdma, isr_dma);

    //Send to some device 10 words

    IOWR_ALTERA_AVALON_DMA_STATUS(SD_DMA_BASE, 0);

    IOWR_ALTERA_AVALON_DMA_RADDRESS(SD_DMA_BASE, (int)p); //Pointer to memory

    IOWR_ALTERA_AVALON_DMA_WADDRESS(SD_DMA_BASE, SD_BASE); //Pointer to your device

    IOWR_ALTERA_AVALON_DMA_LENGTH(SD_DMA_BASE, 40); //Sending 10 words (1 word == 4 bytes)

    IOWR_ALTERA_AVALON_DMA_CONTROL(SD_DMA_BASE, 0x02DC); //See description of dma control register

    ...............

    }