Commit dfa91a3bc3fea741b18f1a2f3e1bb0d695444b33
1 parent
cc228d59b9
Exists in
master
libad9915 : add initial sources & include files
Showing 6 changed files with 541 additions and 0 deletions Side-by-side Diff
include/ad9915.h
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); | |
41 | +void Calibrate_DAC(int fd, int f_dds); | |
42 | +void basic_setup(int fd, int f_dds, uint16_t ampWord, uint16_t phaseWord); | |
43 | +void modulus_setup(int fd, int f_dds); | |
44 | +void setFreqMM(int fd, int f_dds, unsigned int ftw, unsigned int A, unsigned int B); | |
45 | +void setAmpPhaseWord(int fd, int f_dds,unsigned int phaseAmpWord); | |
46 | +int openAndSetDdsFreq( char * device, char * gpio_update, double f_clk, double f_out, uint16_t ampWord, uint16_t phaseWord); | |
47 | +int receiveParameterFromPythonServer(char * device, double f_clk, double f_out); | |
48 | +int setDdsFreqFull ( int fd, int f_dds, double f_clk, double f_out, uint16_t ampWord, uint16_t phaseWord); | |
49 | + |
include/ddsFreq.h
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); | |
13 | + | |
14 | +int ddsFreq(int fd, int f_dds); | |
15 | +int setddsFreq(int fd, int f_dds, long double f0, long double fs); |
include/spi.h
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); | |
13 | +#endif /*SPI_H */ |
src/ad9915.c
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 | +{ | |
149 | + setddsFreq(fd,f_dds,f_out,f_clk); | |
150 | + #ifdef debug | |
151 | + phaseWord = 0x0000; | |
152 | + ampWord=0x0FFF; | |
153 | + #endif | |
154 | + uint32_t phaseAmpWord = phaseWord | ampWord<<16; | |
155 | + setAmpPhaseWord(fd, f_dds, phaseAmpWord); | |
156 | + | |
157 | + return EXIT_SUCCESS; | |
158 | +} | |
159 | + | |
160 | +int receiveParameterFromPythonServer(char * device, double f_clk, double f_out){ | |
161 | + | |
162 | + printf("receiveParameterFromPythonServer::device=%s\tf_clk=%e\tf_out=%e\n",device,f_clk,f_out); | |
163 | + return 0; | |
164 | +} |
src/ddsFreq.c
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); | |
105 | + printf(" N = fs / d1 = %24.16Lf\n",N); | |
106 | + | |
107 | + | |
108 | + long double ftw = M * scalbn(1.0,32); | |
109 | + ftw /= N; | |
110 | + printf("ftw = %24.16Lf\n",ftw); | |
111 | + | |
112 | + | |
113 | + printf("X=floor(ftw) = %24.16Lf\n",(long double)floor(ftw)); | |
114 | + | |
115 | + long double Y = M * scalbn(1.0,32); | |
116 | + Y -= N * floor(ftw); | |
117 | + printf("Y=M*2**32-X*N = %24.16Lf\n",Y); | |
118 | + | |
119 | + long double d2 = pgcd (Y,N); | |
120 | + printf(" d2 = %24.16Lf\n",d2); | |
121 | + | |
122 | + long double A = Y / d2; | |
123 | + long double B = N / d2; | |
124 | + printf("A = Y/d2 = %24.16Lf\n",A); | |
125 | + printf("B = N/d2 = %24.16Lf\n",B); | |
126 | + | |
127 | + printf("f0 = (M/N) * fclk= %24.32Lf\n",fs*M/N); | |
128 | + printf("f0 = (X+A/B)2**32= %24.32Lf\n",fs*(floor(ftw)+A/B)/scalbn(1.0,32)); | |
129 | + | |
130 | +printf("\n so finally the programmed registers are :\n" | |
131 | + "ftw= 0x%08x A= 0x%08x B= 0x%08x\n" | |
132 | + "",(unsigned int)ftw,(unsigned int)A,(unsigned int)B); | |
133 | +//printf("uint ftw = %d\n",(unsigned int)ftw); | |
134 | + | |
135 | +printf("\n 0x%08x 0x%08x 0x%08x \n\n",(unsigned int)ftw,(unsigned int)A,(unsigned int)B); | |
136 | +//setFreqMM(fd,f_dds,(unsigned int)ftw, (unsigned int)A, (unsigned int)B); | |
137 | +setFreqMM(fd,f_dds,(unsigned int)ftw, 2*(unsigned int)B, 2*(unsigned int)A); | |
138 | + return EXIT_SUCCESS; | |
139 | +} |
src/spi.c
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"); | |
145 | + if (ioctl (fd, SPI_IOC_RD_BITS_PER_WORD, &bits) == -1) | |
146 | + pabort ("can't get bits per word"); | |
147 | + | |
148 | + /* max speed hz */ | |
149 | + if (ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) | |
150 | + pabort ("can't set max speed hz"); | |
151 | + | |
152 | + if (ioctl (fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) | |
153 | + pabort ("can't get max speed hz"); | |
154 | +#ifdef DEBUG | |
155 | +//printf("spi mode: %d\n", mode); | |
156 | +printf ("bits per word: %d\r\n", bits); | |
157 | +printf ("max speed: %lu Hz (%lu kHz)\r\n", | |
158 | + (unsigned long) speed, ((unsigned long) speed) / 1000); | |
159 | +#endif /* DEBUG */ | |
160 | + return EXIT_SUCCESS; | |
161 | +} |