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 Side-by-side Diff

  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 +
  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);
  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 */
  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 +}
  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 +}
  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 +}