view ad9912.c @ 258:5296f3bcd160

Implement DDS clients reconnect On network send() failures try to reconnect to the server before returning an error. This allows to restart the network servers controlling the DDSes wiothout having to restart the clients.
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Tue, 16 Jun 2015 14:31:35 +0200
parents 9e0c3541104b
children 6c748ed6a7c5
line wrap: on
line source

#ifdef _CVI_
#include <ansi_c.h>
#include <toolbox.h>
#define usleep(t) Delay((t) / 1000000.0)
#else
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#endif

#include "dds.h"
#include "xsocket.h"
#include "ad9912.h"


int ad9912_init(struct ad9912 *d, const char *hostname, double clock)
{
	int r;
	char buffer[256];

	d->clock = clock;
	d->sock = xsocket(hostname, 1234);
	
 	r = xconnect(d->sock);
	if (r < 0)
		return r;
	
	/* check compatibility */
	r = msend(d->sock, "REVISION", strlen("REVISION"));
	if (r < 0)
		return r;
	r = mrecv(d->sock, buffer, sizeof(buffer));
	if (r < 0)
		return r;
	if (atoi(buffer) != REVISION)
		return -1;

	return 0;
}


int ad9912_set_frequency(struct ad9912 *d, unsigned channel, double f)
{
	int r;
	uint64 value = ftw(d->clock, f);
	
	/* ad9912 ignores ftw last bit */
	value = value & ~1ULL;

	r = command(d->sock, "SET CH%d:FTW0 0x%llX", channel, value);
	if (r < 0)
		return r;

	d->frequency[channel] = freq(d->clock, value);
     
	return 0;
}


int ad9912_get_frequency(struct ad9912 *d, unsigned channel, double *f)
{
	int r, n;
	uint64 value;
	char buffer[256];

	n = snprintf(buffer, sizeof(buffer), "GET CH%d:FTW0", channel);

	r = msend(d->sock, buffer, n);
	if (r < 0)
		return r;

	r = mrecv(d->sock, buffer, sizeof(buffer));
	if (r < 0)
		return r;

	r = strtouint64(buffer, &value);
	if (r < 0)
		return r;

	d->frequency[channel] = freq(d->clock, value);
	if (f)
		*f = d->frequency[channel];

	return 0;
}


/**
 * Ramp DDS frequency from @f1 to @f2 in steps @fstep with 0.01
 * seconds delay after each step.
 */
int ad9912_ramp_frequency2(struct ad9912 *d, unsigned channel, double f1, double f2, double fstep)
{
	const int delay = 10000;
	
	/* f2 > f1 */
	while ((f2 - f1) > fstep) {
		f1 += fstep;
		ad9912_set_frequency(d, channel, f1);
		usleep(delay);
	}
	
	/* f2 < f1 */
	while ((f1 - f2) > fstep) {
		f1 -= fstep;
		ad9912_set_frequency(d, channel, f1);
		usleep(delay);
	}
	
	/* final adjustment */
	ad9912_set_frequency(d, channel, f2);
	
	return 0;
}


int ad9912_ramp_frequency(struct ad9912 *d, unsigned channel, double f, double fstep)
{
	return ad9912_ramp_frequency2(d, channel, d->frequency[channel], f, fstep);
}