Mercurial > hg > fxanalyse
view DDS_Fox.c @ 45:b47b97cfd050
Fix output frequency read back in DDS Fox driver
The FTW registry value was read back wrong due to an integer overflow in the
conversion from bytes string to double. This should fix the "jumps" seen in the
application of the frequency dedrifting.
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Wed, 10 Oct 2012 12:14:01 +0200 |
parents | e45d6e9544f5 |
children | 7ab3fb870ef8 |
line wrap: on
line source
#include <tcpsupp.h> #include <ansi_c.h> #include "DDS_Fox.h" //#define DDS_IP "192.168.0.3" //#define TCP_PORT 6665 #define DIV 0 // divided by 1 #define CMD_SEP ";" #define BASE_TIME 0.01 #define CMD_CONFIG_REG1 1 // cmd d'acces direct au rergistre 1 de config de la DDS (voir datasheet) #define CMD_CONFIG_REG2 2 // cmd d'acces direct au rergistre 1 de config de la DDS (voir datasheet) #define CMD_SINGLE_FREQ_PROF0 7 #define CMD_PROFILE 15 // cmd de choix du profile de fonctionnement de la DDS (voir datasheet) #define CMD_ATTENUATION 16 #define CMD_RESET_DDS 17 #define CMD_NOP 20 #define CMD_FREQ_INF 21 #define CMD_FREQ_SUP 22 #define CMD_DF 23 #define CMD_DT 24 #define CMD_START_SWEEP 25 #define CMD_STOP_SWEEP 26 #define CMD_GET_FREQ 28 #define CMD_SWEEP_SIGN 29 /************************* Global variables ***********************************/ //static char Request[255]; /************************* My own functions ***********************************/ /*DDSParameter DDSGetParam (int panel, int control) { DDSParameter Parameter ; GetCtrlVal (panel, CONTROL_DDS_IP, Parameter->ip) ; GetCtrlVal (panel, CONTROL_DDS_PORT, &(Parameter->Port)) ; GetCtrlVal (panel, CONTROL_DDS_CLOCK, &(Parameter->Clock)) ; GetCtrlVal (panel, CONTROL_DDS_RATE, &(Parameter->SweepRate)) ; GetCtrlVal (panel, CONTROL_DDS_DELTA_T, &(Parameter->Delta_T)) ; return(Parameter); }*/ #define error(...) _error(__FILE__, __LINE__, __func__, __VA_ARGS__) void _error(const char *file, int line, const char *func, const char *frmt, ...) { va_list args; va_start(args, line); fprintf(stderr, "ERROR: %s:%d:%s: ", file, line, func); vfprintf(stderr, frmt, args); fprintf(stderr, "\n"); va_end(args); } void DDS_Initialize (DDSParameter *Param) { char Request[255]; //send NOP command sprintf(Request,"set;%i;%i",1,CMD_NOP); SendCmd(Request, Param) ; //reset the DDS DDSFox_Reset(Param); //Set Profile Number 0 (only one used for soft frequecy sweep) // sprintf(Request,"set;%i;%i;%i",1,CMD_PROFILE,0); // SendCmd(Request, Param) ; //Set Profile Number 7 (only one used for soft frequecy sweep) sprintf(Request,"set;%i;%i;%i",1,CMD_PROFILE,7); SendCmd(Request, Param) ; //Set Clock Divider to 00b (which means 1) DDSFox_SetDiv(Param); //Set sweep rate at 0 DDSFox_SetFreqMax (Param); DDSFox_SetFreq (Param) ; DDSFox_SetDT (Param) ; DDSFox_SetDf (Param) ; DDSFox_StartSweep (Param) ; return ; } void DDS_ReInitialize (DDSParameter *Param) { char Request[255]; //send NOP command sprintf(Request,"set;%i;%i",1,CMD_NOP); SendCmd(Request, Param) ; //reset the DDS //DDSFox_Reset(Param); //Set Profile Number 0 (only one used for soft frequecy sweep) // sprintf(Request,"set;%i;%i;%i",1,CMD_PROFILE,0); // SendCmd(Request, Param) ; //Set Profile Number 7 (only one used for soft frequecy sweep) sprintf(Request,"set;%i;%i;%i",1,CMD_PROFILE,7); SendCmd(Request, Param) ; //Set Clock Divider to 00b (which means 1) DDSFox_SetDiv(Param); //Set sweep rate at 0 DDSFox_SetFreqMax (Param); DDSFox_SetFreq (Param) ; DDSFox_SetDT (Param) ; DDSFox_SetDf (Param) ; DDSFox_StartSweep (Param) ; return ; } void DDSFox_Reset(DDSParameter *Param) { char Request[255]; sprintf(Request,"set;%i;%i",1,CMD_NOP); SendCmd(Request, Param) ; sprintf(Request,"set;%i;%i",1,CMD_RESET_DDS); SendCmd(Request, Param) ; return ; } void DDSFox_StopSweep(DDSParameter *Param) { char Request[255]; sprintf(Request,"set;%i;%i;%i",1,CMD_STOP_SWEEP,1); SendCmd(Request, Param); return ; } void DDSFox_StartSweep(DDSParameter *Param) { char Request[255]; sprintf(Request,"set;%i;%i;%i",1,CMD_START_SWEEP,1); SendCmd(Request, Param); return ; } void DDSFox_SetFreqMax (DDSParameter *Param) { double word ; unsigned char octets[6]; char Request[255]; convert_double_6char(pow(2,48)/2,octets); // borne sup : clock / 2 sprintf(Request,"set;%i;%i;%i;%i;%i;%i;%i;%i",1,CMD_FREQ_SUP, *(octets+5),*(octets+4),*(octets+3),*(octets+2),*(octets+1),*octets); SendCmd(Request, Param); DDSFox_SetSweepSign (Param); return ; } void DDSFox_SetFreqMin (DDSParameter *Param) { double word ; unsigned char octets[6]; char Request[255]; convert_double_6char(1,octets); // borne inf : ~0 sprintf(Request,"set;%i;%i;%i;%i;%i;%i;%i;%i",1,CMD_FREQ_INF, *(octets+5),*(octets+4),*(octets+3),*(octets+2),*(octets+1),*octets); SendCmd(Request, Param); DDSFox_SetSweepSign (Param); return ; } void DDSFox_SetFreq (DDSParameter *Param) { double word ; unsigned char octets[6]; int SweepSign = -1 ; char Request[255]; if (Param->Profil == 0) { word = pow(2,48)*(Param->Frequency/Param->Clock); convert_double_6char(word, octets); // borne inf : la freq voulu sprintf(Request,"set;%i;%i;%i;%i;%i;%i;%i;%i",1,CMD_FREQ_INF, *(octets+5),*(octets+4),*(octets+3),*(octets+2),*(octets+1),*octets); SendCmd(Request, Param); } else if(Param->Profil == 7) { SweepSign = DDSFox_GetSweepSign(Param) ; if(SweepSign == 0){ // sweep positif word = pow(2,48)*(Param->Frequency/Param->Clock); convert_double_6char(word, octets); // borne inf : la freq voulu sprintf(Request,"set;%i;%i;%i;%i;%i;%i;%i;%i",1,CMD_FREQ_INF, *(octets+5),*(octets+4),*(octets+3),*(octets+2),*(octets+1),*octets); SendCmd(Request, Param); DDSFox_SetFreqMax (Param); } else { // sweep neg word = pow(2,48)*(Param->Frequency/Param->Clock); convert_double_6char(word, octets); // borne sup : la freq voulue sprintf(Request,"set;%i;%i;%i;%i;%i;%i;%i;%i",1,CMD_FREQ_SUP, *(octets+5),*(octets+4),*(octets+3),*(octets+2),*(octets+1),*octets); SendCmd(Request, Param); DDSFox_SetFreqMin (Param); } } return ; } // Change le signe de sweep en frequence. Argument: struct de param de la DDS void DDSFox_SetSweepSign(DDSParameter *Param) { char Request[255] ; int SweepSign ; SweepSign = DDSFox_GetSweepSign(Param) ; sprintf(Request,"set;%i;%i;%i",1,CMD_SWEEP_SIGN, SweepSign) ; SendCmd(Request, Param) ; return ; } /*void DDSFox_SetSweepSign(DDSParameter *Param) { char Request[255] ; int SweepSign ; if (Param->Profil == 7) Param->Frequency = DDSFox_ReadFreq(Param) ; DDSFox_SetFreq (Param) ; SweepSign = DDSFox_GetSweepSign(Param) ; sprintf(Request,"set;%i;%i;%i",1,CMD_SWEEP_SIGN, SweepSign) ; SendCmd(Request, Param) ; return ; }*/ // Change la valeur de la base pour 'lincrement de frequence (sweep). Argument: delta T x 10ms, retourne rien. void DDSFox_SetDT(DDSParameter *Param) { char Request[255]; int dt= 0; char FTW0[255]="0"; /**** sinon le fichier inf.xx est faux ***/ dt = ((Param->Delta_T)/BASE_TIME) - 1 ; sprintf(FTW0,"%ims",dt); sprintf(Request,"set;%i;%i;%i;%s",1,CMD_DT, dt ,FTW0); SendCmd(Request, Param) ; return ; } // Change le facteur de division de la clock. Argument: facteur de div, retourne rien void DDSFox_SetDiv(DDSParameter *Param) { char Request[255]; int Div = DIV ; Command Rd; char temp; init_command(&Rd); sprintf(Request,"get;%i;%i",1,CMD_CONFIG_REG2); if (RecvCmd(&Rd, Request, Param) < 0) return; temp = atoi(Rd.value2) ; temp = temp & 0x9F ; temp = temp | Div << 5 ; sprintf(Request,"set;%i;%i;%i;%i;%i;%i;%i",1,CMD_CONFIG_REG2,atoi(Rd.value0), atoi(Rd.value1),temp,atoi(Rd.value3),atoi(Rd.value4)) ; SendCmd(Request, Param) ; return ; } void DDSFox_SetDf(DDSParameter *Param) { char Request[255]; double word ; unsigned char *octets; word = pow(2,48)*(fabs(Param->SweepRate)*Param->Delta_T/Param->Clock); octets=malloc(6*sizeof(unsigned char)); convert_double_6char(word, octets); sprintf(Request,"set;%i;%i;%i;%i;%i;%i;%i;%i",1,CMD_DF, *(octets+5),*(octets+4),*(octets+3),*(octets+2),*(octets+1),*octets); SendCmd(Request, Param); free(octets); return ; } int DDSFox_GetSweepSign(DDSParameter *Param) { if (Param->SweepRate >= 0) return(0); else return(1); } double DDSFox_ReadFreq(DDSParameter *Param) { char Request[255]; unsigned int OctetA, OctetB, OctetC, OctetD, OctetE, OctetF ; double FreqRead ; int cmd[20]; Command Rd; init_command(&Rd); sprintf(Request,"get;%i;%i",1,CMD_GET_FREQ); if (RecvCmd(&Rd, Request, Param) == -1) return -1.; OctetA=atoi(Rd.value0); OctetB=atoi(Rd.value1); OctetC=atoi(Rd.value2); OctetD=atoi(Rd.value3); OctetE=atoi(Rd.value4); OctetF=atoi(Rd.value5); FreqRead = 1099511627776.0 * OctetA + 4294967296.0 * OctetB + 16777216.0 * OctetC + 65536.0 * OctetD + 256.0 * OctetE + 1.0 * OctetF; FreqRead = FreqRead * Param->Clock / pow(2,48); return(FreqRead); } /************************ Fonction de communications TCP ******************/ static const double timeout = 0.5; int SendCmd(char *Buffer, DDSParameter *Param) { unsigned int hConv=0; char Response[255]; char parsebuf[255]; if (ConnectToTCPServer (&hConv, Param->Port, Param->ip, OnTCPEvent, Response, 0) < 0) { error("Connect failed"); return -1; } if (ClientTCPWrite (hConv, Buffer, strlen(Buffer)+1, 0) < 0) { error("Write failed"); return -1; } sprintf(Response," "); if (ClientTCPRead (hConv, Response, 255, 0) < 0) { error("Read failed"); return -1; } if (strncmp("OK",Response,2)) { error("Response failed %s %s", Buffer, Response); return -1; } return 0; } int RecvCmd(Command *Rd, char * Buffer, DDSParameter *Param) { unsigned int hConv=0; char parsebuf[255]; char Response[255]; if (ConnectToTCPServer (&hConv, Param->Port, Param->ip, OnTCPEvent, Response, 0) < 0) { error("Connect failed"); return -1; } if (ClientTCPWrite (hConv, Buffer, strlen(Buffer)+1, 0) < 0) { error("Write failed"); return -1; } sprintf(Response," "); if (ClientTCPRead (hConv, Response, 255, 0) < 0) { error("Read failed"); return -1; } if (strncmp(Buffer,Response,strlen(Buffer))) { error("Response failed %s %s", Buffer, Response); return -1; } sprintf(parsebuf,"%s",Response) ; parse_command(Rd, parsebuf) ; return 0; } int OnTCPEvent(unsigned handle, int xType, int errCode, void *callbackData) { //char* Response = (char*)(callbackData); //char Response[255]; //switch(xType) { // case TCP_DISCONNECT : //printf("Server disconnected\n"); // break; // case TCP_DATAREADY : //printf("Server data ready\n"); //ClientTCPRead (handle, Response, 255, 5); // break; //} return 0; } /************************ Fonction de mise en forme des données pour le transfert ******************/ void parse_command2(int* cmd, char* buf) { char* pointer; int c = 0; pointer = strtok( buf, CMD_SEP ); while( pointer ){ if ((c > 2) && ( c < 19 )) { cmd[c-3] = atoi(pointer); printf("%i", cmd[c-3]); } pointer = strtok( NULL, CMD_SEP ); c++; } } int parse_command(Command *cmd1, char *buf){ char* pointer; int c = 0; pointer = strtok( buf, CMD_SEP ); while( pointer ){ if( c == 0 ){ cmd1->action = pointer; } else if( c == 1 ){ cmd1->canal = pointer; } else if( c == 2 ){ cmd1->command = pointer; } else if( c == 3 ){ cmd1->value0 = pointer; } else if( c == 4 ){ cmd1->value1 = pointer; } else if( c == 5 ){ cmd1->value2 = pointer; } else if( c == 6 ){ cmd1->value3 = pointer; } else if( c == 7 ){ cmd1->value4 = pointer; } else if( c == 8 ){ cmd1->value5 = pointer; } else if( c == 9 ){ cmd1->value6 = pointer; } else if( c == 10 ){ cmd1->value7 = pointer; } pointer = strtok( NULL, CMD_SEP ); c++; } return 0; } int init_command(Command *cmd1){ cmd1->action = NULL; cmd1->canal = NULL; cmd1->command = NULL; cmd1->value0 = NULL; cmd1->value1 = NULL; cmd1->value2 = NULL; cmd1->value3 = NULL; cmd1->value4 = NULL; cmd1->value5 = NULL; cmd1->value6 = NULL; cmd1->value7 = NULL; cmd1->value8 = NULL; cmd1->value9 = NULL; cmd1->value10 = NULL; cmd1->value11 = NULL; cmd1->value12 = NULL; cmd1->value13 = NULL; cmd1->value14 = NULL; cmd1->value15 = NULL; cmd1->value16 = NULL; cmd1->value17 = NULL; cmd1->value18 = NULL; cmd1->value19 = NULL; return 0; } //Convert double into 6 bytes sent back by an unsigned char pointer int convert_double_6char (double fraction, unsigned char* octets) { double bita, bitb, bitc, bitd, bite, bitf; bitf= fraction/(1099511627776.0); *(octets+5)=(unsigned char)bitf; bite= (fraction-1099511627776.0*(*(octets+5)))/(4294967296.0); *(octets+4)=(unsigned char)bite; bitd=(fraction-1099511627776.0*(*(octets+5))- 4294967296.0*(*(octets+4)))/( 16777216.0); *(octets+3)=(unsigned char)bitd; bitc=(fraction-1099511627776.0*(*(octets+5))- 4294967296.0*(*(octets+4))-16777216.0*(*(octets+3)))/( 65536.0); *(octets+2)=(unsigned char)bitc; bitb= (fraction-1099511627776.0*(*(octets+5))- 4294967296.0*(*(octets+4))-16777216.0*(*(octets+3))-65536*(*(octets+2)))/ 256.0; *(octets+1)=(unsigned char)bitb; bita= (fraction-1099511627776.0*(*(octets+5))- 4294967296.0*(*(octets+4))-16777216.0*(*(octets+3))-65536*(*(octets+2))-256.0*(*(octets+1)))/ 1.0; *(octets)=(unsigned char)bita; return 0; }