阅读:2494回复:0
pci9054 DMA 方式 (DWORD)dma.Page[0].pPhysicalAddr为0?
大家帮帮忙,用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"); } |
|