gcy2000
驱动牛犊
驱动牛犊
  • 注册日期2002-03-22
  • 最后登录2005-02-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3402回复:13

ISP1581的DMA传输编程。

楼主#
更多 发布于:2003-06-23 23:42
最近我购买了一块周立功公司的ISP1581开发板,
但直接连接上去速度不高。
所以我想使用DMA传输,希望可以获得更高的传输速度。

我选用的是GDMA从机模式。
按照时序外接了一块FPGA作为硬件电路。
但在软件编程上碰到了一些问题,不知如何解决,
希望各位大侠指点,不胜感激。

我的理解:
   初始化时设置DMA,
   当端口中断发生时,处理中断,
   在数据处理循环中,发送DMA读写命令,
   等待DMA传输完成。  

具体代码如下:
在void Init_Main(void)里面增加调用DMA初始化函数DMA_Init();


void DMA_Init(void)
{

   //issue DMA reset command to ISP1581
   D14_Cntrl_Reg.D14_DMA_COMMAND = DMA_RESET;
   //初始化,这句没有写错吧。

   D14_Cntrl_Reg.D14_GDMA_CONFIG.VALUE = 0x8000;
   //不要计数模式,不知需不需要计数器区别大不大?


   //initialize the config and hardware register to
   //set ISP1581 to generic DMA mode
   D14_Cntrl_Reg.D14_GDMA_CONFIG.BITS.CNTENA = 0;
   D14_Cntrl_Reg.D14_GDMA_CONFIG.BITS.WIDTH = 1;
   D14_Cntrl_Reg.D14_UDMA_CONFIG.BITS.IGNORE_IORDY = 0;


   D14_Cntrl_Reg.D14_UDMA_CONFIG.BITS.PIO_MODE = 0;
   D14_Cntrl_Reg.D14_UDMA_CONFIG.BITS.UDMA_MODE = 0;

   D14_Cntrl_Reg.D14_DMA_HARDWARE.BITS.ENDIAN = 0;
   D14_Cntrl_Reg.D14_DMA_HARDWARE.BITS.EOT_POL = 1;
   D14_Cntrl_Reg.D14_DMA_HARDWARE.BITS.ACK_POL = 0;
   D14_Cntrl_Reg.D14_DMA_HARDWARE.BITS.DREQ_POL = 1;
   D14_Cntrl_Reg.D14_DMA_HARDWARE.BITS.WRITE_POL = 0;
   D14_Cntrl_Reg.D14_DMA_HARDWARE.BITS.READ_POL = 0;
  
   //set to DMA endpoint 1
   //set to Endpoint Index to 2
   //this is to prevent the endpoint index pointing to the same endpoint          
   D14_Cntrl_Reg.D14_DMA_ENDPOINT = 4;        
   //请教各位大侠,这个DMA端点应该怎么设置,它跟端点有什么对应关系,端点应该对应那个缓冲区呢,被设置为DMA的端点,在Init_Endpoint(void)里面应该怎么设置呢,DMA端点是否只能设置一个呢?设置以后还需要进行其他配置吗?

   D14_Cntrl_Reg.D14_ENDPT_INDEX = 2;


    //enable DMA interrupt
    D14_Cntrl_Reg.D14_DMA_INT_ENABLE.VALUE = 0x000D;

   //initialize internal variables            
    Kernel_Flag.BITS.Out_Reset_Done = 0;
    Kernel_Flag.BITS.In_Reset_Done = 0;
    Kernel_Flag.BITS.MPIO_Out_Reset_Done = 0;
    Kernel_Flag.BITS.MPIO_In_Reset_Done = 0;
}
//以上这段代码改变自从P公司下载的代码。
不知DMA的初始化是否已经足够,还差什么,或者那些地方写错了?

-----------------------------
   DMA初始化后就进行传输处理了,我的理解是DMA端点对应普通的端点,在PC端对端口进行对写,就是对DMA端口进行读写了,不知这样的
理解对不对。所以我使用了D14_DMA_ENDPOINT = 4;PC程序不断想端点4
发送数据,我在中断处理程序void Int_Ext_0(void) interrupt 0 using 1里面增加代码:

    //DMA  
    DMA_Int_Flag.VALUE |= D14_Cntrl_Reg.D14_DMA_INT.VALUE;
    D14_Cntrl_Reg.D14_DMA_INT.VALUE = DMA_Int_Flag.VALUE;

    //这样写对吗?

