summaryrefslogtreecommitdiff
path: root/dds.c
blob: fe6a35df22f6501b2ee17d4e91e576bf35a4885d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <stdbool.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include "dds.h"

#define IIODEVICEPATH "/sys/bus/iio/devices/iio:device"
#define DACIIODEVICE "0"
#define DDSIIODEVICE "1"

#define DDSFREQNODE "dds0_freq0"
#define DDSOUTPUTENABLENODE "dds0_out_enable"
#define DDSSQOUTPUTENABLENODE "dds0_out1_enable"
#define DDSWAVETYPENODE "dds0_out0_wavetype"
#define DDSWAVETYPESINE "sine\n"
#define DDSWAVETYPETRI "triangle\n"

#define DACSCALENODE "out_voltage_scale"
#define DACOUTPUTNODE "out_voltage0_raw"

#define ENABLE "1\n"
#define DISABLE "0\n"

void dds_setamplitude(float millivolts)
{
	int scalefd = open(IIODEVICEPATH""DACIIODEVICE"/"DACSCALENODE, O_RDONLY);
	int outputfd = open(IIODEVICEPATH""DACIIODEVICE"/"DACOUTPUTNODE, O_WRONLY);

	if (outputfd < 0 || scalefd < 0) {
		printf("Couldn't open one or more of the control nodes for the dac\n");
	}

	// read the scale value and turn it into a float
	float scale = 0;
	char scalebuff[64];

	if (read(scalefd, scalebuff, sizeof(scalebuff))) {
		sscanf(scalebuff, "%10f\n", &scale); // the string should be ?.??? but round up the width a bit just in case
	}

	if (scale == 0) {
		printf("couldn't read scale or scale is invalid\n");
		return;
	}

	// create a buffer with the scaled millivolt value and write it
	char outputbuff[64];
	int outputchars = snprintf(outputbuff, sizeof(outputbuff), "%d\n", (int) (millivolts / scale));
	write(outputfd, outputbuff, outputchars);

	close(scalefd);
	close(outputfd);
}

void dds_setupwave(int frequency, bool squarewaveoutput, bool triangle)
{
	int wavetypefd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSWAVETYPENODE, O_WRONLY);
	int outputenablefd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSOUTPUTENABLENODE, O_WRONLY);
	int sqwaveenablefd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSSQOUTPUTENABLENODE, O_WRONLY);
	int freqfd = open(IIODEVICEPATH""DDSIIODEVICE"/"DDSFREQNODE, O_WRONLY);

	if (wavetypefd < 0 || outputenablefd < 0 || sqwaveenablefd < 0 || freqfd < 0) {
		printf("Couldn't open one or more of the control nodes for the dds\n");
		return;
	}

	if (triangle) {
		// squarewave output on the signbit out pin can't be selected at the same time as triangle wave
		write(sqwaveenablefd, DISABLE, sizeof(DISABLE));
		write(wavetypefd, DDSWAVETYPETRI, sizeof(DDSWAVETYPETRI));
	} else {
		// enable/disable the square wave ouput and reset the wavetype
		write(sqwaveenablefd, squarewaveoutput ? ENABLE : DISABLE, squarewaveoutput ? sizeof(ENABLE) : sizeof(DISABLE));
		write(wavetypefd, DDSWAVETYPESINE, sizeof(DDSWAVETYPESINE));
	}

	// generate a buffer with the frequency and set it
	char freqbuff[64];
	int freqchars = snprintf(freqbuff, sizeof(freqbuff), "%d\n", frequency);
	write(freqfd, freqbuff, freqchars);

	write(outputenablefd, ENABLE, sizeof(ENABLE));

	close(sqwaveenablefd);
	close(wavetypefd);
	close(freqfd);
	close(outputenablefd);
}