AD7124 Development
Raspberry Pi SPI Interface
Analog Devices AD7124-8
Analog Devices Evaluation Board EVAL-AD7124-8SDZ
Summary
How to connect the 4 wire Serial Peripheral Interface (SPI) Bus on the Raspberry Pi to the Analog Devices AD7124-8 Evaluation Board EVAL-AD7124-8SDZ. No other MCU, including the EVAL-SDP-CB1Z System Demonstration Platform (SDP) board, is necessary. The Pi is operated as the Master, the AD7124 is the Slave. The PIGPIO libraries are necessary.
Resources
PIGPIO Library
EVAL-AD7124-8SDZ User Guide (PDF 4.8 MB 40 Pages)
AD7124-8 Data Sheet (PDF 1.7 MB 92 pages)
Analog Device Virtual Eval Tool (Beta)
Wiring
This shows the necessary connections. NOTE: A ground connection (not shown) is required. The EVAL-AD7124-8SDZ board is powered by it's own power supply.
Raspberry Pi Header J8 | EVAL-AD7124-8SDZ | ||
---|---|---|---|
Signal | Pin Number | Signal | Pin Number |
GPIO 12 SPI0 MOSI | 19 | DI | TDIN or TDIN1 |
GPIO 13 SPI0 MISO | 21 | DO | TDOUT or TDOU1 |
GPIO 14 SPI0 SCLK | 23 | SCLK | TSCLK or TSCLK1 |
GPIO 10 SPI0_CE0 | 24 | ~CS | TCS or TCS1 |
Compiling
To compile with the PIGPIO libraries
gcc -pthread -o AD7124 ad7124PIGPIO.c -lpigpiod_if2 -lrt
Examples
AD7124 -h AD7124 --pm=LOW --fs=120 --verbose=9 --aip=1 --aim=2 --gain=7
Raspberry Pi Code
This program is designed to run on the Raspberry Pi and interface to the Analog Devices AD7124-8 Evaluation Board EVAL-AD7124-8SDZ via the 4 wire SPI interface.
/* * Hivetool AD7124 driver * * To compile with the PIGPIO libraries * gcc -pthread -o AD7124 ad7124PIGPIO.c -lpigpiod_if2 -lrt * * * AD7124 --pm=LOW --fs=120 --verbose=9 --aip=1 --aim=2 --gain=7 * * */ #include <stdio.h> #include <time.h> #include <unistd.h> // usleep #include <getopt.h> #include <string.h> // strcasecmp #include <stdlib.h> // strtol #include <pigpiod_if2.h> // PIGPIO libraries #include <errno.h> // PIGPIO /**************************** printf byte to binary converter ************************************* * https://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format * ***********************************************************************************************/ #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c" #define BYTE_TO_BINARY(byte) \ (byte & 0x80 ? '1' : '0'), \ (byte & 0x40 ? '1' : '0'), \ (byte & 0x20 ? '1' : '0'), \ (byte & 0x10 ? '1' : '0'), \ (byte & 0x08 ? '1' : '0'), \ (byte & 0x04 ? '1' : '0'), \ (byte & 0x02 ? '1' : '0'), \ (byte & 0x01 ? '1' : '0') int initialize( void ); /* set BCM2835 SPI parameters, reset the AD7124, read ID and Status registers */ void setup( void ); /* setup the AD7124 configuration registers */ void read_registers(void); /* read and dump the AD7124 registers */ char wait_for_ready(void); /* wait for conversion by polling the AD7124 Status register */ int median_select(int arr[], int n); /* select the median from the data array */ int get_options(int argc, char **argv); /* read the command line options */ int convert_options(void); /* convert the command line option integers to hex bytes */ void print_help(void); /* display usage when invoked with the --help argument */ enum { LOW_POWER=0x00, MEDIUM_POWER=0x40, HIGH_POWER=0x80 } power_mode = HIGH_POWER; int pi = 0; int spi_handle = 0; int number_active_channels = 1; int number_of_filtered_samples = 0; int data_array[64]; /* command line argument defaults */ int number_of_samples = 64; /* Number of data reads to average */ int verbose = 0; char FS[2] = { 0x01, 0x40 }; /* Filter Select (FS) default: 320 */ char PGA = 0x07; /* PGA default: 128 */ char AINM = 0x06; /* Negative analog input: 6 */ char AINP = 0x07; /* Positive analog input: 7 */ int main(int argc, char **argv) { int i = 0; int j = 0; int sum = 0; int sample_counter = 0; int read_counter = 0; int data_register=0; int return_code = 0; char wrBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; char rdBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; time_t t; /* Read the command line arguments */ get_options(argc, argv); /* connect to the local PIGPIO daemon */ pi = pigpio_start(NULL, NULL); if (pi < 0) { fprintf (stderr, "Unable to connect to pigpiod: %s\n", strerror (errno)); return 1; } spi_handle = spi_open( pi, 0, 4194304, 0x000003 ); if (spi_handle < 0) { fprintf (stderr, "Unable to open SPI device: %s\n", strerror (errno)); fprintf (stderr, "Unable to open SPI device: %x\n", spi_handle); return 2; } /* Initialize the SPI interface and reset the AD7124 */ return_code = initialize(); if ( verbose > 7 ) printf("initialize routine return value: %d\n",return_code); if ( return_code ) { printf("ERROR! Initialization failed code %d. Is the AD7124 connected and powered?\n", return_code); return return_code; } /* Set up the registers on the AD7124 */ setup(); /* turn on load cell excitation using PDSW Power Down Switch */ wrBuf[0]= 0x03; wrBuf[1]= 0x00; wrBuf[2]= 0x80; wrBuf[3]= 0x00; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); /* start data conversion, Continuous conversion mode 00 0084 ADC Control High power, Mode 0*/ wrBuf[0]= 0x01; wrBuf[1]= 0x06; wrBuf[2]= power_mode; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 3); if ( verbose > 6 ) { printf("Write ADC Control: %02x %02x "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n", wrBuf[1],wrBuf[2],BYTE_TO_BINARY(wrBuf[1]),BYTE_TO_BINARY(wrBuf[2])); } wrBuf[0]= 0x41; wrBuf[1]= 0x00; wrBuf[2]= 0x00; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 3); if ( verbose > 6 ) { printf("Read ADC Control: %02x %02x "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\nBeginning continuous conversions\n", rdBuf[1],rdBuf[2],BYTE_TO_BINARY(rdBuf[1]),BYTE_TO_BINARY(rdBuf[2])); } time(&t); // printf(" %s",ctime(&t)); sum=0; sample_counter=0; read_counter = 0; while ( read_counter < 128 && sample_counter < number_of_samples ) { for ( i=0; i< number_active_channels; i++ ) { if ( !wait_for_ready() ) { /* Read the data register */ wrBuf[0]= 0x42; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 5); data_register = (rdBuf[1] << 16) | (rdBuf[2] << 8) | (rdBuf[3]); if ( verbose > 8 ) { printf("Data: %d %02x%02x%02x Status: %02X ",data_register, rdBuf[1],rdBuf[2],rdBuf[3],rdBuf[4]); } /* Read the error register */ wrBuf[0]= 0x46; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); if ( verbose > 8 ) { time(&t); printf(" Error: %02X %02X %02X "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN" %s", rdBuf[1],rdBuf[2],rdBuf[3],BYTE_TO_BINARY(rdBuf[1]),BYTE_TO_BINARY(rdBuf[2]),BYTE_TO_BINARY(rdBuf[3]) ,ctime(&t)); } /* Check for errors */ if ( (rdBuf[1] | rdBuf[2] | rdBuf[3]) == 0 ) /* if no errors, use data to calculate average */ { data_array[sample_counter] = data_register; sum += data_register; sample_counter++; } } } // read_registers(); read_counter++; } /* turn off load cell excitation using PDSW Power Down Switch */ wrBuf[0]= 0x03; wrBuf[1]= 0x00; wrBuf[2]= 0x00; wrBuf[3]= 0x00; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); if (sample_counter == 0) return 5; number_of_filtered_samples = sample_counter; if (sample_counter > 1 ) { /* calculate raw average */ int raw_average = sum/sample_counter; /* calculate median */ int median = median_select( data_array, sample_counter ); printf("AD7124test Raw Average: %10d Median: %10d Number of samples: %4d Number of errors: %3d %s", raw_average, median,sample_counter, (read_counter - sample_counter), ctime(&t) ); // printf(" %s",ctime(&t)); sum = 0; number_of_filtered_samples = 0; /* set limits for outliers */ // int high_limit = median * 1.00002; // int low_limit = median * .99998; int high_limit = median * 1.0002; int low_limit = median * .9998; // printf("high_limit: %10d low_limit: %10d\n", high_limit, low_limit ); /* Test for outliers and throw them away */ for ( j=0; j<sample_counter; j++ ) { if ( data_array[j] < high_limit && data_array[j] > low_limit ) { number_of_filtered_samples++; sum += data_array[j]; // printf ("data_array: %d less median: %d\n", data_array[j], data_array[j] - median); } // else // printf ("OUTLIER %d less median: %d\n", data_array[j], data_array[j] - median); } if (number_of_filtered_samples == 0) return 6; /* calculate raw average */ int filtered_average = sum/number_of_filtered_samples; printf("AD7124test Filtered Avg:%10d Median: %10d Number of samples: %4d Number Outliers: %3d %s", filtered_average, median, number_of_filtered_samples, (sample_counter - number_of_filtered_samples), ctime(&t) ); // printf(" %s",ctime(&t)); } //printf("Weight: %7.3f\n", 0.000536331066441 * ( ( (sum/number_of_filtered_samples)/10 ) - 855362) ); //printf("Weight: %7.3f\n", 0.00000868891 * ( ( (sum/number_of_filtered_samples) ) - 73.10472780232) ); printf("Weight: %7.3f\n", (0.0003438388 * (sum/number_of_filtered_samples)) - 2892.912 ); spi_close(pi, spi_handle); return 0; } /* *********************** initialize ********************************** * * set the BCM2835 SPi parameters * Reset AD7124 * check for AD7124 by reading ID register 5 (ID 14) * Read Status Register * * ***********************************************************************/ int initialize ( void ) { char wrBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; char rdBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; /* Reset the AD7124 by sending 64 ones */ spi_write(pi, spi_handle,wrBuf, 8); // printf("Sent 64 ones to reset\n"); usleep(1000); /* Wait for the reset to complete */ wrBuf[0]= 0x45; /* check for AD7124 by reading ID register 5 (ID 14) */ spi_xfer(pi, spi_handle, wrBuf, rdBuf, 2); if (verbose > 6) printf("initialize() ID register: %02X\n",rdBuf[1]); if ( rdBuf[1] != 0x14 ) { printf("AD7124 reset failed. Bad ID: %02X\n", rdBuf[1]); return 3; } /* Read Status Register */ wrBuf[0]= 0x40; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 2); if (verbose > 6) printf("initialize() Status register: %02X\n",rdBuf[1]); /* Read Status Register again to clear Power reset bit */ wrBuf[0]= 0x40; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 2); if (verbose > 6) printf("initialize() Status register: %02X\n",rdBuf[1]); if ( rdBuf[1] != 0x80 ) { printf("AD7124 reset failed. Bad Status: %02X \n", rdBuf[1]); return 4; } return 0; } /* ************************** setup ************************************ * * Maybe add an external conf file that sets up the ADC registers? * ***********************************************************************/ void setup ( void ) { char wrBuf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char rdBuf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; wrBuf[0]= 0x09; wrBuf[1]= 0x00; wrBuf[2]= 0x01; /* Turn off channel_0 (on by default) */ spi_xfer(pi, spi_handle, wrBuf, rdBuf, 3); //wrBuf[1] = ( AIMP & 0x18 ) >> 3 ; wrBuf[0]= 0x0a; wrBuf[1] = (( AINP >> 3) & 0x07 ) | 0x80; wrBuf[2] = (( AINP & 0x07 ) << 5) | ( AINM & 0x1F ); spi_xfer(pi, spi_handle, wrBuf, rdBuf, 3); wrBuf[0]= 0x19; wrBuf[1]= 0x08; wrBuf[2]= 0x7F; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 3); wrBuf[0]= 0x21; wrBuf[1]= 0x06; wrBuf[2]= FS[0]; wrBuf[3]= FS[1]; /* Set the Filter Select bits */ spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); wrBuf[0]= 0x07; wrBuf[1]= 0x03; wrBuf[2]= 0xF0; wrBuf[3]= 0x38; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); if ( verbose > 6 ) { read_registers(); // This sets the number_active_channels (default = 1) } } /* ************************ read_registers ***************************** * * Read and dump most of the AD7124-8 registers * ***********************************************************************/ void read_registers(void) { int i; char wrBuf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char rdBuf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; wrBuf[0]= 0x46; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); printf("%02X Error : %02X %02X %02X "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n", 0x06,rdBuf[1],rdBuf[2],rdBuf[3],BYTE_TO_BINARY(rdBuf[1]),BYTE_TO_BINARY(rdBuf[2]),BYTE_TO_BINARY(rdBuf[3])); wrBuf[0]= 0x47; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); printf("%02X Error Enab: %02X %02X %02X "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n", 0x07,rdBuf[1],rdBuf[2],rdBuf[3],BYTE_TO_BINARY(rdBuf[1]),BYTE_TO_BINARY(rdBuf[2]),BYTE_TO_BINARY(rdBuf[3])); number_active_channels=0; for ( i = 0x49; i< 0x59; i++ ) /* Read Channel Registers */ { wrBuf[0]= i; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 3); /* Test for active channels and count them */ if ( rdBuf[1] & 0x80 ) { number_active_channels++; } printf("%02X Channel %2d: %02x %02x "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n",i-0x40, (i-0x49),rdBuf[1],rdBuf[2],BYTE_TO_BINARY(rdBuf[1]),BYTE_TO_BINARY(rdBuf[2])); } printf("Number of active channels: %d\n", number_active_channels); for ( i = 0x59; i< 0x61; i++ ) /* Read Configuration Registers */ { wrBuf[0]= i; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 3); printf("%02X Config %2d: %02X %02X "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n", i-0x40, (i-0x59),rdBuf[1],rdBuf[2],BYTE_TO_BINARY(rdBuf[1]),BYTE_TO_BINARY(rdBuf[2])); } for ( i = 0x61; i< 0x69; i++ ) /* Read Configuration Registers */ { wrBuf[0]= i; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 4); printf("%02X Filter %2d: %02X %02X %02X "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n", i-0x40, (i-0x61),rdBuf[1],rdBuf[2],rdBuf[3],BYTE_TO_BINARY(rdBuf[1]),BYTE_TO_BINARY(rdBuf[2]),BYTE_TO_BINARY(rdBuf[3])); } } /************************* wait_for_ready ********************************* * * This routine spins in a loop waiting until either: * 1, The conversion is complete ~RDY bit goes low (data is written to the Data Register) * 2. We time out and give up * * WARNING: This routine is senstive to the SPI clock speed. * Low clock speeds can cause delays much greater than 0.1 miliseconds each pass. * ***************************************************************************/ char wait_for_ready(void) { char wrBuf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char rdBuf[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; unsigned int waiting=10000; char busy = 1; while( busy && waiting ) { /* Read the Status Register */ wrBuf[0]= 0x40; spi_xfer(pi, spi_handle, wrBuf, rdBuf, 2); busy = rdBuf[1] & 0x80 ; /* Test the Not Ready bit */ // printf("Busy: %X timeout: %d\n", busy, (1000-timeout) ); usleep(100); /* wait 0.1 msec */ waiting--; } return busy; } /************************* median_select ********************************* * * from http://ndevilla.free.fr/median/median/ * This Quickselect routine is based on the algorithm described in * "Numerical recipes in C", Second Edition, * Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5 * This code by Nicolas Devillard - 1998. Public domain. * ***************************************************************************/ #define ELEM_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; } int median_select(int arr[], int n) { int low, high; int median; int middle, ll, hh; low = 0 ; high = n-1 ; median = (low + high) / 2; for (;;) { if (high <= low) /* One element only */ return arr[median]; if (high == low + 1) { /* Two elements only */ if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); return arr[median]; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]); if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]); if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]); /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]); /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]); do hh--; while (arr[hh] > arr[low]); if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]); } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]); /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP /****************************** get_options ********************************************************************* * * https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html#Getopt-Long-Option-Example * https://stackoverflow.com/questions/3792663/atol-v-s-strtol * ***************************************************************************************************************/ int get_options (int argc, char **argv) { int short_option; char* end; int filter_select = 0; int positive_analog_input = 0; int negative_analog_input = 0; int programable_gain = 0; while (1) { static struct option long_options[] = { /* These options set a flag. */ // {"brief", no_argument, &verbose_flag, 0}, /* These options don?t set a flag. We distinguish them by their indices. */ {"aip", required_argument, 0, 'p'}, {"aim", required_argument, 0, 'm'}, {"fs", required_argument, 0, 'f'}, {"gain", required_argument, 0, 'g'}, {"help", no_argument, 0, 'h'}, {"samples", required_argument, 0, 'n'}, {"power", required_argument, 0, 'w'}, {"verbose", required_argument, 0, 'v'}, {0, 0, 0, 0} }; /* getopt_long stores the option index here. */ int option_index = 0; short_option = getopt_long (argc, argv, "n:p:m:f:g:hw:v:", long_options, &option_index); /* Detect the end of the options. */ if (short_option == -1) break; switch (short_option) { case 0: /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case 'f': filter_select = strtol(optarg, &end, 10); if (*end) { printf ("ERROR! Filter Select (FS) argument numeric conversion failed, non-numeric part: %s\n", end); exit(-3); } if ( filter_select > 2047 || filter_select < 1 ) { printf ("ERROR! Filter Select (FS) argument out of range (1-2047): %d\n", filter_select); exit(-1); } FS[0] = filter_select & 0xFF; FS[1] = (filter_select >> 8 ) & 0xFF; if ( verbose > 4 ) printf ("Command line option Filter Select (--fs or -f) has value %d converted to %02X %02X \n", filter_select, FS[1], FS[0]); break; case 'g': programable_gain = strtol(optarg, &end, 10); if (*end) { printf ("ERROR! Programable Gain Amplifier (PGA) argument numeric conversion failed, non-numeric part: %s\n", end); exit(-3); } if ( programable_gain > 7 || programable_gain < 0 ) { printf ("ERROR! Programable Gain Amplifier (PGA) argument out of range (0-7): %d\n", programable_gain); exit(-1); } PGA = programable_gain & 0x07; if ( verbose > 4 ) printf ("Command line option Programable Gain Amplifer (--gain or -g) has value %d converted to %02X\n", programable_gain, PGA); break; // case '?': case 'h': print_help(); exit(0); break; case 'm': negative_analog_input = strtol(optarg, &end, 10); if (*end) { printf ("ERROR! Analog INput Minus (AINM) argument numeric conversion failed, non-numeric part: %s\n", end); exit(-3); } if ( negative_analog_input > 31 || negative_analog_input < 0 ) { printf ("ERROR! Analog INput Minus (AINM) argument out of range (0-31): %d\n", negative_analog_input); exit(-1); } AINM = 0x1F & negative_analog_input; if ( verbose > 4 ) printf ("Command line option Analog INput Minus (AINM) (--aim or -m) has value %d converted to %02X\n", negative_analog_input, AINM); break; case 'n': number_of_samples = strtol(optarg, &end, 10); if (*end) { printf ("ERROR! Analog INput Minus (AINM) argument numeric conversion failed, non-numeric part: %s\n", end); exit(-3); } if ( number_of_samples > 64 || number_of_samples < 1 ) { printf ("ERROR! Number of samples argument out of range (0-31): %d\n", number_of_samples); exit(-1); } if ( verbose > 4 ) printf ("Command line option Number of samples (--samples or -n) has value %d\n", number_of_samples); break; case 'p': positive_analog_input = strtol(optarg, &end, 10); if (*end) { printf ("ERROR! Analog INput Plus (AINP) argument numeric conversion failed, non-numeric part: %s\n", end); exit(-3); } if ( positive_analog_input > 31 || positive_analog_input < 0 ) { printf ("ERROR! Analog INput Plus (AINP) argument out of range (0-31): %d\n", positive_analog_input); exit(-1); } AINP = 0x1F & positive_analog_input; if ( verbose > 4 ) printf ("Command line option Analog INput Plus (AINP) (--aip or -p) has value %d converted to %02X\n", positive_analog_input, AINP); break; case 'w': if ( strcasecmp( optarg, "LOW") == 0 ) { power_mode = LOW_POWER; } else if ( strcasecmp( optarg, "MEDIUM") == 0 ) { power_mode = MEDIUM_POWER; } else if ( strcasecmp( optarg, "HIGH") == 0 ) { power_mode = HIGH_POWER; } else { printf ("ERROR! Expecting --power(-w) [low|LOW|medium|MEDIUM|high|HIGH] found %s\n", optarg); exit(-2); } break; case 'v': // verbose = 1; // if ( optarg ) // { verbose = strtol(optarg, &end, 10); if (*end) { printf ("ERROR! Verbose argument numeric conversion failed, non-numeric part: %s\n", end); exit(-3); } if ( verbose > 9 || verbose < 0 ) { printf ("ERROR! Verbose argument out of range (0-9): %d\n", verbose); exit(-1); } // } if ( verbose > 4 ) printf ("Command line option Verbose (--verbose or -v) with value %d\n", verbose); break; case '?': /* getopt_long already printed an error message. */ exit(-5); break; default: abort (); } } /* Instead of reporting ?--verbose? and ?--brief? as they are encountered, we report the final status resulting from them. */ // if (verbose_flag) // puts ("verbose flag is set"); /* Print any remaining command line arguments (not options). */ if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); putchar ('\n'); } return (0); } /* *********************** print_help ********************************** * * Prints usage information - some of this could go in a man page * ***********************************************************************/ void print_help(void) { printf ( "Usage: ad7124 [OPTION...]\n\n" " -f, --fs=FS 0 < FS < 2048\n" " Sets the output data rate of the sinc3, sinc4 and fast settling filters, affects the\n" " position of the first notch, the cutoff frequency of the sinc filter, the output noise\n" " and effective resolution\n" "\n" " -g, --gain=GAIN\n" " Sets PGA stage gain:\n" " GAIN gain Input Voltage Range\n" " 0 1 +/-2.5 V\n" " 1 2 +/-1.25 V\n" " 2 4 +/-625 mV\n" " 3 8 +/-312.5 mV\n" " 4 16 +/-156.25 mV\n" " 5 32 +/-78.125 mV\n" " 6 64 +/-39.06 mV\n" " 7 128 +/-19.53 mV\n" "\n" " -m, --aim=AIM\n" " AIM selects which input is multiplexed to the ADC negative input where:\n" " AIM AINM\n" " 0 AIN0\n" " 1 AIN1\n" " 2 AIN2\n" " 3 AIN3\n" " 4 AIN4\n" " 5 AIN5\n" " 6 AIN6\n" " 7 AIN7\n" " 8 AIN8\n" " 9 AIN9\n" " 10 AIN10\n" " 11 AIN11\n" " 12 AIN12\n" " 13 AIN13\n" " 14 AIN14\n" " 15 AIN15\n" " 16 temperature sensor\n" " 17 AVSS\n" " 18 internal reference\n" " 19 DGND\n" "\n" " -n, --samples=N\n" " N sets the number of samples that are read and averaged. 0 < N < 65\n" " If N > 1, the samples are read as quickly as possible with no delay between samples.\n" "\n" " -p, --aip=AIP\n" " AIP selects which input is multiplexed to the ADC positive input. AIP is the same as\n" " AIM in the -m,--aim option.\n" "\n" "Examples:\n\n" "\n" "\n" "Application Notes:\n" "\n" "This program is designed to run on the Raspberry Pi and interface to the Analog Devices AD7124-8 Evaluation Board\n" "EVAL-AD7124-8SDZ via the 4 wire SPI interface. No other MCU, including the EVAL-SDP-CB1Z System Demonstration Platform\n" "(SDP) board, is necessary. The Pi is operated as the Master, the AD7124 is the Slave.\n" "\n" "Wiring:\n" "Connect:\n" " Raspberry Pi Header J8 EVAL-AD7124-8SDZ\n" " Signal Pin Number Signal Pin Number\n" " GPIO 12 SPI0 MOSI 19 DI TDIN or TDIN1\n" " GPIO 13 SPI0 MISO 21 DO TDOUT or TDOU1\n" " GPIO 14 SPI0 SCLK 23 SCLK TSCLK or TSCLK1\n" " GPIO 10 SPI0_CE0 24 ~CS TCS or TCS1\n" "\n" ); }