📄 da_dma.c
字号:
/* FILE NAME: da_dma.c FILE DESCRIPTION: D/A conversion demonstrating changing the wave form as the program runs. Each DMA channel uses a buffer of up to 64 kilobytes. During each DMA, data from a subbuffer equal in size to 1/2 the FIFO size is copied to the FIFO and used for wave generation. After copying, the driver sets a flag in the control buffer. Every subbuffer has its own 1-byte flag. The application program must check flags and replace subbuffers marked as copied with new data and then set flag in control buffer to indicate the buffer is ready. If conversion is occurring too quickly and the FIFO empties before new data copied, the driver will stop conversion and set a FIFO empty flag in the control buffer. Maximum conversion rate depends on computer system used. General programming sequence: 1. Open the device for reading and writing (fopen). 2. Setup DMA and obtain DMA buffer (setDA_DMA7520). 3. Obtain control buffer (get_control_buf7520). 4. Load DMA buffer with initial values (using memcpy or just "="). Then load the buffer to the driver (setWriteBuffer7520) which will load initial values into the FIFO. 5. Setup DA converter (SetupDAC7520). 6. Setup DA clock - it will start conversion (SetDACRate7520). 7. Check the control buffer flags and renew data in the DMA buffer. Set buffer ready flag when new data is loaded. 8. Unset DMA when program is finished (UnSetDMAMode7520). 9. Close the device. PROJECT NAME: Linux DM7520 Driver, Library, and Example Programs PROJECT VERSION: (Defined in README.TXT) Copyright 2004 RTD Embedded Technologies, Inc. All Rights Reserved.*/#include <stdio.h> //printf#include <stdlib.h> //exit#include <errno.h> //errno#include <math.h> //sin#include "dm7520_library.h"int DABUFFERSIZE; // Equals to 1/2 FIFO. Will be set during the program initializationint16_t *dabuffer1; //addres of buffer 1int16_t *dabuffer2; //address of buffer 2
char *contBuf; //address of control buffer//load buffer with upper part of square signalvoid setLowerBufSq(int16_t *buffer, int j) { int i; int sample; for (i=0; i<DABUFFERSIZE;i++){ sample=-j*20; buffer[i]=sample<<3; }}//load buffer with lower part of square signalvoid setUpperBufSq(int16_t *buffer, int j) { int i; int sample; for (i=0;i<DABUFFERSIZE;i++) { sample = j*20; buffer[i]=sample<<3; }}//load buffer with lower part of sine wavevoid setLowerBufSin(int16_t *buffer, int j) { int i; int sample; float fok, val; for (i=0; i<DABUFFERSIZE;i++){
fok=(float)i*(M_PI/DABUFFERSIZE); val=sin(fok); sample=j*20*val; buffer[i]=sample<<3; }}//load buffer with upper part of sine wavevoid setUpperBufSin(int16_t *buffer, int j) { int i; int sample; float fok, val; for (i=0;i<DABUFFERSIZE;i++) { fok=(float)i*(M_PI/DABUFFERSIZE); val=-sin(fok); sample=j*20*val; buffer[i]=sample<<3; }}//=====================================================================int main(int argc, char * argv[]){ FILE * infile; int i1=0; //index int i2=0;
int fifosize;
int j=0; //index int ret; // return code int devno; // device handler
int bi1 = 0; //buffer1 index
int bi2 = 0; //buffer2 index
int bi1num; //number of indexes int bi2num; //number of indexes if (argc<2) {fprintf(stderr,"Usage: %s <device>\n",argv[0]);exit(1);} if (NULL==(infile=fopen(argv[1],"r+"))) //open device. Enough to open for reading only { fprintf(stderr,"Cannot open file, errno=%d\n",errno); perror("Error is"); exit(2); } devno = fileno(infile); // get device handler InitBoard7520(devno); // Initialize the device ret = dm7520_getFifoSize(devno,&fifosize); printf ("FIFOSIZE=%d ret=%d\n", fifosize, ret); DABUFFERSIZE = fifosize/2;ret = DACClockFreeRun7520(devno,1); //DAC start/stop modeif (ret) printf("free run ret=%d\n", ret);ret = DACClockStopSelect7520(devno, 7); //set DAC clock stop to softwareif (ret) printf("dac stop select ret=%d\n", ret);ret = DACClockStartSelect7520(devno, 7); //set DAC clock start to softwareif (ret) printf("dacstartselect ret=%d\n", ret);ret = SetDACRate7520(devno, 50000); //start da coversion at 100 kHzif (ret) printf("setdac rate ret=%d\n", ret); ret = DACClockStop7520(devno); if (ret) printf("stop dac ret=%d\n", ret);if (SetupDAC7520(devno,DM7520_WRITE_DA1,AOUT_BIP5,DAC_CYCLE_SINGLE,DAC_START_DAC_CLK)) { printf ("could not setup DA1\n"); goto label1; // set up DAC1}if (SetupDAC7520(devno,DM7520_WRITE_DA2,AOUT_BIP5,DAC_CYCLE_SINGLE,DAC_START_DAC_CLK)){ printf ("could not setup DA2\n"); goto label1; //set up DAC2} //set DMA channel 0 and get the buffer1 ret = setDA_DMA7520(devno, DM7520_WRITE_DA1,0, &dabuffer1, DMATEMPSIZE); //size in bytes if (ret) { printf("setDMA0 error=%X\n", ret); goto label1; }//set DMA channel 1 and get the buffer2 ret = setDA_DMA7520(devno, DM7520_WRITE_DA2, 1, &dabuffer2, DMATEMPSIZE); if (ret) { printf("setDMA error1=%X\n", ret); goto label1; }//get control buffer ret = get_control_buf7520(devno, &contBuf);
if (ret) {
printf(" error getting control buf=%X\n", ret);
goto label1;
}
bi1num = DMATEMPSIZE/(DABUFFERSIZE*2); // divide DMA buffer size by size of 1/2 FIFO in bytes
bi2num = DMATEMPSIZE/(DABUFFERSIZE*2); // divide DMA buffer size by size of 1/2 FIFO in bytes// initialize the DMA buffer of wave form 1
for (bi1=0; bi1<bi1num; bi1++) {
i1++;
if (i1>100) j = 200-i1;
else j = i1; if (1==i1%2){
setLowerBufSq(dabuffer1+DABUFFERSIZE*bi1, j);
}
else {
setUpperBufSq(dabuffer1+DABUFFERSIZE*bi1, j);
}
*(contBuf+bi1) = BUFFER_READY;
}
// initialize the DMA buffer of wave form 2
for (bi2=0; bi2<bi2num; bi2++) {
i2++;
if (i2>100) j = 200-i2;
else j = i2;
if (1==i2%2){
setLowerBufSin(dabuffer2+DABUFFERSIZE*bi2, j);
}
else {
setUpperBufSin(dabuffer2+DABUFFERSIZE*bi2, j);
}
*(contBuf+CONTROLFLAGSIZE+bi2) = BUFFER_READY;
}// load data to DAC1 FIFO and initialize control buffer flagsif (setWriteBuffer7520(devno, DM7520_WRITE_DA1, 0, DMATEMPSIZE) ) { // size in bytes printf("Error setting buffer for DMA0\n"); goto label1;}// load data to DAC2 FIFO and initialize control buffer flagsif (setWriteBuffer7520(devno, DM7520_WRITE_DA2, 1, DMATEMPSIZE) ){ // size in bytes printf("Error setting buffer for DMA1\n"); goto label1;} DACClockStart7520(devno); //Start DA conversion while ((i1<200)&&(i2<200)) { if (bi1>=bi1num)bi1 = 0;
if (bi2>=bi2num)bi2 = 0;
if ((BUFFER_NOT_READY==*(contBuf+bi1))||(BUFFER_NOT_READY==*(contBuf+CONTROLFLAGSIZE+bi2))){ printf("Program stopped because fifo got empty because of too high convertion rate - buffer not ready\n"); goto label1; } if ((FIFO_EMPTY==*(contBuf+bi1))||(FIFO_EMPTY==*(contBuf+CONTROLFLAGSIZE+bi2))){ printf("Program stopped because could not get copied due to too high convertion rate - FIFO Empty\n"); goto label1; } if (BUFFER_COPIED==*(contBuf+bi1)) { //DMA done need to update the buffer1 i1++;
if (i1>100) j = 200-i1;
else j = i1; if (1==i1%2){ setLowerBufSq(dabuffer1+DABUFFERSIZE*bi1, j); } else { setUpperBufSq(dabuffer1+DABUFFERSIZE*bi1, j); } *(contBuf+bi1) = BUFFER_READY;
bi1++; } if (BUFFER_COPIED==*(contBuf+CONTROLFLAGSIZE+bi2)) { //DMA done need to update the buffer2
i2++;
// printf("i1=%d\n",i1);
if (i2>100) j = 200-i2;
else j = i2;
if (1==i2%2){ //lower buffer DMA done, need to update lower buffer1
setLowerBufSin(dabuffer2+DABUFFERSIZE*bi2, j);
}
else {
setUpperBufSin(dabuffer2+DABUFFERSIZE*bi2, j); //upper buffer DMA done, need to update upper buffer1
}
*(contBuf+CONTROLFLAGSIZE+bi2) = BUFFER_READY;
bi2++;
} }// wait while buffer is not read while ((*(contBuf+CONTROLFLAGSIZE+bi2-1) == BUFFER_READY) || (*(contBuf+CONTROLFLAGSIZE+bi1-1) == BUFFER_READY));// printf ("\nPlease wait while unsetting the DMA channels\n");label1: ret = UnSetDMAMode7520(devno, 1); // unset DMA1 if (ret) printf("dma1 unset with code=%X\n", ret); ret = UnSetDMAMode7520(devno, 0); // unset DMA0 if (ret) printf("dma0 unset with code=%X\n", ret); fclose(infile); // close device if (ret) printf("device closed\n"); return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -