Nios II DMA: 多次发起

转载:http://blog.ednchina.com/conan85420/431119/message.aspx

本程序首先输出目标地址空间的数据,然后连续发起两次DMA传输,最后再次输出DMA传输后目标地址空间的数据。

第二次发起可以在第一次DMA传输没有结束的情况下开始,不过要注意,两次的目标地址不能有重叠部分,否则发起会失败。

 

#include <stdio.h>
#include <stdlib.h>
#include "unistd.h"
#include "string.h"
#include "io.h"
#include "system.h"
#include "sys/alt_dma.h"
#include "sys/alt_cache.h"
#include "sys/alt_irq.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "altera_avalon_dma_regs.h"
#include "altera_avalon_uart_regs.h"

volatile char chr[20] = {1,2,3,4,6,5,7,8,9,10,
                        11,12,13,14,15,16,17,18,19,20} ;//数据源
volatile char chr2[20] = {1,2,3,4,6,5,7,8,9,10,
                        11,12,13,14,15,16,17,18,19,20} ;//数据源                       
static volatile int rx_done = 0;

static void done (void* handle, void* data)
{
    rx_done++;
    IOWR(LED_BASE,0, rx_done);//LED显示rx_done的变化
}

static void done2 (void* handle, void* data)
{
    rx_done++;
    IOWR(LED_BASE,0, rx_done);//LED显示rx_done的变化
}

int main (int argc, char* argv[], char* envp[])
{
    alt_u8 i="0";
    int rc;
    alt_dma_txchan txchan;
    alt_dma_rxchan rxchan;
    void * tx_data = (void*) chr;
    void * tx_data2 = (void*) chr2;
    char *rx = (char *)ONCHIP_RAM_BASE;
    char *rx2 = (char *)ONCHIP_RAM_BASE+20;
    void* rx_buffer = (void*) ONCHIP_RAM_BASE;//0x00801000; /* pointer to rx buffer */
    void* rx_buffer2 = (void*) ONCHIP_RAM_BASE+20;
    IOWR(LED_BASE,0, 0);
    for(i =0;i<20;i++)  //串口输出目标地址空间的数据
    {
        printf ("%c",*(rx+i));
    }
    printf ("\n");

    for(i =0;i<20;i++)  //串口输出目标地址空间的数据
    {
        printf ("%c",*(rx2+i));
    }
    printf ("\n");

    printf ("Let's begin!\n");
    alt_dcache_flush_all();//清空数据缓存
    if ((txchan = alt_dma_txchan_open("/dev/DMA0")) == NULL)
    {
        printf ("Failed to open transmit channel\n");
    }

    if ((rxchan = alt_dma_rxchan_open("/dev/DMA0")) == NULL)
    {
        printf ("Failed to open receive channel\n");
    }

    rc = alt_dma_rxchan_depth(rxchan);//获取最大可接受请求数量
    printf ("rxchan_depth = %d\n",rc);
    rc = alt_dma_txchan_space(txchan);//获取最大发送请求数目
    printf ("txchan_depth = %d\n",rc);
/******************第一次DMA请求******************/
    if ((rc = alt_dma_txchan_send (    txchan,
                                    tx_data,
                                    20,
                                    NULL,
                                    NULL)) < 0)
    {
        printf ("Failed to post transmit request1, reason = %i\n", rc);
    }
    if ((rc = alt_dma_rxchan_prepare (    rxchan,
                                        rx_buffer,
                                        20,
                                        done,
                                        NULL)) < 0)
    {
        printf ("Failed to post read request1, reason = %i\n", rc);
    }

/******************第二次DMA请求******************/
    if ((rc = alt_dma_txchan_send (    txchan,
                                    tx_data2,
                                    20,
                                    NULL,
                                    NULL)) < 0)
    {
        printf ("Failed to post transmit request2, reason = %i\n", rc);
    }
    if ((rc = alt_dma_rxchan_prepare (    rxchan,
                                        rx_buffer2,
                                        20,
                                        done2,
                                        NULL)) < 0)
    {
        printf ("Failed to post read request2, reason = %i\n", rc);
    }
    while (rx_done<2);//等待两次发送完毕
    printf ("Transfer successful!\n");

    for(i =0;i<20;i++)
    {
        printf ("%c",*(rx+i)); //再次输出dma传输后目标地址的数据
    }
    printf ("\n");

    for(i =0;i<20;i++)
    {
       printf ("%c",*(rx2+i)); //再次输出dma传输后目标地址的数据
    }
    printf ("\n"); 

    while(1);
    return 0;
}

posted on 2011-04-06 20:10  CrazyBingo  阅读(1461)  评论(0编辑  收藏  举报

导航