Commit dfa91a3bc3fea741b18f1a2f3e1bb0d695444b33

Authored by pyb
1 parent cc228d59b9
Exists in master

libad9915 : add initial sources & include files

Showing 6 changed files with 541 additions and 0 deletions Inline Diff

File was created 1 /*
2 dds initialisation et SPI
3 */
4
5 #include <stdint.h>
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <getopt.h>
10 #include <fcntl.h>
11 #include <sys/ioctl.h>
12 #include <linux/types.h>
13 #include <linux/spi/spidev.h>
14 /* memory management */
15 #include <sys/mman.h>
16 #include "spi.h"
17 #include <string.h>
18 #include <math.h>
19 #include <time.h>
20
21
22 static const char CFRAddress[] = {0x00,0x01,0x02,0x03};
23
24 static const char CFR1Start[] ={0x00, 0x01, 0x00, 0x0a};
25 //static const char CFR1Start[] ={0x00, 0x01, 0x01, 0x08}; //with osk enable
26 static const char CFR2Start[] ={0x00, 0x80, 0x09, 0x00}; //0x80 enable prof mode
27 static const char CFR3Start[] = {0x00, 0x00, 0x19, 0x1C};
28 static const char CFR4Start[] = {0x00, 0x05, 0x21, 0x20};
29
30 static const char USR0Address = 0x1B;
31 static const char FTW0Address = 0x0b; //profile 0 ftw
32 static const char PA0Address = 0x0c; //profile 0
33
34 static const char DACCalEnable[] = {0x01, 0x05, 0x21, 0x20}; //Command to enable the DAC Cal, should be 0x01XXXXXX, where X is the last 6 digits of CFR4Start
35
36
37 void Send_Reset(int f_dds);
38 void Send_IO_Update (int f_dds); //Send the update to set the control registers
39 void write_register (int fd, unsigned char addr, unsigned char d3, unsigned char d2, unsigned char d1, unsigned char d0);
40 void Initialize_DDS (int fd, int f_dds);
File was created 1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <math.h>
5
6 struct frac
7 {
8 long double numerator;
9 long double denominator;
10 };
11
12 long double pgcd ( long double m , long double n);
File was created 1 #ifndef SPI_H
2 #define SPI_H
3
4 int configureSpi(char *device);
5 uint16_t transfer(int fd, uint16_t valeur, int truc);
6 uint8_t spi_put(int fd, uint8_t valeur);
7 uint8_t spi_put_multiple(int fd, uint8_t *tx, uint16_t tx_size,
8 uint8_t *rx, uint16_t rx_size);
9 void setMode(int fd, uint8_t mode);
10 uint8_t tr2(int fd, uint8_t val);
11 uint8_t tr3(int fd, uint8_t *val, uint8_t *rx, uint8_t size);
12 int configureSpiFromFd (int fd);
File was created 1 /*
2 SPI : initialisation du dds et communication SPI
3 */
4 #include"ad9915.h"
5 #include "spi.h"
6 #include "ddsFreq.h"
7
8 #define debug
9 //fonction reset
10 void Send_Reset(int f_dds)
11 {
12 char reset='2';
13 write(f_dds,&reset,sizeof(reset)); //reset
14 sleep(0.1);
15 }
16
17 //fonction ioupdate
18 void Send_IO_Update(int f_dds)
19 {
20 char update='1';
21 write(f_dds,&update,sizeof(update)); //reset
22 sleep(0.1);
23 }
24
25 //fonction write register
26 void write_register (int fd, unsigned char addr, unsigned char d3, unsigned char d2, unsigned char d1, unsigned char d0)
27 {
28 unsigned char tx[5]={0};
29 tx[0]=addr;
30 tx[1]=d3;
31 tx[2]=d2;
32 tx[3]=d1;
33 tx[4]=d0;
34 //spi_put_multiple envoie le vecteur dans cet ordre
35 //[tx0]-[tx1]-[tx2] -> adresse->bit poids Fort->bit poids faible
36 spi_put_multiple(fd,tx,5,NULL,0);
37 }
38
39 //initialisation du dds
40 void Initialize_DDS (int fd, int f_dds)
41 {
42 Send_Reset(f_dds);
43 write_register(fd,CFRAddress[0],CFR1Start[0], CFR1Start[1], CFR1Start[2], CFR1Start[3]);
44 Send_IO_Update (f_dds); //Send the update to set the control registers
45 write_register(fd,CFRAddress[1], CFR2Start[0], CFR2Start[1], CFR2Start[2], CFR2Start[3]);
46 Send_IO_Update (f_dds);
47 write_register(fd,CFRAddress[2], CFR3Start[0], CFR3Start[1], CFR3Start[2], CFR3Start[3]);
48 Send_IO_Update (f_dds);
49 write_register(fd,CFRAddress[3], CFR4Start[0], CFR4Start[1], CFR4Start[2], CFR4Start[3]);
50 Send_IO_Update (f_dds);
51 write_register(fd,USR0Address, 0xA2, 0x00, 0x08, 0x00);
52 Send_IO_Update (f_dds);
53 }
54
55 //calibration du dac
56 void Calibrate_DAC (int fd, int f_dds)
57 {
58 write_register(fd,CFRAddress[3], DACCalEnable[0], DACCalEnable[1], DACCalEnable[2], DACCalEnable[3]);
59 Send_IO_Update (f_dds);
60 write_register(fd,CFRAddress[3], CFR4Start[0], CFR4Start[1], CFR4Start[2], CFR4Start[3]);
61 Send_IO_Update (f_dds);
62 }
63
64 void modulus_setup(int fd, int f_dds)
65 {
66 write_register(fd,0x00,0x00, 0x01, 0x01, 0x08); //OSK enable
67 Send_IO_Update (f_dds);
68 write_register(fd,0x01,0x00, 0x89, 0x09, 0x00); //enable program modulus and digital ramp
69 Send_IO_Update (f_dds);
70 }
71
72 void basic_setup(int fd, int f_dds,uint16_t ampWord, uint16_t phaseWord)
73 {
74 write_register(fd,0x00,0x00, 0x01, 0x01, 0x08); //OSK enable
75 Send_IO_Update (f_dds);
76 write_register(fd,0x01,0x00, 0x89, 0x09, 0x00); //enable program modulus and digital ramp
77 Send_IO_Update (f_dds);
78 write_register(fd,0x04,0x19, 0x99, 0x99, 0x99); //ftw
79 Send_IO_Update (f_dds);
80 write_register(fd,0x05,0xC0, 0x00, 0x00, 0x00); //A
81 Send_IO_Update (f_dds);
82 write_register(fd,0x06,0x00, 0x00, 0x00, 0x05); //B
83 Send_IO_Update (f_dds);
84 //write_register(fd,0x0c, 0x0F, 0xFF, 0x00, 0x00); // amp (12b) ph(16)
85 write_register(fd,0x0c, (uint8_t)((ampWord>>8) & 0x0F), (uint8_t)(ampWord & 0xFF), (uint8_t)((phaseWord>>8) & 0xFF), (uint8_t)(phaseWord & 0xFF)); // amp (12b) ph(16)
86 Send_IO_Update (f_dds);
87 }
88
89 void setFreqMM(int fd, int f_dds, unsigned int ftw, unsigned int A, unsigned int B)
90 {
91 //uint16_t phaseWord = 0x7400;
92 //uint16_t ampWord = (uint16_t)strtol(argv[4],NULL,0) & 0x0FFF ; //masque en 2
93 //uint16_t ampWord = 0x00000FFF;
94 //uint32_t phaseAmpWord = phaseWord | ampWord<<16;
95
96 //write_register(fd,0x00,0x00, 0x01, 0x01, 0x08); //OSK enable
97 //Send_IO_Update(f_dds);
98 //write_register(fd,0x01,0x00, 0x89, 0x09, 0x00); //enable program modulus and digital ramp
99 //Send_IO_Update(f_dds);
100 write_register(fd,0x04,ftw>>24&0xFF, ftw>>16&0xFF, ftw>>8&0xFF, ftw&0xFF); //ftw
101 Send_IO_Update(f_dds);
102 write_register(fd,0x05,A>>24&0xFF,A>>16&0xFF, A>>8&0xFF, A&0xFF); //A
103 Send_IO_Update(f_dds);
104 write_register(fd,0x06,B>>24&0xFF,B>>16&0xFF, B>>8&0xFF, B&0xFF); //B
105 Send_IO_Update(f_dds);
106 // write_register(fd,0x0c, phaseAmpWord>>24&0xFF, phaseAmpWord>>16&0xFF,phaseAmpWord>>8&0xFF,phaseAmpWord&0xFF); // amp (12b) ph(16)
107 //Send_IO_Update(f_dds);
108 }
109
110 void setAmpPhaseWord(int fd, int f_dds,unsigned int phaseAmpWord)
111 {
112 write_register(fd,0x0c, phaseAmpWord>>24&0xFF, phaseAmpWord>>16&0xFF,phaseAmpWord>>8&0xFF,phaseAmpWord&0xFF); // amp (12b) ph(16)
113 Send_IO_Update(f_dds);
114 }
115
116
117 int openAndSetDdsFreq( char * device, char * gpio_update, double f_clk, double f_out, uint16_t ampWord, uint16_t phaseWord)
118 {
119 #ifdef debug
120 printf("device=%s\tgpio_update=%s\tf_clk=%e\tf_out=%e\tampWord=%d\tphaseWord=%d\n\n",device,gpio_update,f_clk,f_out,ampWord,phaseWord);
121 #else
122 printf("device=%s\tgpio_update=%s\tf_clk=%e\tf_out=%e\tampWord=%d\tphaseWord=%d\n\n",device,gpio_update,f_clk,f_out,ampWord,phaseWord);
123 int fd=configureSpi(device); //ex #define FILENAME2 "/dev/spidev0.0"
124 printf("fd(funct)=%d\n",fd);
125 setMode(fd,SPI_MODE_0);
126 if (fd <= 0){
127 printf("ERREUR : ouverture pรฉriphรฉrique SPI %s\n",device);
128 return EXIT_FAILURE;
129 }
130 int f_dds=open(gpio_update,O_RDWR); //ex #define UPDATE2 "/sys/dds/gpio24/updateOn"
131 printf("f_dds(funct)=%d\n",f_dds);
132 if (f_dds <= 0){
133 printf("ERREUR : ouverture ");printf(gpio_update);printf("\n");
134 printf("Chargez le module ddsIOupdateX\n");
135 return EXIT_FAILURE;
136 }
137 setddsFreq(fd,f_dds,f_out,f_clk);
138 //debug
139 phaseWord = 0x0000;
140 ampWord=0x0FFF;
141 uint32_t phaseAmpWord = phaseWord | ampWord<<16;
142 setAmpPhaseWord(fd, f_dds, phaseAmpWord);
143 #endif
144 return EXIT_SUCCESS;
145 }
146
147 int setDdsFreqFull ( int fd, int f_dds, double f_clk, double f_out, uint16_t ampWord, uint16_t phaseWord)
148 {
File was created 1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <math.h>
5 #include "ddsFreq.h"
6 #include "ad9915.h"
7
8 //#define debug
9 long double pgcd ( long double m , long double n)
10 {
11 if (fmod(m,n) ==0)
12 return n;
13 return pgcd(n,fmod(m,n));
14 }
15
16 int setddsFreq(int fd, int f_dds, long double f0, long double fs)
17 {
18
19 #ifdef debug
20 printf("f0=%Le\tfs=%Le\n",f0,fs);
21 #endif
22
23 if (fs<0 || f0<0) return EXIT_FAILURE;
24
25 struct frac f1;
26
27 f1.numerator = f0;
28 f1.denominator = fs;
29
30 long double d1 = pgcd (f1.numerator , f1.denominator );
31 //printf(" d1 = %24.16Lf\n",d1);
32
33 long double M = f0 / d1 ;
34 long double N = fs / d1 ;
35 //printf(" M = f0 / d1 = %24.16Lf\n",M);
36 //printf(" N = fs / d1 = %24.16Lf\n",N);
37
38
39 long double ftw = M * scalbn(1.0,32);
40 ftw /= N;
41 //printf("ftw = %24.16Lf\n",ftw);
42
43
44 //printf("X=floor(ftw) = %24.16Lf\n",(long double)floor(ftw));
45
46 long double Y = M * scalbn(1.0,32);
47 Y -= N * floor(ftw);
48 //printf("Y=M*2**32-X*N = %24.16Lf\n",Y);
49
50 long double d2 = pgcd (Y,N);
51 //printf(" d2 = %24.16Lf\n",d2);
52
53 long double A = Y / d2;
54 long double B = N / d2;
55 //printf("A = Y/d2 = %24.16Lf\n",A);
56 //printf("B = N/d2 = %24.16Lf\n",B);
57
58 //printf("f0 = (M/N) * fclk= %24.32Lf\n",fs*M/N);
59 //printf("f0 = (X+A/B)2**32= %24.32Lf\n",fs*(floor(ftw)+A/B)/scalbn(1.0,32));
60
61 #ifdef debug
62 printf("\n so finally the programmed registers are :\n"
63 "ftw= 0x%08x A= 0x%08x B= 0x%08x\n"
64 "",(unsigned int)ftw,(unsigned int)A,(unsigned int)B);
65 printf("uint ftw = %d\n",(unsigned int)ftw);
66
67 printf("\n 0x%08x 0x%08x 0x%08x \n\n",(unsigned int)ftw,(unsigned int)A,(unsigned int)B);
68 //setFreqMM(fd,f_dds,(unsigned int)ftw, (unsigned int)A, (unsigned int)B);
69 #endif
70 setFreqMM(fd,f_dds,(unsigned int)ftw, 2*(unsigned int)B, 2*(unsigned int)A); //??why *2??
71 return EXIT_SUCCESS;
72 }
73 int ddsFreq(int fd, int f_dds)
74 {
75 //checkSize();
76 long double f0,fs;
77 //printf("long = %lu\n",sizeof (long));
78 //printf("float = %lu\n",sizeof (float));
79 //printf("double = %lu\n",sizeof (double));
80 //printf("long double = %lu\n",sizeof (long double));
81
82 printf("\nDesired output Frequency (MHz) : ");
83 scanf("%Lf",&f0);
84 printf("DDS frequency Clock (MHz) : ");
85 scanf("%Lf",&fs);
86
87 //long double f0=atof(argv[1]); //desired output freq
88 //long double fs=atof(argv[2]); //dds_clk
89 //int toto = (int)strtol(argv[3],NULL,0);
90 //printf("toto=%d\t%x\n",toto,toto);
91
92 if (fs<0 || f0<0) return EXIT_FAILURE;
93
94 struct frac f1;
95
96 f1.numerator = f0;
97 f1.denominator = fs;
98
99 long double d1 = pgcd (f1.numerator , f1.denominator );
100 printf(" d1 = %24.16Lf\n",d1);
101
102 long double M = f0 / d1 ;
103 long double N = fs / d1 ;
104 printf(" M = f0 / d1 = %24.16Lf\n",M);
File was created 1 #include <stdint.h>
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <getopt.h>
6 #include <fcntl.h>
7 #include <sys/ioctl.h>
8 #include <linux/types.h>
9 #include <linux/spi/spidev.h>
10 /* memory management */
11 #include <sys/mman.h>
12 #include "spi.h"
13 #include <string.h>
14
15 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
16
17 #undef DEBUG
18 //#define DEBUG
19 static uint8_t bits = 8;
20 //static uint32_t speed = 15000000; // 9600;
21 //static uint32_t speed = 20000000; // 9600;
22 static uint32_t speed = 10000000;
23 //static uint32_t speed = 100000; // 9600;
24 //static uint16_t delay;
25 static void
26 pabort (const char *s)
27 {
28 perror (s);
29 abort ();
30 }
31
32 uint8_t
33 spi_put_multiple (int fd, uint8_t * tx, uint16_t tx_size,
34 uint8_t * rx, uint16_t rx_size)
35 {
36 int ret;
37 int nb = 2;
38 if (rx_size == 0 || tx_size == 0)
39 nb = 1;
40 struct spi_ioc_transfer xfer[nb];
41 nb = 0;
42 memset (xfer, 0, sizeof (xfer));
43 if (tx_size > 0)
44 {
45 xfer[nb].tx_buf = (unsigned long) tx;
46 xfer[nb].len = tx_size;
47 nb++;
48 }
49 if (rx_size > 0)
50 {
51 xfer[nb].rx_buf = (unsigned long) rx;
52 xfer[nb].len = rx_size;
53 nb++;
54 }
55 ret = ioctl (fd, SPI_IOC_MESSAGE (nb), xfer);
56 return ret;
57 }
58
59 uint8_t
60 tr3 (int fd, uint8_t * val, uint8_t * rx, uint8_t size)
61 {
62 int ret;
63
64 struct spi_ioc_transfer xfer[2];
65 memset (xfer, 0, sizeof (xfer));
66
67 xfer[0].tx_buf = (unsigned long) val;
68 xfer[0].len = size;
69 xfer[1].rx_buf = (unsigned long) rx;
70 xfer[1].len = size;
71
72 ret = ioctl (fd, SPI_IOC_MESSAGE (2), xfer);
73 if (ret < 1)
74 {
75 pabort ("can't send spi message");
76 }
77 return ret;
78 }
79
80 void
81 setMode (int fd, uint8_t mode)
82 {
83 if (ioctl (fd, SPI_IOC_WR_MODE, &mode) < 0)
84 pabort ("can't set mode");
85 if (ioctl (fd, SPI_IOC_RD_MODE, &mode) < 0)
86 pabort ("can't get mode");
87 }
88
89 uint8_t
90 spi_put (int fd, uint8_t valeur)
91 {
92 int ret;
93 uint8_t rx_buf[1], tx_buf[1];
94 tx_buf[0] = valeur;
95 struct spi_ioc_transfer xfer[2];
96 memset (xfer, 0, sizeof (xfer));
97
98 xfer[0].tx_buf = (unsigned long) tx_buf;
99 xfer[0].rx_buf = (unsigned long) rx_buf;
100 xfer[0].len = 1;
101 ret = ioctl (fd, SPI_IOC_MESSAGE (1), xfer);
102 if (ret < 1)
103 {
104 pabort ("can't send spi message");
105 }
106 return rx_buf[0];
107 }
108
109 int
110 configureSpi (char *device)
111 {
112 printf("device(configureSpi)=%s\n",device);
113 int fd = open (device, O_RDWR);
114 if (fd < 0)
115 pabort ("can't open device");
116
117 setMode (fd, 0);
118 /* bits per word */
119 if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1)
120 pabort ("can't set bits per word");
121 if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &bits) == -1)
122 pabort ("can't get bits per word");
123
124 /* max speed hz */
125 if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1)
126 pabort ("can't set max speed hz");
127
128 if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1)
129 pabort ("can't get max speed hz");
130 //#ifdef DEBUG
131 //printf("spi mode: %d\n", mode);
132 //printf ("bits per word: %d\r\n", bits);
133 //printf ("max speed: %lu Hz (%lu kHz)\r\n",
134 // (unsigned long) speed, ((unsigned long) speed) / 1000);
135 //#endif /* DEBUG */
136 return fd;
137 }
138
139 int configureSpiFromFd (int fd)
140 {
141 setMode (fd, 0);
142 /* bits per word */
143 if (ioctl (fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1)
144 pabort ("can't set bits per word");