Mercurial > hg > fxanalyse
view DDS_Fox.c @ 68:64a7a1d3d75c
Cleanup AD9956 DDS driver
author | Daniele Nicolodi <daniele.nicolodi@obspm.fr> |
---|---|
date | Mon, 29 Oct 2012 14:48:14 +0100 |
parents | 2320f5fc66aa |
children | 8e6a2ec85169 |
line wrap: on
line source
#include <tcpsupp.h> #include <ansi_c.h> #include "DDS_Fox.h" // #define DEBUG 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 typedef struct { char* action; char* canal; char* command; char* value0; char* value1; char* value2; char* value3; char* value4; char* value5; char* value6; char* value7; char* value8; char* value9; char* value10; char* value11; char* value12; char* value13; char* value14; char* value15; char* value16; char* value17; char* value18; char* value19; } Command; static int SendCmd(char *Buffer, DDSParameter *Param); static int RecvCmd(Command *Rd, char * Buffer, DDSParameter *Param); static void init_command(Command *cmd); static int parse_command(Command *cmd1, char *buf); static void convert_double_6char (double fraction, unsigned char* octets); #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, frmt); fprintf(stderr, "ERROR: %s:%d:%s: ", file, line, func); vfprintf(stderr, frmt, args); fprintf(stderr, "\n"); va_end(args); } void DDSFox_Initialize(DDSParameter *Param, char *ip, int port, double frequency) { strcpy(Param->ip, ip); Param->Port = 6665; Param->Profil = 7; // configuration profile: single freq=0, sweep=7 Param->Clock = 200000000; Param->Delta_T = 0.01; Param->SweepRate = 0.0; // reset the DDS //DDSFox_Nop(Param); DDSFox_Reset(Param); // set profile number 7 soft frequecy sweep DDSFox_SetProfile(Param); // set clock divider to 1 DDSFox_SetDiv(Param, 1); // set frequency DDSFox_SetFreqInf(Param, frequency); // set frequency upper bound to max value DDSFox_SetFreqMax(Param); // set sweep rate to 0 DDSFox_SetDT(Param); DDSFox_SetDf(Param); DDSFox_SetSweepSign(Param); // start sweep DDSFox_StartSweep(Param); // set frequency lower bound to min value DDSFox_SetFreqMin(Param); return; } void DDSFox_SetSweepRate(DDSParameter *Param, double sweepRate) { Param->SweepRate = sweepRate; DDSFox_SetDf(Param); DDSFox_SetSweepSign(Param); } void DDSFox_Set(DDSParameter *Param, double frequency, double sweepRate) { // set desired frequency DDSFox_SetFreqInf(Param, frequency); // set frequency upper bound to max value DDSFox_SetFreqMax(Param); // set sweep rate to 0 Param->SweepRate = 0.0; DDSFox_SetDT(Param); DDSFox_SetDf(Param); DDSFox_SetSweepSign(Param); // start sweep DDSFox_StartSweep(Param); // set frequency lower bound to min value DDSFox_SetFreqMin(Param); // set desired sweep rate Param->SweepRate = sweepRate; DDSFox_SetDf(Param); DDSFox_SetSweepSign(Param); } void DDSFox_Nop (DDSParameter *Param) { // send NOP command char request[255]; sprintf(request, "set;%i;%i", 1, CMD_NOP); SendCmd(request, Param); } void DDSFox_SetProfile (DDSParameter *Param) { char request[255]; sprintf(request, "set;%i;%i;%i", 1, CMD_PROFILE, Param->Profil); SendCmd(request, Param); } 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) { 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) { 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_SetFreqInf (DDSParameter *Param, double frequency) { double word ; unsigned char octets[6]; char Request[255]; word = pow(2,48)*(frequency / Param->Clock); convert_double_6char(word, octets); 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); } void DDSFox_SetFreqSup (DDSParameter *Param, double frequency) { double word ; unsigned char octets[6]; char Request[255]; word = pow(2,48)*(frequency / Param->Clock); convert_double_6char(word, octets); 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); } static int GetSweepSign(DDSParameter *Param) { if (Param->SweepRate >= 0.0) return 0; return 1; } void DDSFox_SetSweepSign(DDSParameter *Param) { char Request[255] ; int SweepSign ; SweepSign = GetSweepSign(Param) ; sprintf(Request, "set;%i;%i;%i", 1, CMD_SWEEP_SIGN, SweepSign); SendCmd(Request, Param) ; return ; } 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, int div) { char Request[255]; Command Rd; char temp; int Div = 0; // Div = log2(div) while ((div >>= 1) > 1) Div++; 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 ; } double DDSFox_ReadFreq(DDSParameter *Param) { char Request[255]; unsigned int OctetA, OctetB, OctetC, OctetD, OctetE, OctetF ; double FreqRead ; 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); } // TCP communication static unsigned int timeout = 0; // milliseconds int OnTCPEvent(unsigned handle, int xType, int errCode, void *callbackData) { return 0; } static int SendCmd(char *Buffer, DDSParameter *Param) { unsigned int hConv=0; char Response[255]; #ifdef DEBUG fprintf(stderr, "> %s\n", Buffer); #endif if (ConnectToTCPServer (&hConv, Param->Port, Param->ip, OnTCPEvent, Response, timeout) < 0) { error("Connect failed"); return -1; } if (ClientTCPWrite (hConv, Buffer, strlen(Buffer)+1, timeout) < 0) { error("Write failed"); return -1; } sprintf(Response," "); if (ClientTCPRead (hConv, Response, 255, timeout) < 0) { error("Read failed"); return -1; } #ifdef DEBUG fprintf(stderr, "< %s\n", Response); #endif if (strncmp("OK",Response,2)) { error("Response failed %s %s", Buffer, Response); return -1; } return 0; } static int RecvCmd(Command *Rd, char * Buffer, DDSParameter *Param) { unsigned int hConv=0; char parsebuf[255]; char Response[255]; #ifdef DEBUG fprintf(stderr, "> %s\n", Buffer); #endif if (ConnectToTCPServer (&hConv, Param->Port, Param->ip, OnTCPEvent, Response, timeout) < 0) { error("Connect failed"); return -1; } if (ClientTCPWrite (hConv, Buffer, strlen(Buffer)+1, timeout) < 0) { error("Write failed"); return -1; } sprintf(Response," "); if (ClientTCPRead (hConv, Response, 255, timeout) < 0) { error("Read failed"); return -1; } #ifdef DEBUG fprintf(stderr, "< %s\n", Response); #endif 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; } static void init_command(Command *cmd) { memset(cmd, 0, sizeof(Command)); } static 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; } // convert double into 6 bytes sent back by an unsigned char pointer static void convert_double_6char (double fraction, unsigned char* octets) { // 64 bits integer unsigned long long x = fraction; for (int i = 0; i < 6; i++) octets[5 - i] = (unsigned char)((x >> (i * 8)) & 0xFF); }