diff --git a/include/ad9915.h b/include/ad9915.h index 4363f6e..12c4273 100644 --- a/include/ad9915.h +++ b/include/ad9915.h @@ -25,7 +25,9 @@ static const char CFR1Start[] ={0x00, 0x01, 0x00, 0x0a}; //static const char CFR1Start[] ={0x00, 0x01, 0x01, 0x08}; //with osk enable static const char CFR2Start[] ={0x00, 0x80, 0x09, 0x00}; //0x80 enable prof mode static const char CFR3Start[] = {0x00, 0x00, 0x19, 0x1C}; -static const char CFR4Start[] = {0x00, 0x05, 0x21, 0x20}; +static const char CFR4Start[] = {0x00, 0x05, 0x21, 0x20}; +//static const char CFR4Start[] = {0x20, 0x21, 0x05, 0x00}; + static const char USR0Address = 0x1B; static const char FTW0Address = 0x0b; //profile 0 ftw @@ -37,13 +39,56 @@ static const char DACCalEnable[] = {0x01, 0x05, 0x21, 0x20}; //Command to enabl void Send_Reset(int f_dds); void Send_IO_Update (int f_dds); //Send the update to set the control registers void write_register (int fd, unsigned char addr, unsigned char d3, unsigned char d2, unsigned char d1, unsigned char d0); +void read_register (int fd, unsigned char addr, uint32_t *readword); +void read_register_ini (int fd,unsigned char addr); void Initialize_DDS (int fd, int f_dds); void Calibrate_DAC(int fd, int f_dds); void basic_setup(int fd, int f_dds, uint16_t ampWord, uint16_t phaseWord); void modulus_setup(int fd, int f_dds); void setFreqMM(int fd, int f_dds, unsigned int ftw, unsigned int A, unsigned int B); void setAmpPhaseWord(int fd, int f_dds,unsigned int phaseAmpWord); +void checkSize(void); int openAndSetDdsFreq( char * device, char * gpio_update, double f_clk, double f_out, uint16_t ampWord, uint16_t phaseWord); int receiveParameterFromPythonServer(char * device, double f_clk, double f_out); int setDdsFreqFull ( int fd, int f_dds, double f_clk, double f_out, uint16_t ampWord, uint16_t phaseWord); +//------------ DRCTL + +void Send_CTRL_UP(int fp); +void Send_CTRL_DOWN(int fp); +void Send_HOLD(int fp); +void Send_UNHOLD(int fp); +int testRampFreq(int fd, int f_dds, int fp); + +//-------Profile register mode + +int InitialisationProfile (int fd,int f_dds); +int PutFrequencyAmpPhaseWord(int fd, int f_dds, double fout, double fclk,double amp, double phase); + + +int PutFrequencyWord(int fd, int f_dds, double freq);//Attention uniquement valable pour fclk = 1 GHz +int PutPhaseWord(int fd, int f_dds, double phase); +int PutAmpWord(int fd, int f_dds, double amplitude); + +//fonctions rampes hardwres + +int FrequencySweep (int fd, int f_dds,double fclk,double dfUp, double dfDown, double FreqMax,double FreqMin, double DeltaTimeUp, double DeltaTimeDown); +int ContinueFrequencySweep (int fd, int f_dds,double fclk,double dfUp, double dfDown, double FreqMax,double FreqMin, double DeltaTimeUp, double DeltaTimeDown); +int AmplitudeSweep (int fd, int f_dds,double fclk,double dAUp, double dADown, double AMax,double AMin, double DeltaTimeUp, double DeltaTimeDown); +int ContinueAmplitudeSweep (int fd, int f_dds,double fclk,double dAUp, double dADown, double AMax,double AMin, double DeltaTimeUp, double DeltaTimeDown); +int PhaseSweep (int fd, int f_dds,double fclk,double dphiUp, double dphiDown, double PhiMax,double PhiMin, double DeltaTimeUp, double DeltaTimeDown); +int ContinuePhaseSweep (int fd, int f_dds,double fclk,double dphiUp, double dphiDown, double PhiMax,double PhiMin, double DeltaTimeUp, double DeltaTimeDown); + +//fin fonctions rampes hardwares + +// fonctions rampes softwares + +int RampAmpFromSoft(int fd, int f_dds,double DeltaTimeUp,double AIni, double AFin); + +int RampPhaseFromSoft(int fd, int f_dds,double DeltaTimeUp,double PhiIni, double PhiFin); + +// fin fonctoins rampes softwares + + + + diff --git a/src/ad9915.c b/src/ad9915.c index 9e90697..8b1b9c7 100644 --- a/src/ad9915.c +++ b/src/ad9915.c @@ -36,6 +36,35 @@ void write_register (int fd, unsigned char addr, unsigned char d3, unsigned cha spi_put_multiple(fd,tx,5,NULL,0); } +//fonction read register + +void read_register (int fd,unsigned char addr, uint32_t *readword) +{ + unsigned char tx[1] = {0}; + unsigned char rx[4] = {0}; + addr = addr|0x80;//instruction byte for the read : 1000 0000 | byte_adress + tx[0]=addr; + spi_put_multiple(fd,tx,1,rx,4); + //printf("TX:%x RX:%x %x %x %x\n",tx[0],rx[0],rx[1],rx[2],rx[3]); + *readword = 0x00000000; + *readword = *readword|(rx[0]<<24); + *readword = *readword|(rx[1]<<16); + *readword = *readword|(rx[2]<<8); + *readword = *readword|rx[3]; +} + +//fonction read register +void read_register_ini (int fd, unsigned char addr) +{ + unsigned char tx[1] = {0}; + unsigned char rx[4] = {0}; + addr = addr|0x80; + tx[0]=addr; + spi_put_multiple(fd,tx,1,rx,4); + printf("TX:%x RX:%x %x %x %x\n",tx[0],rx[0],rx[1],rx[2],rx[3]); + // Send_IO_Update (f_dds); //Send the update to set the control registers +} + //initialisation du dds void Initialize_DDS (int fd, int f_dds) { @@ -63,7 +92,8 @@ void Calibrate_DAC (int fd, int f_dds) void modulus_setup(int fd, int f_dds) { - write_register(fd,0x00,0x00, 0x01, 0x01, 0x08); //OSK enable + write_register(fd,0x00,0x00, 0x01, 0x01, 0x0a); //OSK enable //0x08 + //write_register(fd,0x00,0x00, 0x01, 0x01, 0x08); //OSK enable de base Send_IO_Update (f_dds); write_register(fd,0x01,0x00, 0x89, 0x09, 0x00); //enable program modulus and digital ramp Send_IO_Update (f_dds); @@ -113,6 +143,24 @@ void setAmpPhaseWord(int fd, int f_dds,unsigned int phaseAmpWord) Send_IO_Update(f_dds); } +/* +void getAmpPhaseWord(int fd) +{ + // unsigned char rx[5]={0}; + unsigned char* pt; + read_register(fd,0x0c,rx); // amp (12b) ph(16) + rx[0]=*pt; + rx[1]=*(pt+1); + rx[2]=*(pt+2); + rx[3]=*(pt+3); + rx[4]=*(pt+4); + printf("%c %c %c %c %c", rx[0], rx[1], rx[2], rx[3], rx[4]); +} +*/ +void checkSize(void) +{ + printf("int : %d\n",sizeof(unsigned int)); +} int openAndSetDdsFreq( char * device, char * gpio_update, double f_clk, double f_out, uint16_t ampWord, uint16_t phaseWord) { @@ -157,6 +205,1178 @@ int setDdsFreqFull ( int fd, int f_dds, double f_clk, double f_out, uint16_t amp return EXIT_SUCCESS; } +void Send_CTRL_UP(int fp) +{ + char DRCTLOn='0';//pente positive + write(fp,&DRCTLOn,sizeof(DRCTLOn)); // + sleep(0.1); +} + +void Send_CTRL_DOWN(int fp) +{ + char DRCTLOn='2';//pente negative + write(fp,&DRCTLOn,sizeof(DRCTLOn)); //reset + sleep(0.1); +} + +void Send_HOLD(int fp) +{ + char DRHOLDOn ='1';//rampe bloquée + write(fp,&DRHOLDOn,sizeof(DRHOLDOn)); //reset + sleep(0.1); +} + +void Send_UNHOLD(int fp) +{ + char DRHOLDOn ='3';//rampe debloquée + write(fp,&DRHOLDOn,sizeof(DRHOLDOn)); //reset + sleep(0.1); +} + + +int testRampFreq(int fd, int f_dds, int fp) +{ + + + //3-Rampe de pente positive + debloquage + Send_CTRL_DOWN(fp);//rampe up + Send_UNHOLD(fp); + + Send_Reset(f_dds); + //Initialize_DDS (fd, f_dds); + + //0- paramètre de bases + write_register(fd,0x00,0x00,0x01,0x01,0x0a);//OSKenable+Read&write + Send_IO_Update(f_dds); + read_register_ini(fd,0x00); + + write_register(fd,0x01,0x00, 0x00, 0x09, 0x00); // enable amp ramp + Send_IO_Update(f_dds); + read_register_ini(fd,0x00); + + //1- Donner une frequence f_dds de 1.1e7 Hz sachant que f_clk=1e9 Hz; + // => Le mot a donner est (p.19) : FTW=(f_dds/f_clk)*2³² + // FTW = 42949672.96 = 42 949 673. = 0x028f5c29 + // 1.1e7 =0x02d0e560 + +// 2d0e560 + + //Calibrate_DAC (fd,f_dds); + + + + write_register(fd,0x0b,0x02,0xd0,0xe5,0x60);//mot de frequence + Send_IO_Update(f_dds); + write_register(fd,0x0c,0x0F,0xFF,0x00,0x00); //mot de amp et de phase : amp max, phase nulle + Send_IO_Update(f_dds); + + printf("Les mots de frequences, d'amplitudes et de phases sont envoyes\n"); + printf("Lecture registre de frequence: 0x0b\n"); + read_register_ini(fd,0x0b); + printf("Lecture registre de amp et phase: 0x0c\n"); + read_register_ini(fd,0x0c); + + Calibrate_DAC (fd,f_dds); + printf("\n\n ----------------------- \n\n"); + + +/* + //2- Taille des dt + + write_register(fd,0x08,0xFF,0xFF,0xFF,0xFF); //+dt max, -dt max (+dt = -dt) + Send_IO_Update(f_dds); + + printf("Les mots de dt sont envoyes\n"); + printf("Lecture dans le registre 0x08 : taille dt\n"); + read_register_ini (fd,0x08); + + + + + printf("\n\n ----------------------- \n\n"); + + + //3- STEP SIZE :dphi + + // en theorie dphi =2.25e-28 degrees + write_register(fd,0x06,0x00,0x00,0x00,0x01); + Send_IO_Update(f_dds); + + write_register(fd,0x07,0x00,0x00,0x00,0x01); + Send_IO_Update(f_dds); + + //printf("\n\n ----------------------- \n\n"); + printf("Les mots de dphi sont envoyes\n"); + printf("Lecture dans les registres 0x06 et 0x07 : taille dt\n"); + read_register_ini (fd,0x06); + read_register_ini (fd,0x07); + + printf("\n\n ----------------------- \n\n"); + //4- Ecrire les extremums de la rampe + + write_register(fd,0x04,0x00,0x00,0x00,0x01);//0 rad + Send_IO_Update(f_dds); + write_register(fd,0x05,0xFF,0xFF,0xFF,0xFF);//2*pi rad + Send_IO_Update(f_dds); + + printf("Les mots des frontieres sont envoyes\n"); + printf("Lecture dans les registres 0x04 et 0x05 : taille dt\n"); + read_register_ini (fd,0x04); + read_register_ini (fd,0x05); + + + //3-Rampe de pente positive ou négative +// Send_CTRL_UP(fp);//rampe up + + + //4-ecriture dans le registre 0x01 + write_register(fd,0x01,0x00, 0xa8, 0x09, 0x00); // enable amp ramp + Send_IO_Update(f_dds); + + printf("Lecture dans le registre 0x01 : \n"); + read_register_ini (fd,0x01); +// printf("Les mots de dt sont envoyes\n"); + printf("Lecture dans le registre 0x08 : taille dt\n"); + read_register_ini (fd,0x08); + + +*/ + return EXIT_SUCCESS; +} + +//---------------rajout 8/1 + +int PutAmpWord(int fd, int f_dds, double amplitude) +{ + uint16_t PhaseWord = 0x0000; + uint16_t AmpWord = 0x0000; + uint32_t ReadPhaseAmpWord=0x00000000; + + AmpWord = rint(amplitude*(pow(2.0,12.0)-1)/100); + + read_register(fd,0x0c,&ReadPhaseAmpWord); + + PhaseWord = ReadPhaseAmpWord&0xFFFF; + + write_register(fd,0x0c,AmpWord>>8&0xFF,AmpWord&0xFF,PhaseWord>>8&0xFF,PhaseWord&0xFF); + Send_IO_Update(f_dds); + + return 0; +} + + +int PutPhaseWord(int fd, int f_dds, double phase) +{ + uint16_t PhaseWord = 0x0000; + uint16_t AmpWord = 0x0000; + uint32_t ReadPhaseAmpWord=0x00000000; + + PhaseWord = rint(phase*(pow(2.0,16.0)-1)/360); + + read_register(fd,0x0c,&ReadPhaseAmpWord); + + AmpWord = ReadPhaseAmpWord>>16&0xFFFF; + + write_register(fd,0x0c,AmpWord>>8&0xFF,AmpWord&0xFF,PhaseWord>>8&0xFF,PhaseWord&0xFF); + Send_IO_Update(f_dds); + + return 0; +} + +int PutFrequencyWord(int fd, int f_dds, double fout)//Attention uniquement valable pour fclk = 1 GHz +{ + + uint32_t FTWR = 0x00000000; + FTWR = rint((fout/1e9)*pow(2.0,32.0)); + write_register(fd,0x0b,FTWR>>24&0xFF,FTWR>>16&0xFF,FTWR>>8&0xFF,FTWR&0xFF);//mot de frequence + Send_IO_Update(f_dds); + + return 0; +} + + +int PutFrequencyAmpPhaseWord(int fd, int f_dds, double fout, double fclk,double amp, double phase)//n'existe pas dans le mode profile enable +{ + + uint32_t FTWR = 0x00000000; + + FTWR = rint((fout/fclk)*pow(2.0,32.0)); + + write_register(fd,0x0b,FTWR>>24&0xFF,FTWR>>16&0xFF,FTWR>>8&0xFF,FTWR&0xFF);//mot de frequence + + Send_IO_Update(f_dds); + +// write_register(fd,0x0c,0x0F,0xFF,0x00,0x00); //mot de amp et de phase : amp max, phase nulle +// Send_IO_Update(f_dds); + + PutPhaseWord(fd,f_dds,phase); + PutAmpWord(fd,f_dds,amp); + + return 0; +} + + +int InitialisationProfile (int fd,int f_dds) +{ + + Send_Reset(f_dds); //les registres sont maintenant par defaut + write_register(fd,0x00,0x00,0x01,0x01,0x0a); //OSK+SDIO input only//ok + Send_IO_Update(f_dds); + write_register(fd,0x01,0x00,0x80,0x09,0x00); // profile mode enable very important + Send_IO_Update(f_dds); + write_register(fd,0x02,0x00,0x00,0x19,0x1c); // default + Send_IO_Update(f_dds); + write_register(fd,0x03,0x01,0x05,0x21,0x20); // calibration 1/2 :enable + Send_IO_Update(f_dds); + write_register(fd,0x03,0x00,0x05,0x21,0x20); // calibration 2/2 :desenable + Send_IO_Update(f_dds); + + return 0; +} + + + +//------------------- FIN RAJOUT 8/1 + + +//-------------------------FONCTIONS RAMPES HARDWARE + +//1-rampe de frequence + +//rampe simple de fréquence +int FrequencySweep (int fd, int f_dds,double fclk,double dfUp, double dfDown, double FreqMax,double FreqMin, double DeltaTimeUp, double DeltaTimeDown) +{ + //calcul de N => N=DeltaF/df = DeltaT/dt + + //1-fmax > fmin + double DeltaFreq = FreqMax-FreqMin; + if(FreqMax FreqMin\n"); + printf("Can't Start the ramp\n"); + return -1; + } + + //2- Calcul du nombre de points de la rampe + int NumberPointsUp = DeltaFreq/dfUp; + int NumberPointsDown = DeltaFreq/dfDown; + + //3- En déduire la valeur de dtUp et dtDown + double dtUp = DeltaTimeUp/NumberPointsUp; + double dtDown = DeltaTimeDown/NumberPointsDown; + + double dtmin = 24/fclk; + double dtmax = dtmin*(pow(2.0,16.0)-1); + + //Check Up + if(dtUp %f s\n",dtmin*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtUp>dtmax) + { + printf("During of ramp UP should be < %f\n",dtmax*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + //Check Down + if(dtDown %f s\n",dtmin*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtDown>dtmax) + { + printf("During of ramp DOWN should be < %f\n",dtmax*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + + //4 - Put word in register + + + //4.1 Limit register + uint32_t FTWRmin = rint((FreqMin/fclk)*pow(2.0,32.0)); + write_register(fd,0x04,FTWRmin>>24&0xFF,FTWRmin>>16&0xFF,FTWRmin>>8&0xFF,FTWRmin&0xFF);//mot de frequence + Send_IO_Update(f_dds); + + uint32_t FTWRmax = rint((FreqMax/fclk)*pow(2.0,32.0)); + write_register(fd,0x05,FTWRmax>>24&0xFF,FTWRmax>>16&0xFF,FTWRmax>>8&0xFF,FTWRmax&0xFF);//mot de frequence + Send_IO_Update(f_dds); + + + //4.2 dfUP et dfDown + double df_up = DeltaFreq/NumberPointsUp; + double df_down = DeltaFreq/NumberPointsDown; + + uint32_t Word_df_up = rint(df_up*pow(2.0,32.0)/fclk); + uint32_t Word_df_down = rint(df_down*pow(2.0,32.0)/fclk); + + write_register(fd,0x06,Word_df_up>>24&0xFF,Word_df_up>>16&0xFF,Word_df_up>>8&0xFF,Word_df_up&0xFF); //df_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_df_down>>24&0xFF,Word_df_down>>16&0xFF,Word_df_down>>8&0xFF,Word_df_down&0xFF);//df_down + Send_IO_Update(f_dds); + + + //4.3 dtUp et dtDown + + uint16_t Word_dt_up = 0x0000; + uint16_t Word_dt_down = 0x0000; + + Word_dt_up = rint(dtUp*fclk/24); + Word_dt_down = rint(dtDown*fclk/24); + + write_register(fd,0x08,Word_dt_down>>8&0xFF,Word_dt_down&0xFF,Word_dt_up>>8&0xFF,Word_dt_up&0xFF); // il y a 2 dt + Send_IO_Update(f_dds); + + //5 Start of the ramp + + write_register(fd,0x01,0x00,0x08,0x09,0x00); //rampe simple + Send_IO_Update(f_dds); + return 0; + + + + return EXIT_SUCCESS; + +} + + +//rampe continue de fréquence +int ContinueFrequencySweep (int fd, int f_dds,double fclk,double dfUp, double dfDown, double FreqMax,double FreqMin, double DeltaTimeUp, double DeltaTimeDown) +{ + //calcul de N => N=DeltaF/df = DeltaT/dt + + //1-fmax > fmin + double DeltaFreq = FreqMax-FreqMin; + if(FreqMax FreqMin\n"); + printf("Can't Start the ramp\n"); + return -1; + } + + //2- Calcul du nombre de points de la rampe + int NumberPointsUp = DeltaFreq/dfUp; + int NumberPointsDown = DeltaFreq/dfDown; + + //3- En déduire la valeur de dtUp et dtDown + double dtUp = DeltaTimeUp/NumberPointsUp; + double dtDown = DeltaTimeDown/NumberPointsDown; + + double dtmin = 24/fclk; + double dtmax = dtmin*(pow(2.0,16.0)-1); + + //Check Up + if(dtUp %f s\n",dtmin*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtUp>dtmax) + { + printf("During of ramp UP should be < %f\n",dtmax*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + //Check Down + if(dtDown %f s\n",dtmin*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtDown>dtmax) + { + printf("During of ramp DOWN should be < %f\n",dtmax*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + + //4 - Put word in register + + + //4.1 Limit register + uint32_t FTWRmin = rint((FreqMin/fclk)*pow(2.0,32.0)); + write_register(fd,0x04,FTWRmin>>24&0xFF,FTWRmin>>16&0xFF,FTWRmin>>8&0xFF,FTWRmin&0xFF);//mot de frequence + Send_IO_Update(f_dds); + + uint32_t FTWRmax = rint((FreqMax/fclk)*pow(2.0,32.0)); + write_register(fd,0x05,FTWRmax>>24&0xFF,FTWRmax>>16&0xFF,FTWRmax>>8&0xFF,FTWRmax&0xFF);//mot de frequence + Send_IO_Update(f_dds); + + + //4.2 dfUP et dfDown + double df_up = DeltaFreq/NumberPointsUp; + double df_down = DeltaFreq/NumberPointsDown; + + uint32_t Word_df_up = rint(df_up*pow(2.0,32.0)/fclk); + uint32_t Word_df_down = rint(df_down*pow(2.0,32.0)/fclk); + + write_register(fd,0x06,Word_df_up>>24&0xFF,Word_df_up>>16&0xFF,Word_df_up>>8&0xFF,Word_df_up&0xFF); //df_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_df_down>>24&0xFF,Word_df_down>>16&0xFF,Word_df_down>>8&0xFF,Word_df_down&0xFF);//df_down + Send_IO_Update(f_dds); + + + //4.3 dtUp et dtDown + + uint16_t Word_dt_up = 0x0000; + uint16_t Word_dt_down = 0x0000; + + Word_dt_up = rint(dtUp*fclk/24); + Word_dt_down = rint(dtDown*fclk/24); + + write_register(fd,0x08,Word_dt_down>>8&0xFF,Word_dt_down&0xFF,Word_dt_up>>8&0xFF,Word_dt_up&0xFF); // il y a 2 dt + Send_IO_Update(f_dds); + + //5 Start of the ramp + + write_register(fd,0x01,0x00,0x8e,0x29,0x00); //rampe triangulaire + Send_IO_Update(f_dds); + return 0; + + + + return EXIT_SUCCESS; + +} + +//2-rampe d'amplitude + +int AmplitudeSweep (int fd, int f_dds,double fclk,double dAUp, double dADown, double AMax,double AMin, double DeltaTimeUp, double DeltaTimeDown) +{ + + + //calcul de N => N=DeltaF/df = DeltaT/dt + + //1-Amax > Amin + double DeltaAmp = AMax-AMin; + if(AMax AMin\n"); + printf("Can't Start the ramp\n"); + return -1; + } + + + //2- Calcul du nombre de points de la rampe + int NumberPointsUp = DeltaAmp/dAUp; + int NumberPointsDown = DeltaAmp/dADown; + + //3- En déduire la valeur de dtUp et dtDown + double dtUp = DeltaTimeUp/NumberPointsUp; + double dtDown = DeltaTimeDown/NumberPointsDown; + + double dtmin = 24/fclk; + double dtmax = dtmin*(pow(2.0,16.0)-1); + + //Check Up + if(dtUp %f s\n",dtmin*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtUp>dtmax) + { + printf("During of ramp UP should be < %f\n",dtmax*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + //Check Down + if(dtDown %f s\n",dtmin*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtDown>dtmax) + { + printf("During of ramp DOWN should be < %f\n",dtmax*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + + + //check if DeltaAmp is enouth + double enouthUP=0.5*NumberPointsUp*100/4095; + double enouthDOWN=0.5*NumberPointsDown*100/4095; + + int borneUP = rint(enouthUP); + int borneDown = rint(enouthDOWN); + + if(DeltaAmp<=enouthUP) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for positive slope",borneUP); + //return -1; + } + + if(DeltaAmp<=enouthDOWN) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for negative slope",borneDown); + //return -1; + } + + + //4 - Put word in register + + + //4.1 Limit register + uint32_t WordAmin = rint(AMin*4095/100); + uint32_t WordAmax= rint(AMax*4095/100); + + write_register(fd,0x04,WordAmin>>24&0xFF,WordAmin>>16&0xFF,WordAmin>>8&0xFF,WordAmin&0xFF); //min => lim-(Amp ) = 0x800 = Amax/2 + Send_IO_Update(f_dds); + write_register(fd,0x05,WordAmax>>24&0xFF,WordAmax>>16&0xFF,WordAmax>>8&0xFF,WordAmax&0xFF);//max => lim+(Amp) = 0xFFF= Amax0 + Send_IO_Update(f_dds); + + + //4.2 dAUP et dADown + + uint32_t Word_dA_up = rint(dAUp*4095/100); + uint32_t Word_dA_down = rint(dADown*4095/100); + + write_register(fd,0x06,Word_dA_up>>24&0xFF,Word_dA_up>>16&0xFF,Word_dA_up>>8&0xFF,Word_dA_up&0xFF); //dA_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_dA_down>>24&0xFF,Word_dA_down>>16&0xFF,Word_dA_down>>8&0xFF,Word_dA_down&0xFF);//dA_down + Send_IO_Update(f_dds); + + + //4.3 dtUp et dtDown + + uint16_t Word_dt_up = rint(dtUp*fclk/24); + uint16_t Word_dt_down = rint(dtDown*fclk/24); + + write_register(fd,0x08,Word_dt_down>>8&0xFF,Word_dt_down&0xFF,Word_dt_up>>8&0xFF,Word_dt_up&0xFF); // il y a 2 dt + Send_IO_Update(f_dds); + + //5 Start of the ramp + + write_register(fd,0x01,0x00,0x28,0x09,0x00); //rampe simple montante + //write_register(fd,0x01,0x00,0xAE,0x29,0x00); //rampe continue + Send_IO_Update(f_dds); + + return EXIT_SUCCESS; +} + +int ContinueAmplitudeSweep (int fd, int f_dds,double fclk,double dAUp, double dADown, double AMax,double AMin, double DeltaTimeUp, double DeltaTimeDown) +{ + + + //calcul de N => N=DeltaF/df = DeltaT/dt + + //1-Amax > Amin + double DeltaAmp = AMax-AMin; + if(AMax AMin\n"); + printf("Can't Start the ramp\n"); + return -1; + } + + + //2- Calcul du nombre de points de la rampe + int NumberPointsUp = DeltaAmp/dAUp; + int NumberPointsDown = DeltaAmp/dADown; + + //3- En déduire la valeur de dtUp et dtDown + double dtUp = DeltaTimeUp/NumberPointsUp; + double dtDown = DeltaTimeDown/NumberPointsDown; + + double dtmin = 24/fclk; + double dtmax = dtmin*(pow(2.0,16.0)-1); + + //Check Up + if(dtUp %f s\n",dtmin*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtUp>dtmax) + { + printf("During of ramp UP should be < %f\n",dtmax*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + //Check Down + if(dtDown %f s\n",dtmin*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtDown>dtmax) + { + printf("During of ramp DOWN should be < %f\n",dtmax*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + + + //check if DeltaAmp is enouth + double enouthUP=0.5*NumberPointsUp*100/4095; + double enouthDOWN=0.5*NumberPointsDown*100/4095; + + int borneUP = rint(enouthUP); + int borneDown = rint(enouthDOWN); + + if(DeltaAmp<=enouthUP) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for positive slope",borneUP); + //return -1; + } + + if(DeltaAmp<=enouthDOWN) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for negative slope",borneDown); + //return -1; + } + + + //4 - Put word in register + + + //4.1 Limit register + uint32_t WordAmin = rint(AMin*4095/100); + uint32_t WordAmax= rint(AMax*4095/100); + + write_register(fd,0x04,WordAmin>>24&0xFF,WordAmin>>16&0xFF,WordAmin>>8&0xFF,WordAmin&0xFF); //min => lim-(Amp ) = 0x800 = Amax/2 + Send_IO_Update(f_dds); + write_register(fd,0x05,WordAmax>>24&0xFF,WordAmax>>16&0xFF,WordAmax>>8&0xFF,WordAmax&0xFF);//max => lim+(Amp) = 0xFFF= Amax0 + Send_IO_Update(f_dds); + + + //4.2 dAUP et dADown + + uint32_t Word_dA_up = rint(dAUp*4095/100); + uint32_t Word_dA_down = rint(dADown*4095/100); + + write_register(fd,0x06,Word_dA_up>>24&0xFF,Word_dA_up>>16&0xFF,Word_dA_up>>8&0xFF,Word_dA_up&0xFF); //dA_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_dA_down>>24&0xFF,Word_dA_down>>16&0xFF,Word_dA_down>>8&0xFF,Word_dA_down&0xFF);//dA_down + Send_IO_Update(f_dds); + + + //4.3 dtUp et dtDown + + uint16_t Word_dt_up = rint(dtUp*fclk/24); + uint16_t Word_dt_down = rint(dtDown*fclk/24); + + write_register(fd,0x08,Word_dt_down>>8&0xFF,Word_dt_down&0xFF,Word_dt_up>>8&0xFF,Word_dt_up&0xFF); // il y a 2 dt + Send_IO_Update(f_dds); + + //5 Start of the ramp + + //write_register(fd,0x01,0x00,0x28,0x09,0x00); //rampe simple montante + write_register(fd,0x01,0x00,0xAE,0x29,0x00); //rampe continue + Send_IO_Update(f_dds); + + return EXIT_SUCCESS; +} + + +//3-rampe de ĥase + +int PhaseSweep (int fd, int f_dds,double fclk,double dphiUp, double dphiDown, double PhiMax,double PhiMin, double DeltaTimeUp, double DeltaTimeDown) +{ + + + //calcul de N => N=Deltaphi/dphi = DeltaT/dt + + //1-phimax > phimin + double DeltaPhi = PhiMax-PhiMin; + if(PhiMax PhiMin\n"); + printf("Can't Start the ramp\n"); + return -1; + } + + + //2- Calcul du nombre de points de la rampe + int NumberPointsUp = DeltaPhi/dphiUp; + int NumberPointsDown = DeltaPhi/dphiDown; + + printf("NumberPointsUp = %d\n",NumberPointsUp); + printf("NumberPointsDown = %d\n",NumberPointsDown); + + //3- En déduire la valeur de dtUp et dtDown + double dtUp = DeltaTimeUp/NumberPointsUp; + double dtDown = DeltaTimeDown/NumberPointsDown; + + double dtmin = 24/fclk; + double dtmax = dtmin*(pow(2.0,16.0)-1); + + //Check Up + if(dtUp %f s\n",dtmin*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtUp>dtmax) + { + printf("During of ramp UP should be < %f\n",dtmax*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + //Check Down + if(dtDown %f s\n",dtmin*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtDown>dtmax) + { + printf("During of ramp DOWN should be < %f\n",dtmax*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + + + //check if DeltaAmp is enouth +/* + double enouthUP=0.5*NumberPointsUp*100/4095; + double enouthDOWN=0.5*NumberPointsDown*100/4095; + + int borneUP = rint(enouthUP); + int borneDown = rint(enouthDOWN); + + if(DeltaAmp<=enouthUP) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for positive slope",borneUP); + //return -1; + } + + if(DeltaAmp<=enouthDOWN) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for negative slope",borneDown); + //return -1; + } + +*/ + + //4 - Put word in register + + + //4.1 Limit register + uint32_t WordPhimin = rint(PhiMin*65535/360); + uint32_t WordPhimax= rint(PhiMax*65535/360); + + + printf("WordPhimin = %.32x\n",WordPhimin); + printf("WordPhimax = %.32x\n",WordPhimax); + + + write_register(fd,0x04,WordPhimin>>24&0xFF,WordPhimin>>16&0xFF,WordPhimin>>8&0xFF,WordPhimin&0xFF); //min => lim-(Amp ) = 0x800 = Amax/2 + Send_IO_Update(f_dds); + write_register(fd,0x05,WordPhimax>>24&0xFF,WordPhimax>>16&0xFF,WordPhimax>>8&0xFF,WordPhimax&0xFF);//max => lim+(Amp) = 0xFFF= Amax0 + Send_IO_Update(f_dds); + + + //4.2 dphiUP et dphiDown + +// uint32_t Word_dphi_up = rint(dphiUp*(pow(2.0,29.0)-1)/45); +// uint32_t Word_dphi_down = rint(dphiDown*(pow(2.0,29.0)-1)/45); + uint32_t Word_dphi_up = rint(dphiUp*(65535/360)); + uint32_t Word_dphi_down = rint(dphiDown*(65535/360)); + + printf("Word_dphi_up = %.32x\n",Word_dphi_up); + printf("Word_dphi_down = %.32x\n",Word_dphi_down); + +/* + write_register(fd,0x06,Word_dphi_up>>16&0xFF,Word_dphi_up>>8&0xFF,Word_dphi_up>>0&0xFF,Word_dphi_up&0xFF); //dphi_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_dphi_down>>16&0xFF,Word_dphi_down>>8&0xFF,Word_dphi_down>>0&0xFF,Word_dphi_down&0xFF);//dphi_down + Send_IO_Update(f_dds); + +*/ + + + write_register(fd,0x06,Word_dphi_up>>24&0xFF,Word_dphi_up>>16&0xFF,Word_dphi_up>>8&0xFF,Word_dphi_up&0xFF); //dA_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_dphi_down>>24&0xFF,Word_dphi_down>>16&0xFF,Word_dphi_down>>8&0xFF,Word_dphi_down&0xFF);//dA_down + Send_IO_Update(f_dds); + + + //4.3 dtUp et dtDown + + uint16_t Word_dt_up = rint(dtUp*fclk/24); + uint16_t Word_dt_down = rint(dtDown*fclk/24); + + write_register(fd,0x08,Word_dt_down>>8&0xFF,Word_dt_down&0xFF,Word_dt_up>>8&0xFF,Word_dt_up&0xFF); // il y a 2 dt + Send_IO_Update(f_dds); + + //5 Start of the ramp + + write_register(fd,0x01,0x00,0x18,0x09,0x00); //rampe simple montante + Send_IO_Update(f_dds); + + return EXIT_SUCCESS; +} + +int ContinuePhaseSweep (int fd, int f_dds,double fclk,double dphiUp, double dphiDown, double PhiMax,double PhiMin, double DeltaTimeUp, double DeltaTimeDown) +{ + + + //calcul de N => N=Deltaphi/dphi = DeltaT/dt + + //1-phimax > phimin + double DeltaPhi = PhiMax-PhiMin; + if(PhiMax PhiMin\n"); + printf("Can't Start the ramp\n"); + return -1; + } + + + //2- Calcul du nombre de points de la rampe + int NumberPointsUp = DeltaPhi/dphiUp; + int NumberPointsDown = DeltaPhi/dphiDown; + + printf("NumberPointsUp = %d\n",NumberPointsUp); + printf("NumberPointsDown = %d\n",NumberPointsDown); + + //3- En déduire la valeur de dtUp et dtDown + double dtUp = DeltaTimeUp/NumberPointsUp; + double dtDown = DeltaTimeDown/NumberPointsDown; + + double dtmin = 24/fclk; + double dtmax = dtmin*(pow(2.0,16.0)-1); + + //Check Up + if(dtUp %f s\n",dtmin*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtUp>dtmax) + { + printf("During of ramp UP should be < %f\n",dtmax*NumberPointsUp); + printf("Can't start the ramp\n"); + return -1; + } + + //Check Down + if(dtDown %f s\n",dtmin*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + if(dtDown>dtmax) + { + printf("During of ramp DOWN should be < %f\n",dtmax*NumberPointsDown); + printf("Can't start the ramp\n"); + return -1; + } + + + + //check if DeltaAmp is enouth +/* + double enouthUP=0.5*NumberPointsUp*100/4095; + double enouthDOWN=0.5*NumberPointsDown*100/4095; + + int borneUP = rint(enouthUP); + int borneDown = rint(enouthDOWN); + + if(DeltaAmp<=enouthUP) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for positive slope",borneUP); + //return -1; + } + + if(DeltaAmp<=enouthDOWN) + { + printf("The amplitude difference should be > %d\n, decrease Number Points for negative slope",borneDown); + //return -1; + } + +*/ + + //4 - Put word in register + + + //4.1 Limit register + uint32_t WordPhimin = rint(PhiMin*65535/360); + uint32_t WordPhimax= rint(PhiMax*65535/360); + + + printf("WordPhimin = %.32x\n",WordPhimin); + printf("WordPhimax = %.32x\n",WordPhimax); + + + write_register(fd,0x04,WordPhimin>>24&0xFF,WordPhimin>>16&0xFF,WordPhimin>>8&0xFF,WordPhimin&0xFF); //min => lim-(Amp ) = 0x800 = Amax/2 + Send_IO_Update(f_dds); + write_register(fd,0x05,WordPhimax>>24&0xFF,WordPhimax>>16&0xFF,WordPhimax>>8&0xFF,WordPhimax&0xFF);//max => lim+(Amp) = 0xFFF= Amax0 + Send_IO_Update(f_dds); + + + //4.2 dphiUP et dphiDown + +// uint32_t Word_dphi_up = rint(dphiUp*(pow(2.0,29.0)-1)/45); +// uint32_t Word_dphi_down = rint(dphiDown*(pow(2.0,29.0)-1)/45); + uint32_t Word_dphi_up = rint(dphiUp*(65535/360)); + uint32_t Word_dphi_down = rint(dphiDown*(65535/360)); + + printf("Word_dphi_up = %.32x\n",Word_dphi_up); + printf("Word_dphi_down = %.32x\n",Word_dphi_down); + +/* + write_register(fd,0x06,Word_dphi_up>>16&0xFF,Word_dphi_up>>8&0xFF,Word_dphi_up>>0&0xFF,Word_dphi_up&0xFF); //dphi_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_dphi_down>>16&0xFF,Word_dphi_down>>8&0xFF,Word_dphi_down>>0&0xFF,Word_dphi_down&0xFF);//dphi_down + Send_IO_Update(f_dds); + +*/ + + + write_register(fd,0x06,Word_dphi_up>>24&0xFF,Word_dphi_up>>16&0xFF,Word_dphi_up>>8&0xFF,Word_dphi_up&0xFF); //dA_up + Send_IO_Update(f_dds); + write_register(fd,0x07,Word_dphi_down>>24&0xFF,Word_dphi_down>>16&0xFF,Word_dphi_down>>8&0xFF,Word_dphi_down&0xFF);//dA_down + Send_IO_Update(f_dds); + + + //4.3 dtUp et dtDown + + uint16_t Word_dt_up = rint(dtUp*fclk/24); + uint16_t Word_dt_down = rint(dtDown*fclk/24); + + write_register(fd,0x08,Word_dt_down>>8&0xFF,Word_dt_down&0xFF,Word_dt_up>>8&0xFF,Word_dt_up&0xFF); // il y a 2 dt + Send_IO_Update(f_dds); + + //5 Start of the ramp + + write_register(fd,0x01,0x00,0x9E,0x29,0x00); //rampe simple montante + Send_IO_Update(f_dds); + + return EXIT_SUCCESS; +} + + +//-------------------------FIN FONCTIONS RAMPES HARDWARES + +//--------------------------FONCTIONS RAMPES SOFTWARES + +int RampAmpFromSoft(int fd, int f_dds,double DeltaTimeUp,double AIni, double AFin) +{ + + //On va plutôt fixé dA sinon trop de contrainte : => Besoin d'allocation dynamique + double dA=0.024;//en % + double DeltaAmp = AIni-AFin; + double AbsDeltaAmp = 0; + if(DeltaAmp>=0) + { + AbsDeltaAmp = DeltaAmp; + } + else + { + AbsDeltaAmp = -1*DeltaAmp; + } + + int NumberPoints = AbsDeltaAmp/dA; + + double dt=DeltaTimeUp/NumberPoints; + + printf("Taille du tableau = %d\n", NumberPoints); + printf("dt = %f s\n",dt); + + + uint16_t* ArrayWordAmp= NULL; + ArrayWordAmp = malloc(NumberPoints*sizeof(uint16_t)); + + //extraction de la phase initiale et de l'amplitude + + uint32_t ReadPhaseAmpWord = 0x00000000; + read_register(fd, 0x0c,&ReadPhaseAmpWord); + printf("ReadPhaseAmpWord = %.8x \n", ReadPhaseAmpWord); + + uint16_t WordPhaseInitiale = ReadPhaseAmpWord&0xFFFF; + printf("Phase = %.4x \n", WordPhaseInitiale); + + + // + for(int i=0;i>8&0xFF,ArrayWordAmp[i]&0xFF,WordPhaseInitiale>>8&0xFF,WordPhaseInitiale&0xFF); + Send_IO_Update(f_dds); + usleep(1000000*dt); + } + + + +/* + uint16_t PhaseWord = 0x0000; + uint16_t AmpWord = 0x0000; + uint32_t ReadPhaseAmpWord=0x00000000; + + AmpWord = rint(amplitude*(pow(2.0,12.0)-1)/100); + + read_register(fd,0x0c,&ReadPhaseAmpWord); + + PhaseWord = ReadPhaseAmpWord&0xFFFF; + + write_register(fd,0x0c,AmpWord>>8&0xFF,AmpWord&0xFF,PhaseWord>>8&0xFF,PhaseWord&0xFF); + +*/ + + + +/* + + //pas de durée dtUp et dtDown fixée au minimum à 1 ms + if(DeltaTimeUp < 4.095) + { + printf("Use hardware fonctions for the ramp\n"); + } + + + // + double DeltaAmp = AMax-AMin; + double dA = DeltaAmp/TAILLETAB; + printf("dA=%f\n",dA); + + + if(dA<0.024) + { + printf("Amplitude step should be > 0.024 pourcent\n"); + printf("Impossible to start a ramp of amplitude\n"); + return -1; + } + + //extraction de la phase initiale et de l'amplitude + + uint32_t ReadPhaseAmpWord = 0x00000000; + read_register(fd, 0x0c,&ReadPhaseAmpWord); + printf("ReadPhaseAmpWord = %.8x \n", ReadPhaseAmpWord); + + uint16_t WordPhaseInitiale = ReadPhaseAmpWord&0xFFFF; + printf("Phase = %.4x \n", WordPhaseInitiale); + + uint16_t WordAmpInitiale = ReadPhaseAmpWord>>16&0xFFFF; + printf("Amp = %.4x \n", WordAmpInitiale); + + uint16_t Word_dA = rint(dA*4095/100); + + uint32_t ArrayWordAmp[TAILLETAB]; + + for(int i=0;i Besoin d'allocation dynamique + double dphi=0.06;//en ° + double DeltaPhi = PhiIni-PhiFin; + double AbsDeltaPhi = 0; + if(DeltaPhi>=0) + { + AbsDeltaPhi = DeltaPhi; + } + else + { + AbsDeltaPhi = -1*DeltaPhi; + } + + int NumberPoints = AbsDeltaPhi/dphi; + + double dt=DeltaTimeUp/NumberPoints; + + printf("Taille du tableau = %d\n", NumberPoints); + printf("dt = %f s\n",dt); + + + uint16_t* ArrayWordPhi= NULL; + ArrayWordPhi = malloc(NumberPoints*sizeof(uint16_t)); + + //extraction de l'amplitude + + uint32_t ReadPhaseAmpWord = 0x00000000; + read_register(fd, 0x0c,&ReadPhaseAmpWord); + printf("ReadPhaseAmpWord = %.8x \n", ReadPhaseAmpWord); + + uint16_t WordAmpInitiale = ReadPhaseAmpWord>>16&0xFFFF; + printf("Amp = %.4x \n", WordAmpInitiale); + + + for(int i=0;i>8&0xFF,WordAmpInitiale&0xFF,ArrayWordPhi[i]>>8&0xFF,ArrayWordPhi[i]&0xFF); + Send_IO_Update(f_dds); + usleep(1000000*dt); + } + + + return EXIT_SUCCESS; +} + + + +//-------------------------FIN FONCTIONS RAMPES SOFTWARES + + + + int receiveParameterFromPythonServer(char * device, double f_clk, double f_out){ printf("receiveParameterFromPythonServer::device=%s\tf_clk=%e\tf_out=%e\n",device,f_clk,f_out); diff --git a/src/ddsFreq.c b/src/ddsFreq.c index 14fa684..63c15c1 100644 --- a/src/ddsFreq.c +++ b/src/ddsFreq.c @@ -72,7 +72,7 @@ setFreqMM(fd,f_dds,(unsigned int)ftw, 2*(unsigned int)B, 2*(unsigned int)A); / } int ddsFreq(int fd, int f_dds) { - //checkSize(); + checkSize(); long double f0,fs; //printf("long = %lu\n",sizeof (long)); //printf("float = %lu\n",sizeof (float));