view DDSBes.c @ 183:791ca26fee6a

Rewrite data writing to file Fmt() uses by default truncation to conver double arguments to their text representation. Rounding must be used. Rewrite using standard C functions to get rid of this problem (and probably make it more efficient). Extend to handle arbitrary number of channels and to report errors on opening the data files.
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Fri, 21 Feb 2014 18:42:30 +0100
parents d9aae7d7f2c6
children
line wrap: on
line source

#include <utility.h>
#include <cvirte.h>		/* Needed if linking in external compiler; harmless otherwise */
#include <userint.h>
#include "DDSBes.h"
#include <ansi_c.h>
#include <gpib.h>

#define PPORT	0x378
#define PPCTRL	PPORT+2
#define UPDate	0x040
#define nWR	0x080
#define MReset	0x0C0
#define tempo   20

// Private functions, hence declared as static ...

static int delai(int t) {
	int j ;
	for (j=0;j<t; j++) ;
	return(0) ;
}


static int Strb_adress(unsigned char ad) {
	outp(PPCTRL,0x08) ;
	outp(PPORT,ad) ;
	outp(PPCTRL,0x09) ;
	delai(tempo) ;
	outp(PPCTRL,0x08) ;
    delai(tempo); 
	return(0) ;
}

static int Strb_data(unsigned char da) {
	outp(PPCTRL,0x00) ;
	outp(PPORT,da) ;   
	outp(PPCTRL,0x01) ;
	delai(tempo) ;
	outp(PPCTRL,0x00) ;
	delai(tempo) ;
	return(0) ;
}

static int Strb_nWrite(void) {
	outp(PPCTRL,0x08) ;
	outp(PPORT,nWR) ;
	outp(PPCTRL,0x09) ; 
	delai(tempo) ;
	outp(PPCTRL,0x08) ;
	delai(tempo) ; 
	return(0) ;   
}

static int Strb_Update(void) {
	outp(PPCTRL,0x08) ;
	outp(PPORT,UPDate) ;
	outp(PPCTRL,0x09) ;
	delai(tempo) ;
	outp(PPCTRL,0x08) ;
	delai(tempo) ;
	return(0) ;
}

static int Strb_MReset(void) {
	outp(PPCTRL,0x08) ;
	outp(PPORT,MReset) ;
	outp(PPCTRL,0x09) ;
	delai(tempo) ;
	outp(PPCTRL,0x08) ;
	delai(tempo) ;
	return(0) ;
}

// Public functions

void DDSBes_Initialize(DDSBes_Data * Instance) {
	Strb_MReset();
	/* 0 dans 0x1F => update clock externe */
	Strb_data(0x00);
	Strb_adress(0x1F);
	Strb_nWrite();
	
	return ;
}

void DDSBes_Close(DDSBes_Data * Instance){

	return ;
}

void DDSBes_SetClockFrequency(DDSBes_Data * Instance, double clock_frequency){
	
	int fPLL  ;
	unsigned char oPLL;
	
	fPLL = 1;
	if(fPLL==1 || (fPLL>3 && fPLL<21)) { 
		Instance->ClockFrequency = clock_frequency*fPLL;
		if (Instance->ClockFrequency>300.0e6) {
			Instance->ClockFrequency = 300.0e6 ;
		}
	}

	if (fPLL==1) oPLL=0x60 ; 
	else {
		if (Instance->ClockFrequency>=2e8) oPLL=(unsigned char)(0x40 + fPLL) ;
		else oPLL= (unsigned char)fPLL ;
	}

	Strb_data(oPLL);
	Strb_adress(0x1E);
	Strb_nWrite();
	
	return ;
}

void DDSBes_SetFrequency(DDSBes_Data * Instance, double frequency){

	double pas ;
	double reste ;
	double coeff;
	double fdiv[7];
	double p[6];
	
	int i;
	
	unsigned char o[6];
	
	fdiv[6]=pow(2.0,48.0);
	fdiv[5]=pow(2.0,40.0);
	fdiv[4]=pow(2.0,32.0);
	fdiv[3]=pow(2.0,24.0);
	fdiv[2]=65536.0;
	fdiv[1]=256.0;
	fdiv[0]=1.0;
	
	coeff=fdiv[6]/Instance->ClockFrequency;
	pas=coeff*frequency;
	reste=pas;

	for (i=5;i>0;i--){
		p[i]=(reste/fdiv[i]);
		reste=fmod(pas,fdiv[i]);
	}
	p[0]=reste;

	for (i=5;i>=0;i--){
		o[i]=(unsigned char) p[i];
	}

	/* frequence (6 octets) */
	Strb_adress(0x04);Strb_data(o[5]);Strb_nWrite();
	Strb_adress(0x05);Strb_data(o[4]);Strb_nWrite();
	Strb_adress(0x06);Strb_data(o[3]);Strb_nWrite();
	Strb_adress(0x07);Strb_data(o[2]);Strb_nWrite();
	Strb_adress(0x08);Strb_data(o[1]);Strb_nWrite();
	Strb_adress(0x09);Strb_data(o[0]);Strb_nWrite();

	Strb_Update();
	
	// store in Instance->Frequency the real frequency generated by the DDS 
	// (and not "frequency", which is only the requested frequency and might differ by as much as ClockFrequency/2^48
	Instance->Frequency = Instance->ClockFrequency/fdiv[6]
		*(fdiv[5]*o[5]+fdiv[4]*o[4]+fdiv[3]*o[3]+fdiv[2]*o[2]+fdiv[1]*o[1]+fdiv[0]*o[0]) ;
	
	
	
	return ;
}


void DDSBes_SetAmplitude(DDSBes_Data * Instance, int amplitude) {
	unsigned char a[2];

	if (amplitude > 0 && amplitude < 4096){ 
		a[1]=(unsigned char)(amplitude>>8);
		a[0]=(unsigned char)floor(fmod(amplitude,256.0));
		Instance->Amplitude = amplitude ;
		} 
		
	/* nibble fort adresse=0x21 data=a[1] */
	Strb_data(a[1]);
	Strb_adress(0x21);
	Strb_nWrite();
	/* octet faible adresse=0x22  data=a[0] */
	Strb_data(a[0]);
	Strb_adress(0x22);
	Strb_nWrite();
	/* mise a jour */
	Strb_Update();

	return ;
}