huangying
驱动牛犊
驱动牛犊
  • 注册日期2011-04-20
  • 最后登录2011-06-03
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望41点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2425回复:0

pci9054 DMA 方式 (DWORD)dma.Page[0].pPhysicalAddr为0?

楼主#
更多 发布于:2011-04-21 10:02
大家帮帮忙,用windriver生成的,在里面添加了DMA操作
void PCI9054_DMAReadWriteBlock(PCI9054_HANDLE hPCI9054, DWORD dwLocalAddr)//,PVOID pBuffer, DWORD dwBytes)
{
FILE *fp,*fp2;
  int j;
   WD_DMA dma;
  DWORD dwStatus;
   DWORD dwDMAMODE;
  DWORD dwLBRD;
  DWORD dwVal;
  DWORD dwINTCSR;
  DWORD dwLAS0BA;
  DWORD dwDMAPADR;
  DWORD dwDMALADR;
  DWORD dwDMASIZ0;
  DWORD dwDMADPR;
  BYTE dwDMACSR;
  BYTE DMALAG;
   HANDLE hWD ;

        hyper mcount1,mcount2;
     double realcount,realtm,realfreq,realcount2,realtm2;
     LARGE_INTEGER mfreq,startfreq,endfreq;

     PCI9054_ADDR addrSpace;
     DWORD addr=0;
     DWORD data;
   PVOID pBuffer = NULL;
hWD = INVALID_HANDLE_VALUE;
 hWD = WD_Open();

    

         dwVal = PCI9054_Readcntrl(hPCI9054);
           dwVal=dwVal | BIT30;
            PCI9054_Writecntrl(hPCI9054, dwVal);
            Sleep(1000);    // 这是从例程上看来的
            dwVal &=  ~(BIT30);
            PCI9054_Writecntrl(hPCI9054, dwVal);
            
            //reload local register
            dwVal=dwVal | BIT29;
          PCI9054_Writecntrl(hPCI9054, dwVal);
             Sleep(100);
             dwVal &=  ~(BIT29);
           PCI9054_Writecntrl(hPCI9054, dwVal);
           ////////////////////////////

    pBuffer=malloc(40000);
  
      BZERO(dma);
    if(pBuffer!=NULL)
         memset(pBuffer, 0, 40000);
     else
        printf("buffer allocate error\n");
    dma.pUserAddr = pBuffer;
    dma.dwBytes = 700;//dwBytes;
    dma.dwOptions = 0;
  dwStatus = WD_DMALock(hPCI9054, &dma);
       if (dma.hDma==0)//(dwStatus)
   {
        sprintf(PCI9054_ErrorString, "cannot lock down buffer. Status 0x%x - %s\n",
            dwStatus, Stat2Str(dwStatus));
      //  return FALSE;
   }

  //////////////////////
    dwDMAMODE= PCI9054_ReadDMAMODE0 (hPCI9054);
                                 //添加DMAMODE控制(burst位(BIT8)使能, (BIT9=0) 模式)
     dwDMAMODE |=BIT1|BIT0;                    //32位总线进行的BLOCK
     dwDMAMODE |= BIT8;                        //Local burst
     dwDMAMODE |= BIT7;                            //bterm enalbe
     dwDMAMODE &= ~(BIT9);                     //采用得块(block)模式
     dwDMAMODE=dwDMAMODE|BIT6;                 //允许ready信号做为输入端
        dwDMAMODE=dwDMAMODE|BIT11;                 //保持LOCAL端地址不变

     PCI9054_WriteDMAMODE0 (hPCI9054, dwDMAMODE);
     //**************************ready输入使能
    dwLBRD= PCI9054_ReadLBRD0 (hPCI9054);
                      

     dwLBRD |= BIT6;             //屏蔽ready使能
//     Trans.Data.Dword &= ~BIT6;             //屏蔽ready使能
     dwLBRD|= BIT24;            //burst使能  
                                          //BIT7为BTERM#输入使能位,默认值为0
                                          //BIT24为BURST使能位,默认值为0;
     dwLBRD |= BIT7;
    PCI9054_WriteLBRD0(hPCI9054, dwLBRD);
    //**************************中断使能  这个在DMA传输中不用,以查询方式代替channel 0中断
    dwINTCSR=PCI9054_Readintcsr(hPCI9054);
    dwINTCSR=dwINTCSR | BIT8 | BIT11 | BIT18;//---PCI Interrupt Enable.
     //dwINTCSR &=~(BIT7)  ;                                //BIT11---Local Interrupt Input Enable.
     PCI9054_Writeintcsr(hPCI9054,dwINTCSR);
////////////////////////////////////////
     dwLAS0BA=0x02;
     PCI9054_WriteLAS0BA (hPCI9054,dwLAS0BA);
     //***************************设置PCI地址
     dwDMAPADR= (DWORD)dma.Page[0].pPhysicalAddr;//把获取的地址赋给PCI地址     PCI9054_WriteDMAPADR0(hPCI9054,dwDMAPADR);
//**************************设置LOCAL地址
    //dwLocalAddr= 0x14;//对应FPGA中的地址      
    dwDMALADR = dwLocalAddr;
     PCI9054_WriteDMALADR0(hPCI9054,dwDMALADR);
     //*****************************************************************
     //读取地址

     //********************************************************************
     //**************************设置传输的字节数
                            //例程上SIZE是Page[0].dwBytes,即申请多少个字节内存,即为传输字节数
     dwDMASIZ0=700;//dma.Page[0].dwBytes;
     PCI9054_WriteDMASIZ0 (hPCI9054,  dwDMASIZ0);
//***************************设置P9054_DMADPR0(DMA传输方向)
     dwDMADPR=0X00000009;
     PCI9054_WriteDMADPR0 ( hPCI9054, dwDMADPR);

     ////******************************************
            QueryPerformanceFrequency(&mfreq);  //获得时钟频率
     realfreq=(double)mfreq.QuadPart;

    QueryPerformanceCounter(&startfreq);


     //**********************开始进行DMA传输
    dwDMACSR |=(BYTE)(BIT1|BIT0|BIT3);
 //BIT1=1:开始DMA数据传输
                                        //BIT0=1:通道0被选通
  PCI9054_WriteDMACSR ( hPCI9054, dwDMACSR);

     //**********查询传输结束标志位(BIT4?=1)
    

     do
     {    
     DMALAG=PCI9054_ReadDMACSR (hPCI9054);
     }
     //while((DMALAG & 00010011)==00000011);//表达式为真的时候返回do{}继续执行
     while((DMALAG &(BYTE)(BIT4))!=(BYTE)BIT4);
    
        
      printf("%x %x %x\n",*((int*)dma.pUserAddr),*((int*)dma.pUserAddr+1),*((int*)dma.pUserAddr+2));
    
 QueryPerformanceCounter(&endfreq);

    fp =fopen("data.txt","w");
    fp2=fopen("time.txt","w");
    for(j=0;j<500;j++)
    {

            fprintf(fp,"%d\n",*((int*)dma.pUserAddr+j));
        
        }
    


    realcount2=(double)(endfreq.QuadPart-startfreq.QuadPart);
     realtm2=realcount2/realfreq;
    fprintf(fp2,"%f ",realtm2);

////////////////////////////////////////////////写数据
///////////////////////////////////////////////
         free(pBuffer);
             fclose(fp);
     fclose(fp2);
    WD_DMAUnlock(hWD, &dma);

        printf("\n");
        }

游客

返回顶部