然后我在void DMA_Mode(Data)里面进行数据处理,我测试的代码只处理PC输出数据。    

    if(Data)
    {
        //read
        do
        {
            //Check for Out Token ACK interrupt
            while(!USB_Int_Flag.BITS.EP2RX)
            {
                if(USB_Int_Flag.BITS.SUSP || Kernel_Flag.BITS.Bus_Reset || USB_Int_Flag.BITS.EP0SETUP)
                    break;
            }
            EA_DISABLE;
            USB_Int_Flag.BITS.EP2RX = 0;
            EA_ENABLE;

  当检测到中断的时候,我的理解是这个端点写数据应该可以触发这个中断,而这个端点已经被设置成DMA端点。所以在这后面写处理代码:

         D14_Cntrl_Reg.D14_DMA_ENDPOINT = 4;
                  //指向DMA端点

            //Read in FIFO data
            if (bytecount > PIO_Count)
            {
                Datcount = PIO_Count;
            }
            else
            {
                Datcount = bytecount;
            }


         D14_Cntrl_Reg.D14_DMA_COMMAND = GDMA_Read_Command;    //开始传输,不知是否可以发指令,是否是这个指令。


         //等待DMA处理完成
      while(!DMA_Int_Flag.BITS.DMA_DONE && !DMA_Int_Flag.BITS.INT_EOT)
        {
          //Exit function when bus reset or suspend detected
          if(USB_Int_Flag.BITS.SUSP || Kernel_Flag.BITS.Bus_Reset ||
            USB_Int_Flag.BITS.EP0SETUP)
          {  
            D14_Cntrl_Reg.D14_DMA_COMMAND = DMA_RESET;
            DMA_Init();
            break;
          }                        
        }            
          
         //完成
      DMA_Int_Flag.BITS.DMA_DONE = 0;
        DMA_Int_Flag.BITS.INT_EOT = 0;


        //以下是其它代码

        bytecount -= Datcount;
        }while(bytecount);
    }
    else
    {  

          ……

        
但是在测试过程中,程序并没有运行起来,DREQ脚没有检测到高电平,
不知程序出错在那里,是初始化,还是中断处理,还是DMA控制处理。
还是DMA传输原理不是这样的。希望得到各位高手的指点。谢谢。
plasma
驱动小牛
驱动小牛
  • 注册日期2002-02-19
  • 最后登录2008-02-27
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-06-24 11:32
祝贺你购买了开发板
建议你用断开模式
sod123
驱动牛犊
驱动牛犊
  • 注册日期2002-05-16
  • 最后登录2003-06-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-06-24 11:38
周立功的那个ISP1581开发板是没有DMA功能的,USB2.0如果不能实现DMA传输的话其实是没有什么意义的。
  
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-06-24 12:41
我用ISP1581的通用处理器模式最高的做到4.5M/s,不知道你能做到多高。我没用过dma,也没仔细深究过。
gcy2000
驱动牛犊
驱动牛犊
  • 注册日期2002-03-22
  • 最后登录2005-02-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-06-24 23:23
板子直接使用才用80K,
修改程序后可以达到400K,
不处理数据直接清空缓冲区可以达到4.5M,不过这样没有什么意义了。
板上单片机为PHILIPS P89C61x2 。


plasma:希望可以讲详细点,编程的关键点在哪里阿。

jinghuiren:你用什么单片机阿,可以达到这么高速度。

sod123:改板有输出脚,理论上可以外接DMA硬件线路的,
        我外接了一块MAX7128,并且按照时序图编写了一个逻辑,
        不知这样做行不行得通。


还请各位大侠指点赐教,不胜感激。^_^

jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-06-25 10:36
我用的是40M的DSP,好像是ADSP21062,别名叫SHARC。
我用TMS3205402平均速度才能达到3M/s
用tms320f206平均速度能达到2M/s。
速度测试是,用dsp来填充端点缓冲区,由app读取数据,然后存储到文件中,整个过程的传输速度。

如果直接清空端点的话那当然会更快,可是这是无意义的,因此我根本就没有试过。
xxg
xxg
驱动小牛
驱动小牛
  • 注册日期2002-02-28
  • 最后登录2005-12-12
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-06-25 10:54
DMA的实现牵涉到两个地方,一是控制器对ISP1581的设置,包括DMA的模式选择,传输长度,BUFFER大小等;二是外部电路的配合,就是实现DMA读写的控制与时序。
   DMA传输时,控制CPU是不参与的,所以这时的传输速率就取决于外部DMA控制电路的设计,以及PC机驱动程序的设计。PC机这边我们可以把缓存开的大一些,每次读写更多的数据,这样效率也就自然提高了;DMA控制电路的设计,主要是在满足ISP1581最小读写周期的前提下,使读写周期尽量小,这样也就提高了传输速率。
   如果没有DMA传输,那么控制CPU就很可能成为一个瓶颈了。
   其实DMA控制电路的设计并不麻烦,时序比较简单,我们的开发板上是用CPLD来实现的,几十行的代码就搞定了。
gcy2000
驱动牛犊
驱动牛犊
  • 注册日期2002-03-22
  • 最后登录2005-02-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-06-25 23:09
祝贺你购买了开发板
建议你用断开模式




周立功的开发板就是断开总线模式的啊。
那还有什么好的方法。

gcy2000
驱动牛犊
驱动牛犊
  • 注册日期2002-03-22
  • 最后登录2005-02-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-06-25 23:12
我用的是40M的DSP,好像是ADSP21062,别名叫SHARC。
我用TMS3205402平均速度才能达到3M/s
用tms320f206平均速度能达到2M/s。
速度测试是,用dsp来填充端点缓冲区,由app读取数据,然后存储到文件中,整个过程的传输速度。

如果直接清空端点的话那当然会更快,可是这是无意义的,因此我根本就没有试过。


谢谢jinghuiren兄指点,
呵呵,没办法,我连DSP都还没有见过。
看来还需修炼多几年了,努力中。。。。


gcy2000
驱动牛犊
驱动牛犊
  • 注册日期2002-03-22
  • 最后登录2005-02-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-06-25 23:17
DMA的实现牵涉到两个地方,一是控制器对ISP1581的设置,包括DMA的模式选择,传输长度,BUFFER大小等;二是外部电路的配合,就是实现DMA读写的控制与时序。
   DMA传输时,控制CPU是不参与的,所以这时的传输速率就取决于外部DMA控制电路的设计,以及PC机驱动程序的设计。PC机这边我们可以把缓存开的大一些,每次读写更多的数据,这样效率也就自然提高了;DMA控制电路的设计,主要是在满足ISP1581最小读写周期的前提下,使读写周期尽量小,这样也就提高了传输速率。
   如果没有DMA传输,那么控制CPU就很可能成为一个瓶颈了。
   其实DMA控制电路的设计并不麻烦,时序比较简单,我们的开发板上是用CPLD来实现的,几十行的代码就搞定了。



XXG兄啊,多谢指点。
你提到的问题我基本都留意了,但还是无法成功,
我已经对DMA的相关寄存器进行了初始化,
不知哪里设置得不对,还希望给予指点。

另外,你提到你们的开发板,
我想问一下你们的开发板的实际速度达到多少,
是通过什么方法测量出来的速度。谢谢。


lily311
驱动小牛
驱动小牛
  • 注册日期2002-08-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望26点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-06-14 18:03
我的MDMA也动不了。 :(
我是这样启动dma的:
1)Set DMA Endpoint 04
2)Set DMA Transfer Counter
3)Set MDMA Read Command
然后理论上就应该开始了。
可是没有看到数据呀?
darydl
驱动小牛
驱动小牛
  • 注册日期2003-06-29
  • 最后登录2017-05-02
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2004-06-14 20:23
hi
me too
lily311
驱动小牛
驱动小牛
  • 注册日期2002-08-15
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望26点
  • 贡献值0点
  • 好评度23点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-06-15 10:37
可以启动了。
数据是从设备上传到主机的,所以应该用endpt 05
Ivan78
驱动牛犊
驱动牛犊
  • 注册日期2004-12-01
  • 最后登录2005-09-27
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-01-29 09:16
lily311还在吗?有问题要请教……
你启动DMA的步骤里面不用设置LBA地址的吗?
还有,如果DMA成功启动把数据传到enpt 5,我能读出来吗?
游客

返回顶部