Maxim Integrated / MAX11131

Dependents:   MAX11131BOB_Tester MAX11131BOB_12bit_16ch_SampleSet_SPI_ADC MAX11131BOB_Serial_Tester

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX11131.cpp Source File

MAX11131.cpp

00001 // /*******************************************************************************
00002 // * Copyright (C) 2021 Maxim Integrated Products, Inc., All Rights Reserved.
00003 // *
00004 // * Permission is hereby granted, free of charge, to any person obtaining a
00005 // * copy of this software and associated documentation files (the "Software"),
00006 // * to deal in the Software without restriction, including without limitation
00007 // * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 // * and/or sell copies of the Software, and to permit persons to whom the
00009 // * Software is furnished to do so, subject to the following conditions:
00010 // *
00011 // * The above copyright notice and this permission notice shall be included
00012 // * in all copies or substantial portions of the Software.
00013 // *
00014 // * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 // * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 // * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 // * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 // * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 // * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 // * OTHER DEALINGS IN THE SOFTWARE.
00021 // *
00022 // * Except as contained in this notice, the name of Maxim Integrated
00023 // * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 // * Products, Inc. Branding Policy.
00025 // *
00026 // * The mere transfer of this software does not imply any licenses
00027 // * of trade secrets, proprietary technology, copyrights, patents,
00028 // * trademarks, maskwork rights, or any other form of intellectual
00029 // * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 // * ownership rights.
00031 // *******************************************************************************
00032 // */
00033 // *********************************************************************
00034 // @file MAX11131.cpp
00035 // *********************************************************************
00036 // Device Driver file
00037 // DO NOT EDIT; except areas designated "CUSTOMIZE". Automatically generated file.
00038 // generated by XMLSystemOfDevicesToMBED.py
00039 // System Name = ExampleSystem
00040 // System Description = Device driver example
00041 
00042 #include "MAX11131.h"
00043 
00044 // Device Name = MAX11131
00045 // Device Description = 3Msps, Low-Power, Serial SPI 12-Bit, 16-Channel, Differential/Single-Ended Input, SAR ADC
00046 // Device DeviceBriefDescription = 12-bit 3Msps 16-ch ADC
00047 // Device Manufacturer = Maxim Integrated
00048 // Device PartNumber = MAX11131ATI+
00049 // Device RegValue_Width = DataWidth16bit_HL
00050 //
00051 // ADC MaxOutputDataRate = 3Msps
00052 // ADC NumChannels = 16
00053 // ADC ResolutionBits = 12
00054 //
00055 // SPI CS = ActiveLow
00056 // SPI FrameStart = CS
00057 // SPI CPOL = 1
00058 // SPI CPHA = 1
00059 // SPI MOSI and MISO Data are both stable on Rising edge of SCLK
00060 // SPI SCLK Idle High
00061 // SPI SCLKMaxMHz = 48
00062 // SPI SCLKMinMHz = 0.48
00063 //
00064 // InputPin Name = CNVST
00065 // InputPin Description = Active-Low Conversion Start Input/Analog Input 14
00066 // InputPin Function = Trigger
00067 //
00068 // InputPin Name = REF+
00069 // InputPin Description = External Positive Reference Input. Apply a reference voltage at REF+. Bypass to GND with a 0.47uF capacitor.
00070 // InputPin Function = Reference
00071 //
00072 // InputPin Name = REF-/AIN15
00073 // InputPin Description = External Differential Reference Negative Input/Analog Input 15
00074 // InputPin Function = Reference
00075 //
00076 // OutputPin Name = EOC
00077 // OutputPin Description = End of Conversion Output. Data is valid after EOC pulls low (Internal clock mode only).
00078 // OutputPin Function = Event
00079 //
00080 // SupplyPin Name = VDD
00081 // SupplyPin Description = Power-Supply Input. Bypass to GND with a 10uF in parallel with a 0.1uF capacitors.
00082 // SupplyPin VinMax = 3.6
00083 // SupplyPin VinMin = 2.35
00084 // SupplyPin Function = Analog
00085 //
00086 // SupplyPin Name = OVDD
00087 // SupplyPin Description = Interface Digital Power-Supply Input. Bypass to GND with a 10uF in parallel with a 0.1uF capacitors.
00088 // SupplyPin VinMax = 3.6
00089 // SupplyPin VinMin = 1.5
00090 // SupplyPin Function = Digital
00091 //
00092 
00093 MAX11131::MAX11131(SPI &spi, DigitalOut &cs_pin, // SPI interface
00094                  DigitalOut &CNVST_pin, // Digital Trigger Input to MAX11131 device
00095                  // AnalogOut &REF_plus_pin, // Reference Input to MAX11131 device
00096                  // AnalogOut &REF_minus_slash_AIN15_pin, // Reference Input to MAX11131 device
00097                  DigitalIn &EOC_pin, // Digital Event Output from MAX11131 device
00098                  MAX11131_ic_t ic_variant)
00099     : m_spi(spi), m_cs_pin(cs_pin), // SPI interface
00100     m_CNVST_pin(CNVST_pin), // Digital Trigger Input to MAX11131 device
00101     // m_REF_plus_pin(REF_plus_pin), // Reference Input to MAX11131 device
00102     // m_REF_minus_slash_AIN15_pin(REF_minus_slash_AIN15_pin), // Reference Input to MAX11131 device
00103     m_EOC_pin(EOC_pin), // Digital Event Output from MAX11131 device
00104     m_ic_variant(ic_variant)
00105 {
00106     // SPI CS = ActiveLow
00107     // SPI FrameStart = CS
00108     m_SPI_cs_state = 1;
00109     if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected
00110         m_cs_pin = m_SPI_cs_state;
00111     }
00112 
00113     // SPI CPOL = 1
00114     // SPI CPHA = 1
00115     // SPI MOSI and MISO Data are both stable on Rising edge of SCLK
00116     // SPI SCLK Idle High
00117     m_SPI_dataMode = 3; //SPI_MODE3; // CPOL=1,CPHA=1: Rising Edge stable; SCLK idle High
00118     m_spi.format(8,m_SPI_dataMode);         // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0
00119 
00120     // SPI SCLKMaxMHz = 48
00121     // SPI SCLKMinMHz = 0.48
00122     //#define SPI_SCLK_Hz 48000000 // 48MHz
00123     //#define SPI_SCLK_Hz 24000000 // 24MHz
00124     //#define SPI_SCLK_Hz 12000000 // 12MHz
00125     //#define SPI_SCLK_Hz 6000000 // 6MHz
00126     //#define SPI_SCLK_Hz 4000000 // 4MHz
00127     //#define SPI_SCLK_Hz 2000000 // 2MHz
00128     //#define SPI_SCLK_Hz 1000000 // 1MHz
00129 #if defined(TARGET_MAX32600)
00130     // MAX11131BOB_Serial_Tester on MAX32600MBED limit SCLK=6MHz
00131     m_SPI_SCLK_Hz = 6000000; // 6MHz; MAX11131 limit is 48MHz
00132 #else
00133     // all other platforms
00134     m_SPI_SCLK_Hz = 24000000; // platform limit 24MHz; MAX11131 limit is 48MHz
00135 #endif
00136     m_spi.frequency(m_SPI_SCLK_Hz);
00137 
00138     //
00139     // CNVST Trigger Input to MAX11131 device
00140     m_CNVST_pin = 1; // output logic high -- initial value in constructor
00141     //
00142     // REF_plus Reference Input to MAX11131 device
00143     //
00144     // REF_minus_slash_AIN15 Reference Input to MAX11131 device
00145     //
00146     // EOC Event Output from device
00147 }
00148 
00149 MAX11131::~MAX11131()
00150 {
00151     // do nothing
00152 }
00153 
00154 /// set SPI SCLK frequency
00155 void MAX11131::spi_frequency(int spi_sclk_Hz)
00156 {
00157     m_SPI_SCLK_Hz = spi_sclk_Hz;
00158     m_spi.frequency(m_SPI_SCLK_Hz);
00159 }
00160 
00161 // set SPI SCLK frequency for MAX11131
00162 //
00163 void MAX11131::SPIfrequency(int spi_sclk_Hz)
00164 {
00165     m_SPI_SCLK_Hz = spi_sclk_Hz;
00166     m_spi.frequency(m_SPI_SCLK_Hz);
00167 }
00168 
00169 // get SPI SCLK frequency for MAX11131
00170 //
00171 int MAX11131::SPIgetFrequency()
00172 {
00173     return m_SPI_SCLK_Hz;
00174 }
00175 
00176 // Assert SPI Chip Select
00177 // SPI chip-select for MAX11131
00178 //
00179 inline void MAX11131::SPIoutputCS(int isLogicHigh)
00180 {
00181     m_SPI_cs_state = isLogicHigh;
00182     if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected
00183         m_cs_pin = m_SPI_cs_state;
00184     }
00185 }
00186 
00187 // SPI write 16 bits
00188 // SPI interface to MAX11131 shift 16 bits mosiData16 into MAX11131 DIN
00189 // ignoring MAX11131 DOUT
00190 //
00191 void MAX11131::SPIwrite16bits(int16_t mosiData16)
00192 {
00193     size_t byteCount = 2;
00194     static char mosiData[2];
00195     static char misoData[2];
00196     mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte
00197     mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte
00198     //
00199     // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
00200     //~ noInterrupts();
00201     //
00202     //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin
00203     //
00204     unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount);
00205     //~ m_spi.transfer(mosiData8_FF0000);
00206     //~ m_spi.transfer(mosiData16_00FF00);
00207     //~ m_spi.transfer(mosiData16_0000FF);
00208     //
00209     //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin
00210     //
00211     // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
00212     //~ interrupts();
00213     // Optional Diagnostic function to print SPI transactions
00214     if (onSPIprint)
00215     {
00216         onSPIprint(byteCount, (uint8_t*)mosiData, (uint8_t*)misoData);
00217     }
00218     //
00219     // VERIFY: SPIwrite24bits print diagnostic information
00220     //cmdLine.serial().printf(" MOSI->"));
00221     //cmdLine.serial().printf(" 0x"));
00222     //Serial.print( (mosiData8_FF0000 & 0xFF), HEX);
00223     //cmdLine.serial().printf(" 0x"));
00224     //Serial.print( (mosiData16_00FF00 & 0xFF), HEX);
00225     //cmdLine.serial().printf(" 0x"));
00226     //Serial.print( (mosiData16_0000FF & 0xFF), HEX);
00227     // hex dump mosiData[0..byteCount-1]
00228 #if 0 // HAS_MICROUSBSERIAL
00229     cmdLine_microUSBserial.serial().printf("\r\nSPI");
00230     if (byteCount > 7) {
00231         cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount);
00232     }
00233     cmdLine_microUSBserial.serial().printf(" MOSI->");
00234     for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
00235     {
00236         cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
00237     }
00238     // hex dump misoData[0..byteCount-1]
00239     cmdLine_microUSBserial.serial().printf(" MISO<-");
00240     for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
00241     {
00242         cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
00243     }
00244     cmdLine_microUSBserial.serial().printf(" ");
00245 #endif
00246 #if 0 // HAS_DAPLINK_SERIAL
00247     cmdLine_DAPLINKserial.serial().printf("\r\nSPI");
00248     if (byteCount > 7) {
00249         cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount);
00250     }
00251     cmdLine_DAPLINKserial.serial().printf(" MOSI->");
00252     for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
00253     {
00254         cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
00255     }
00256     // hex dump misoData[0..byteCount-1]
00257     cmdLine_DAPLINKserial.serial().printf(" MISO<-");
00258     for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
00259     {
00260         cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
00261     }
00262     cmdLine_DAPLINKserial.serial().printf(" ");
00263 #endif
00264     // VERIFY: DIAGNOSTIC: print MAX5715 device register write
00265     // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF);
00266     // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF);
00267     //
00268     // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF;
00269     // return misoData16;
00270 }
00271 
00272 // SPI write 17-24 bits
00273 // SPI interface to MAX11131 shift 16 bits mosiData16 into MAX11131 DIN
00274 // followed by one additional SCLK byte.
00275 // ignoring MAX11131 DOUT
00276 //
00277 void MAX11131::SPIwrite24bits(int16_t mosiData16_FFFF00, int8_t mosiData8_0000FF)
00278 {
00279     // TODO: implement SPIwrite24bits(int16_t mosiData16_FFFF00, int8_t mosiData8_0000FF)
00280     size_t byteCount = 3;
00281     static char mosiData[3];
00282     static char misoData[3];
00283     mosiData[0] = (char)((mosiData16_FFFF00 >> 8) & 0xFF); // MSByte
00284     mosiData[1] = (char)((mosiData16_FFFF00 >> 0) & 0xFF); // LSByte
00285     mosiData[2] = mosiData8_0000FF;
00286     //
00287     // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
00288     //~ noInterrupts();
00289     //
00290     //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin
00291     //
00292     unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount);
00293     //~ m_spi.transfer(mosiData8_FF0000);
00294     //~ m_spi.transfer(mosiData16_00FF00);
00295     //~ m_spi.transfer(mosiData16_0000FF);
00296     //
00297     //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin
00298     //
00299     // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
00300     //~ interrupts();
00301     // Optional Diagnostic function to print SPI transactions
00302     if (onSPIprint)
00303     {
00304         onSPIprint(byteCount, (uint8_t*)mosiData, (uint8_t*)misoData);
00305     }
00306     //
00307     // VERIFY: SPIwrite24bits print diagnostic information
00308     //cmdLine.serial().printf(" MOSI->"));
00309     //cmdLine.serial().printf(" 0x"));
00310     //Serial.print( (mosiData8_FF0000 & 0xFF), HEX);
00311     //cmdLine.serial().printf(" 0x"));
00312     //Serial.print( (mosiData16_00FF00 & 0xFF), HEX);
00313     //cmdLine.serial().printf(" 0x"));
00314     //Serial.print( (mosiData16_0000FF & 0xFF), HEX);
00315     // hex dump mosiData[0..byteCount-1]
00316 #if 0 // HAS_MICROUSBSERIAL
00317     cmdLine_microUSBserial.serial().printf("\r\nSPI");
00318     if (byteCount > 7) {
00319         cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount);
00320     }
00321     cmdLine_microUSBserial.serial().printf(" MOSI->");
00322     for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
00323     {
00324         cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
00325     }
00326     // hex dump misoData[0..byteCount-1]
00327     cmdLine_microUSBserial.serial().printf(" MISO<-");
00328     for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
00329     {
00330         cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
00331     }
00332     cmdLine_microUSBserial.serial().printf(" ");
00333 #endif
00334 #if 0 // HAS_DAPLINK_SERIAL
00335     cmdLine_DAPLINKserial.serial().printf("\r\nSPI");
00336     if (byteCount > 7) {
00337         cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount);
00338     }
00339     cmdLine_DAPLINKserial.serial().printf(" MOSI->");
00340     for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
00341     {
00342         cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
00343     }
00344     // hex dump misoData[0..byteCount-1]
00345     cmdLine_DAPLINKserial.serial().printf(" MISO<-");
00346     for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
00347     {
00348         cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
00349     }
00350     cmdLine_DAPLINKserial.serial().printf(" ");
00351 #endif
00352     // VERIFY: DIAGNOSTIC: print MAX5715 device register write
00353     // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF);
00354     //
00355     // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF;
00356     // return misoData16;
00357 }
00358 
00359 // SPI read 16 bits while MOSI (MAX11131 DIN) is 0
00360 // SPI interface to capture 16 bits miso data from MAX11131 DOUT
00361 //
00362 int16_t MAX11131::SPIread16bits()
00363 {
00364     int mosiData16 = 0;
00365     size_t byteCount = 2;
00366     static char mosiData[2];
00367     static char misoData[2];
00368     mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte
00369     mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte
00370     //
00371     // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
00372     //~ noInterrupts();
00373     //
00374     //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin
00375     //
00376     unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount);
00377     //~ m_spi.transfer(mosiData8_FF0000);
00378     //~ m_spi.transfer(mosiData16_00FF00);
00379     //~ m_spi.transfer(mosiData16_0000FF);
00380     //
00381     //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin
00382     //
00383     // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts()
00384     //~ interrupts();
00385     // Optional Diagnostic function to print SPI transactions
00386     if (onSPIprint)
00387     {
00388         onSPIprint(byteCount, (uint8_t*)mosiData, (uint8_t*)misoData);
00389     }
00390     //
00391     // VERIFY: SPIwrite24bits print diagnostic information
00392     //cmdLine.serial().printf(" MOSI->"));
00393     //cmdLine.serial().printf(" 0x"));
00394     //Serial.print( (mosiData8_FF0000 & 0xFF), HEX);
00395     //cmdLine.serial().printf(" 0x"));
00396     //Serial.print( (mosiData16_00FF00 & 0xFF), HEX);
00397     //cmdLine.serial().printf(" 0x"));
00398     //Serial.print( (mosiData16_0000FF & 0xFF), HEX);
00399     // hex dump mosiData[0..byteCount-1]
00400 #if 0 // HAS_MICROUSBSERIAL
00401     cmdLine_microUSBserial.serial().printf("\r\nSPI");
00402     if (byteCount > 7) {
00403         cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount);
00404     }
00405     cmdLine_microUSBserial.serial().printf(" MOSI->");
00406     for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
00407     {
00408         cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
00409     }
00410     // hex dump misoData[0..byteCount-1]
00411     cmdLine_microUSBserial.serial().printf(" MISO<-");
00412     for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
00413     {
00414         cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
00415     }
00416     cmdLine_microUSBserial.serial().printf(" ");
00417 #endif
00418 #if 0 // HAS_DAPLINK_SERIAL
00419     cmdLine_DAPLINKserial.serial().printf("\r\nSPI");
00420     if (byteCount > 7) {
00421         cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount);
00422     }
00423     cmdLine_DAPLINKserial.serial().printf(" MOSI->");
00424     for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++)
00425     {
00426         cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]);
00427     }
00428     // hex dump misoData[0..byteCount-1]
00429     cmdLine_DAPLINKserial.serial().printf(" MISO<-");
00430     for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++)
00431     {
00432         cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]);
00433     }
00434     cmdLine_DAPLINKserial.serial().printf(" ");
00435 #endif
00436     // VERIFY: DIAGNOSTIC: print MAX5715 device register write
00437     // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF);
00438     // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF);
00439     //
00440     int misoData16 = (misoData[0] << 8) | misoData[1];
00441     return misoData16;
00442 }
00443 
00444 // Assert MAX11131 CNVST convert start.
00445 // Required when using any of the InternalClock modes with SWCNV 0.
00446 // Trigger measurement by driving CNVST/AIN14 pin low for a minimum active-low pulse duration of 5ns. (AIN14 is not available)
00447 //
00448 void MAX11131::CNVSToutputPulseLow()
00449 {
00450     // m_CNVST_pin.output(); // only applicable to DigitalInOut
00451     m_CNVST_pin = 0; // output logic low
00452     wait(0.01); // pulse low delay time
00453     m_CNVST_pin = 1; // output logic high
00454 }
00455 
00456 // Wait for MAX11131 EOC pin low, indicating end of conversion.
00457 // Required when using any of the InternalClock modes.
00458 //
00459 void MAX11131::EOCinputWaitUntilLow()
00460 {
00461     // m_EOC_pin.input(); // only applicable to DigitalInOut
00462     while (m_EOC_pin != 0)
00463     {
00464         // spinlock waiting for logic low pin state
00465     }
00466 }
00467 
00468 // Return the status of the MAX11131 EOC pin.
00469 //
00470 int MAX11131::EOCinputValue()
00471 {
00472     // m_EOC_pin.input(); // only applicable to DigitalInOut
00473     return m_EOC_pin.read();
00474 }
00475 
00476 //----------------------------------------
00477 // Menu item '!'
00478 // Initialize device
00479 //
00480 // TODO1: #170 MAX11131 Self Test for Test Fixture Firmware
00481 // @future test group ____ // Verify function ____ (enabled by default)
00482 //
00483 // @future test group DACCodeOfVoltage // Verify function DACCodeOfVoltage (enabled by default)
00484 // @future test group DACCodeOfVoltage tinyTester.blink_time_msec = 20 // quickly speed through the software verification
00485 // @future test group DACCodeOfVoltage tinyTester.print("VRef = 2.500  MAX5171 14-bit LSB = 0.00015V")
00486 // @future test group DACCodeOfVoltage VRef = 2.500
00487 // @future test group DACCodeOfVoltage tinyTester.err_threshold = 0.00015259720441921504 // 14-bit LSB (2.500/16383)
00488 //     //
00489 // @future test group DACCodeOfVoltage DACCodeOfVoltage(2.499847412109375) expect 0x3FFF
00490 //     //
00491 //     //
00492 // @future test group CODE_LOAD // Verify function CODE_LOAD (enabled by default)
00493 // @future test group CODE_LOAD tinyTester.blink_time_msec = 75 // default 75 resume hardware self test
00494 // @future test group CODE_LOAD tinyTester.settle_time_msec = 250
00495 // @future test Init()
00496 // @future test VRef expect 2.500 // Nominal Full-Scale Voltage Reference
00497 //     //
00498 //     tinyTester.err_threshold = 0.030; // 30mV
00499 // @future test group CODE_LOAD tinyTester.err_threshold = 0.030
00500 // @future test group CODE_LOAD tinyTester.DigitalIn_Read_Expect_WarnOnly(UPO_pin, "UPO", 1, "UPO_pin is high after MAX5171 UPO_HIGH command")
00501 // @future test group CODE_LOAD tinyTester.AnalogIn0_Read_Expect_voltageV(1.2500)
00502 //
00503 //
00504 //
00505 // TODO1: #170 MAX11131 Self Test for Test Fixture Firmware
00506 // @future test group ____ // Verify function ____ (enabled by default)
00507 // @future test group ____ // Verify function ____ (enabled by default)
00508 //     // MAX11131BOB self-test functions
00509 //     //~ SelfTest_FAIL(cmdLine);
00510 //     //~ cmdLine.serial().printf("test program not implemented yet");
00511 //     int16_t value_u12;
00512 //     int channelId;
00513 //     double voltageV = 0.5;
00514 //     //
00515 //     //cmdLine.serial().printf("
00516 //       0.0: MAX11131.Init()");
00517 //     //Init();
00518 //     //
00519 //     // Device Testing: ADC commands, verify with on-board ADC and SPI framing
00520 //     //
00521 // @test group SPI48_3MSps // support 3MSps parts SCLK<=48MHz (enabled by default)
00522 // @test group SPI48_3MSps tinyTester.print("SPI 48MHz")
00523 // @test group SPI48_3MSps SPIfrequency(48000000); // support 3MSps parts SCLK<=48MHz
00524 // @test group SPI48_3MSps SPIgetFrequency() expect 48000000
00525 // @test group SPI48_3MSps tinyTester.settle_time_msec = 250 // default 250
00526 // @test group SPI48_3MSps tinyTester.Wait_Output_Settling()
00527 // @test group SPI48_3MSps SPIoutputCS(0)
00528 // @test group SPI48_3MSps SPIread16bits()
00529 // @test group SPI48_3MSps SPIoutputCS(1)
00530 // //
00531 // @test group SPI16MHz_1MSps // support 1MSps parts SCLK<=16MHz (enabled by default)
00532 // @test group SPI16MHz_1MSps tinyTester.print("SPI 16MHz")
00533 // @test group SPI16MHz_1MSps SPIfrequency(16000000); // support 1MSps parts SCLK<=16MHz
00534 // @test group SPI16MHz_1MSps SPIgetFrequency() expect 16000000
00535 // @test group SPI16MHz_1MSps tinyTester.settle_time_msec = 250 // default 250
00536 // @test group SPI16MHz_1MSps tinyTester.Wait_Output_Settling()
00537 // @test group SPI16MHz_1MSps SPIoutputCS(0)
00538 // @test group SPI16MHz_1MSps SPIread16bits()
00539 // @test group SPI16MHz_1MSps SPIoutputCS(1)
00540 // //
00541 // @test group SPI8MHz_500kSps // support 500kSps parts SCLK<=8MHz (enabled by default)
00542 // @test group SPI8MHz_500kSps tinyTester.print("SPI 8MHz")
00543 // @test group SPI8MHz_500kSps SPIfrequency(8000000); // support 500kSps parts SCLK<=8MHz
00544 // @test group SPI8MHz_500kSps SPIgetFrequency() expect 8000000
00545 // @test group SPI8MHz_500kSps tinyTester.settle_time_msec = 250 // default 250
00546 // @test group SPI8MHz_500kSps tinyTester.Wait_Output_Settling()
00547 // @test group SPI8MHz_500kSps SPIoutputCS(0)
00548 // @test group SPI8MHz_500kSps SPIread16bits()
00549 // @test group SPI8MHz_500kSps SPIoutputCS(1)
00550 // //
00551 // @test group SPI12MHz_1MSps // support 1MSps parts SCLK<=16MHz (enabled by default)
00552 // @test group SPI12MHz_1MSps tinyTester.print("SPI 12MHz")
00553 // @test group SPI12MHz_1MSps SPIfrequency(12000000); // support 1MSps parts SCLK<=16MHz
00554 // @test group SPI12MHz_1MSps SPIgetFrequency() expect 12000000
00555 // @test group SPI12MHz_1MSps tinyTester.settle_time_msec = 250 // default 250
00556 // @test group SPI12MHz_1MSps tinyTester.Wait_Output_Settling()
00557 // @test group SPI12MHz_1MSps SPIoutputCS(0)
00558 // @test group SPI12MHz_1MSps SPIread16bits()
00559 // @test group SPI12MHz_1MSps SPIoutputCS(1)
00560 // //
00561 // @test tinyTester.blink_time_msec = 75 // default 75 resume hardware self test
00562 //     tinyTester.blink_time_msec = 75;
00563 //     // MAX11131 SelfTest: MAX11131 SPI connections (Power Supply and GND, SCLK, MOSI, MISO, CS)
00564 //     cmdLine.serial().printf("
00565 // ");
00566 //     cmdLine.serial().printf(
00567 //         "
00568 //       1.0: Test Scan_0100_StandardExt -- verify SPI (VDD, GND, SCLK, MOSI, MISO, CS)");
00569 // @test tinyTester.print("0.0: MAX11131.Init()")
00570 //     cmdLine.serial().printf("
00571 //       MAX11131.Init()");
00572 //     Init();
00573 // @test Init()
00574 // @test VRef expect 2.500 // Nominal Full-Scale Voltage Reference
00575 //     //
00576 // @test group TEST10_SCAN_0100 // Test SCAN_0100_StandardExt -- verify VDD,GND,SCLK,MOSI,MISO,CS (enabled by default)
00577 // @test group TEST10_SCAN_0100 tinyTester.print("1.0: Test SCAN_0100_StandardExt -- verify VDD,GND,SCLK,MOSI,MISO,CS")
00578 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00579 // @test group TEST10_SCAN_0100 tinyTester.print("0000_0000_0100_0010  ADC_MODE_CONTROL SCAN_0000")
00580 // @test group TEST10_SCAN_0100 tinyTester.print("                                      CHSEL=0 RESET=2 CHANID=1")
00581 // @test group TEST10_SCAN_0100 SPIwrite16bits(0x0040)
00582 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00583 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00584 // @test group TEST10_SCAN_0100 SPIread16bits()
00585 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00586 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00587 // @test group TEST10_SCAN_0100 SPIread16bits()
00588 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00589 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00590 // @test group TEST10_SCAN_0100 SPIread16bits()
00591 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00592 // @test group TEST10_SCAN_0100 tinyTester.print("1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0")
00593 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00594 // @test group TEST10_SCAN_0100 SPIwrite16bits(0x8000)
00595 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00596 // @test group TEST10_SCAN_0100 tinyTester.print("0010_0111_1010_0100  ADC_MODE_CONTROL SCAN_0100_StandardExt")
00597 // @test group TEST10_SCAN_0100 tinyTester.print("                                      CHSEL=15 RESET=1 CHANID=1")
00598 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00599 // @test group TEST10_SCAN_0100 SPIwrite16bits(0x27a4)
00600 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00601 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x0xxx (channel ID 0)")
00602 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00603 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x0000 mask 0xF000 // expect 0x0xxx (channel ID 0)
00604 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00605 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x1xxx (channel ID 1)")
00606 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00607 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x1000 mask 0xF000 // expect 0x1xxx (channel ID 1)
00608 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00609 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x2xxx (channel ID 2)")
00610 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00611 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x2000 mask 0xF000 // expect 0x2xxx (channel ID 2)
00612 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00613 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x3xxx (channel ID 3)")
00614 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00615 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x3000 mask 0xF000 // expect 0x3xxx (channel ID 3)
00616 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00617 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x4xxx (channel ID 4)")
00618 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00619 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x4000 mask 0xF000 // expect 0x4xxx (channel ID 4)
00620 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00621 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x5xxx (channel ID 5)")
00622 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00623 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x5000 mask 0xF000 // expect 0x5xxx (channel ID 5)
00624 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00625 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x6xxx (channel ID 6)")
00626 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00627 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x6000 mask 0xF000 // expect 0x6xxx (channel ID 6)
00628 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00629 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x7xxx (channel ID 7)")
00630 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00631 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x7000 mask 0xF000 // expect 0x7xxx (channel ID 7)
00632 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00633 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x8xxx (channel ID 8)")
00634 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00635 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x8000 mask 0xF000 // expect 0x8xxx (channel ID 8)
00636 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00637 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0x9xxx (channel ID 9)")
00638 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00639 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0x9000 mask 0xF000 // expect 0x9xxx (channel ID 9)
00640 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00641 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xaxxx (channel ID 10)")
00642 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00643 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0xA000 mask 0xF000 // expect 0xaxxx (channel ID 10)
00644 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00645 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xbxxx (channel ID 11)")
00646 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00647 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0xB000 mask 0xF000 // expect 0xbxxx (channel ID 11)
00648 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00649 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xcxxx (channel ID 12)")
00650 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00651 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0xC000 mask 0xF000 // expect 0xcxxx (channel ID 12)
00652 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00653 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xdxxx (channel ID 13)")
00654 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00655 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0xD000 mask 0xF000 // expect 0xdxxx (channel ID 13)
00656 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00657 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xexxx (channel ID 14)")
00658 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00659 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0xE000 mask 0xF000 // expect 0xexxx (channel ID 14)
00660 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00661 // @test group TEST10_SCAN_0100 tinyTester.print("MISO --> expect 0xfxxx (channel ID 15)")
00662 // @test group TEST10_SCAN_0100 SPIoutputCS(0)
00663 // @test group TEST10_SCAN_0100 SPIread16bits() expect 0xF000 mask 0xF000 // expect 0xfxxx (channel ID 15)
00664 // @test group TEST10_SCAN_0100 SPIoutputCS(1)
00665 //     //
00666 // @test group TEST4_SCAN_0100 // 4 ch=15 pm=0 id=1 -- ScanStandardExternalCloc (enabled by default)
00667 // @test group TEST4_SCAN_0100 tinyTester.print("4 ch=15 pm=0 id=1 -- ScanStandardExternalClock")
00668 // @test group TEST4_SCAN_0100 tinyTester.print("channelNumber_0_15 = 15")
00669 // @test group TEST4_SCAN_0100 channelNumber_0_15 = 15
00670 // @test group TEST4_SCAN_0100 tinyTester.print("PowerManagement_0_2 = 0")
00671 // @test group TEST4_SCAN_0100 PowerManagement_0_2 = 0 // 0=Normal
00672 // @test group TEST4_SCAN_0100 tinyTester.print("chan_id_0_1 = 1")
00673 // @test group TEST4_SCAN_0100 chan_id_0_1 = 1 // misoData16 = CH[3:0] DATA[11:0]
00674 // @test group TEST4_SCAN_0100 tinyTester.print("ScanStandardExternalClock() expect 16")
00675 // @test group TEST4_SCAN_0100 ScanStandardExternalClock() expect 16 // Scan_0100_StandardExt
00676 // @test group TEST4_SCAN_0100 tinyTester.print("NumWords expect 16")
00677 // @test group TEST4_SCAN_0100 NumWords expect 16
00678 // @test group TEST4_SCAN_0100 ReadAINcode()
00679 // @test group TEST4_SCAN_0100 tinyTester.print("Verify RAW_misoData16[0..15]>>12&0x000F == 0..15 channelId")
00680 // @test group TEST4_SCAN_0100 RAW_misoData16[0]  expect 0x0000 mask 0xF000 // expect 0x0xxx (channel ID 0)
00681 // @test group TEST4_SCAN_0100 RAW_misoData16[1]  expect 0x1000 mask 0xF000 // expect 0x1xxx (channel ID 1)
00682 // @test group TEST4_SCAN_0100 RAW_misoData16[2]  expect 0x2000 mask 0xF000 // expect 0x2xxx (channel ID 2)
00683 // @test group TEST4_SCAN_0100 RAW_misoData16[3]  expect 0x3000 mask 0xF000 // expect 0x3xxx (channel ID 3)
00684 // @test group TEST4_SCAN_0100 RAW_misoData16[4]  expect 0x4000 mask 0xF000 // expect 0x4xxx (channel ID 4)
00685 // @test group TEST4_SCAN_0100 RAW_misoData16[5]  expect 0x5000 mask 0xF000 // expect 0x5xxx (channel ID 5)
00686 // @test group TEST4_SCAN_0100 RAW_misoData16[6]  expect 0x6000 mask 0xF000 // expect 0x6xxx (channel ID 6)
00687 // @test group TEST4_SCAN_0100 RAW_misoData16[7]  expect 0x7000 mask 0xF000 // expect 0x7xxx (channel ID 7)
00688 // @test group TEST4_SCAN_0100 RAW_misoData16[8]  expect 0x8000 mask 0xF000 // expect 0x8xxx (channel ID 8)
00689 // @test group TEST4_SCAN_0100 RAW_misoData16[9]  expect 0x9000 mask 0xF000 // expect 0x9xxx (channel ID 9)
00690 // @test group TEST4_SCAN_0100 RAW_misoData16[10] expect 0xA000 mask 0xF000 // expect 0xaxxx (channel ID 10)
00691 // @test group TEST4_SCAN_0100 RAW_misoData16[11] expect 0xB000 mask 0xF000 // expect 0xbxxx (channel ID 11)
00692 // @test group TEST4_SCAN_0100 RAW_misoData16[12] expect 0xC000 mask 0xF000 // expect 0xcxxx (channel ID 12)
00693 // @test group TEST4_SCAN_0100 RAW_misoData16[13] expect 0xD000 mask 0xF000 // expect 0xdxxx (channel ID 13)
00694 // @test group TEST4_SCAN_0100 RAW_misoData16[14] expect 0xE000 mask 0xF000 // expect 0xexxx (channel ID 14)
00695 // @test group TEST4_SCAN_0100 RAW_misoData16[15] expect 0xF000 mask 0xF000 // expect 0xfxxx (channel ID 15)
00696 //     // Send MOSI data       Expect MISO data    Description
00697 //     // 1000_0000_0000_0000  xxxx_xxxx_xxxx_xxxx ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0
00698 //     // 0010_0111_1010_0100  xxxx_xxxx_xxxx_xxxx ADC_MODE_CONTROL Scan_0100_StandardExt CHSEL=15 RESET=1 CHANID=1
00699 //     // 0000_0000_0000_0000  0000_xxxx_xxxx_xxxx Channel ID tag = AIN0 expect high nybble 0
00700 //     // 0000_0000_0000_0000  0001_xxxx_xxxx_xxxx Channel ID tag = AIN1 expect high nybble 1
00701 //     // 0000_0000_0000_0000  0010_xxxx_xxxx_xxxx Channel ID tag = AIN2 expect high nybble 2
00702 //     // 0000_0000_0000_0000  0011_xxxx_xxxx_xxxx Channel ID tag = AIN3 expect high nybble 3
00703 //     //
00704 //     cmdLine.serial().printf("
00705 //       MOSI <-- 1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0");
00706 // @test tinyTester.print("1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0")
00707 //     SPIoutputCS(0); // drive CS low
00708 //     SPIwrite16bits(0x8000);
00709 //     SPIoutputCS(1); // drive CS high
00710 // @test SPIoutputCS(0)
00711 // @test SPIwrite16bits(0x8000)
00712 // @test SPIoutputCS(1)
00713 //     //
00714 //     cmdLine.serial().printf(
00715 //         "
00716 //       MOSI <-- 0010_0111_1010_0100  ADC_MODE_CONTROL Scan_0100_StandardExt CHSEL=15 RESET=1 CHANID=1");
00717 // @test tinyTester.print("0010_0111_1010_0100  ADC_MODE_CONTROL Scan_0100_StandardExt")
00718 // @test tinyTester.print("                                      CHSEL=15 RESET=1 CHANID=1")
00719 //     SPIoutputCS(0); // drive CS low
00720 //     SPIwrite16bits(0x27a4);
00721 //     SPIoutputCS(1); // drive CS high
00722 // @test SPIoutputCS(0)
00723 // @test SPIwrite16bits(0x27a4)
00724 // @test SPIoutputCS(1)
00725 //     //
00726 // @future test SPIoutputCS(0)
00727 // @future SPIread16bits() expect 0x0000
00728 // @future SPIread16bits() expect 0x0000 mask 0xF000
00729 // @future test SPIread16bits() expect 0x1000 mask 0xF000
00730 // @future test SPIread16bits() expect 0x2000 mask 0xF000
00731 // @future test SPIread16bits() expect 0x3000 mask 0xF000
00732 // @future test SPIread16bits() expect 0x4000 mask 0xF000
00733 // @future test SPIread16bits() expect 0x5000 mask 0xF000
00734 // @future test SPIread16bits() expect 0x6000 mask 0xF000
00735 // @future test SPIread16bits() expect 0x7000 mask 0xF000
00736 // @future test SPIread16bits() expect 0x8000 mask 0xF000
00737 // @future test SPIread16bits() expect 0x9000 mask 0xF000
00738 // @future test SPIread16bits() expect 0xA000 mask 0xF000
00739 // @future test SPIread16bits() expect 0xB000 mask 0xF000
00740 // @future test SPIread16bits() expect 0xC000 mask 0xF000
00741 // @future test SPIread16bits() expect 0xD000 mask 0xF000
00742 // @future test SPIread16bits() expect 0xE000 mask 0xF000
00743 // @future test SPIread16bits() expect 0xF000 mask 0xF000
00744 // @future test SPIoutputCS(1)
00745 //     //
00746 //     for (int channelIndex = 0; channelIndex < 16; channelIndex++) {
00747 //         //~ cmdLine.serial().printf("
00748 //       MISO --> expect 0000_xxxx_xxxx_xxxx");
00749 //         SPIoutputCS(0); // drive CS low
00750 //         RAW_misoData16[channelIndex] = SPIread16bits();
00751 //         SPIoutputCS(1); // drive CS high
00752 //         int expect_channelId = channelIndex;
00753 //         int actual_channelId = (RAW_misoData16[channelIndex] >> 12) & 0x000F;
00754 //         if (actual_channelId != expect_channelId)
00755 //         {
00756 //             tinyTester.FAIL();
00757 //             cmdLine.serial().printf("MISO --> 0x%4.4x", (RAW_misoData16[channelIndex] & 0xFFFF));
00758 //             cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
00759 //             cmdLine.serial().printf(" but got 0x%1.1xxxx", actual_channelId);
00760 //         }
00761 //         else
00762 //         {
00763 //             tinyTester.PASS();
00764 //             cmdLine.serial().printf("MISO --> 0x%4.4x", (RAW_misoData16[channelIndex] & 0xFFFF));
00765 //             cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
00766 //         }
00767 //     }
00768 // @future test tinyTester.print("NumWords=16")
00769 // @future test NumWords=16
00770 // @future test tinyTester.print("ReadAINcode()")
00771 // @future test ReadAINcode()
00772 // @future test tinyTester.print("TODO: expect RAW_misoData16[0..15]>>12&0x000F == 0..15 channelId")
00773 // @future test RAW_misoData16[0] expect 0x0000 mask 0xF000
00774 // @future test RAW_misoData16[1] expect 0x1000 mask 0xF000
00775 // @future test RAW_misoData16[2] expect 0x2000 mask 0xF000
00776 // @future test RAW_misoData16[3] expect 0x3000 mask 0xF000
00777 //     //
00778 //     // MAX11131 SelfTest: MAX11131 Supports Internal Clock Modes (CNVST, EOC)
00779 //     cmdLine.serial().printf("
00780 // ");
00781 //     cmdLine.serial().printf(
00782 //         "
00783 //       1.1: Test Scan_0011_StandardInt -- verify Internal Clock signals (CNVST, EOC)");
00784 // @test group TEST11_SCAN_0011 // 1.1: Test Scan_0011_StandardInt -- verify Internal Clock CNVST,EOC (enabled by default)
00785 // @test group TEST11_SCAN_0011 tinyTester.print("1.1: Test Scan_0011_StandardInt -- verify Internal Clock CNVST,EOC")
00786 //     cmdLine.serial().printf("
00787 //       MAX11131.Init()");
00788 // @future test tinyTester.print("_______")
00789 // @test group TEST11_SCAN_0011 Init();
00790 // @test group TEST11_SCAN_0011 SPIoutputCS(0); // drive CS low
00791 //     RAW_misoData16[0] = SPIread16bits();
00792 // @test group TEST11_SCAN_0011 group TEST11_SCAN_0011 SPIoutputCS(1); // drive CS high
00793 // //
00794 //     // tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_MAX11131_EOC_expect
00795 //     tinyTester.DigitalIn_Read_Expect_WarnOnly(EOCb_pin, "EOC", 1, "initial value before sending commands");
00796 // //
00797 //     // Send MOSI data       Expect MISO data    Description
00798 //     // 1000_0000_0000_0000  xxxx_xxxx_xxxx_xxxx ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0 No Averaging
00799 //     // 0001_1001_1010_0000  xxxx_xxxx_xxxx_xxxx ADC_MODE_CONTROL Scan_0011_StandardInt CHSEL=3 RESET=1 SWCNV=0
00800 //     // 0000_0000_0000_0000  0000_xxxx_xxxx_xxxx Channel ID tag = AIN0 expect high nybble 0
00801 //     // 0000_0000_0000_0000  0001_xxxx_xxxx_xxxx Channel ID tag = AIN1 expect high nybble 1
00802 //     // 0000_0000_0000_0000  0010_xxxx_xxxx_xxxx Channel ID tag = AIN2 expect high nybble 2
00803 //     // 0000_0000_0000_0000  0011_xxxx_xxxx_xxxx Channel ID tag = AIN3 expect high nybble 3
00804 //     //
00805 //     cmdLine.serial().printf("
00806 //       MOSI <-- 1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0");
00807 // @test group TEST11_SCAN_0011 tinyTester.print("1000_0000_0000_0000  ADC_CONFIGURATION REFSEL=0 SPM[1:0]=0 ECHO=0")
00808 // @test group TEST11_SCAN_0011 SPIoutputCS(0); // drive CS low
00809 // @test group TEST11_SCAN_0011 SPIwrite16bits(0x8000);
00810 // @test group TEST11_SCAN_0011 SPIoutputCS(1); // drive CS high
00811 //     //
00812 //     cmdLine.serial().printf(
00813 //         "
00814 //       MOSI <-- 0001_1001_1010_0000  ADC_MODE_CONTROL Scan_0011_StandardInt CHSEL=3 RESET=1 SWCNV=0");
00815 // @test group TEST11_SCAN_0011 tinyTester.print("0001_1001_1010_0000  ADC_MODE_CONTROL Scan_0011_StandardInt")
00816 // @test group TEST11_SCAN_0011 tinyTester.print("                                      CHSEL=3 RESET=1 SWCNV=0")
00817 // @test group TEST11_SCAN_0011 SPIoutputCS(0); // drive CS low
00818 // @test group TEST11_SCAN_0011 SPIwrite16bits(0x19a0);
00819 // @test group TEST11_SCAN_0011 SPIoutputCS(1); // drive CS high
00820 //     //
00821 //     for (int channelIndex = 0; channelIndex < 4; channelIndex++) {
00822 //         //~ cmdLine.serial().printf("
00823 //       MISO --> expect 0000_xxxx_xxxx_xxxx");
00824 //         //~ wait_ms(200); // delay
00825 //         CNVSToutputPulseLow();
00826 //         //~ CNVSToutputValue(0);
00827 //         //~ wait_ms(100); // delay
00828 //         //~ CNVSToutputValue(1);
00829 //         // EOCinputWaitUntilLow(); // infinite wait hazard, need to fail if timeout exceeded
00830 //         // tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_MAX11131_EOC_expect
00831 //         tinyTester.DigitalIn_Read_Expect_WarnOnly(EOCb_pin, "EOC", 0, "after CNVST pulse");
00832 //         SPIoutputCS(0); // drive CS low
00833 //         RAW_misoData16[channelIndex] = SPIread16bits();
00834 //         SPIoutputCS(1); // drive CS high
00835 //         // tinyTester.DigitalIn_Read_Expect_WarnOnly replaces SelfTest_MAX11131_EOC_expect
00836 //         tinyTester.DigitalIn_Read_Expect_WarnOnly(EOCb_pin, "EOC", 1, "after SPI read");
00837 //         int expect_channelId = channelIndex;
00838 //         int actual_channelId = (RAW_misoData16[channelIndex] >> 12) & 0x000F;
00839 //         if (actual_channelId != expect_channelId)
00840 //         {
00841 //             tinyTester.FAIL();
00842 //             cmdLine.serial().printf("MISO --> 0x%4.4x", (RAW_misoData16[channelIndex] & 0xFFFF));
00843 //             cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
00844 //             cmdLine.serial().printf(" but got 0x%1.1xxxx", actual_channelId);
00845 //         }
00846 //         else
00847 //         {
00848 //             tinyTester.PASS();
00849 //             cmdLine.serial().printf("MISO --> 0x%4.4x", (RAW_misoData16[channelIndex] & 0xFFFF));
00850 //             cmdLine.serial().printf(" expect 0x%1.1xxxx (channel ID %d)", expect_channelId, expect_channelId);
00851 //         }
00852 //     }
00853 //     //
00854 //     // MAX11131 SelfTest: Test Fixture: MAX541ACPA+ to MAX32625MBED.AIN0/AIN4
00855 //     // Test Fixture: MAX541 connected to spi2
00856 //     // SPI spi2_max541(SPI2_MOSI, SPI2_MISO, SPI2_SCK); // mosi, miso, sclk spi2 TARGET_MAX32635MBED: P2_5 P2_6 P2_4 Arduino 2x3-pin header; microSD
00857 //     // DigitalOut spi2_max541_cs(SPI2_SS); // TARGET_MAX32635MBED: P2_7 Arduino 2x3-pin header
00858 //     // Test Fixture: MAX541 spi2 init
00859 //     cmdLine.serial().printf("
00860 // ");
00861 //     cmdLine.serial().printf("
00862 //       2.0: Test Fixture: MAX541 connected to spi2 (P2.4 P2.5 P2.7)?");
00863 // @future test tinyTester.print("_______")
00864 //     bool SelfTest_has_max541 = false;
00865 //     // Check actual MAX541 reference voltage
00866 //     cmdLine.serial().printf("
00867 //       Test Fixture: MAX541 midscale voltage measure with MAX32625MBED AIN0/4");
00868 //     max541.Set_Code(0x8000); // we don't know the fullscale voltage yet, so set code to midscale
00869 //     tinyTester.Wait_Output_Settling(); // wait for MAX541 to settle
00870 //     //
00871 //     double max541_midscale_V = analogInPin_fullScaleVoltage[4] * analogIn4.read(); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
00872 //     const int average_count = 100;
00873 //     const double average_K = 0.25;
00874 //     for (int count = 0; count < average_count; count++) {
00875 //         double measurement_V = analogInPin_fullScaleVoltage[4] * analogIn4.read(); // TARGET_MAX32630 J1.5 AIN_4 = AIN0 / 5.0     fullscale is 6.0V
00876 //         max541_midscale_V = ((1 - average_K) * max541_midscale_V) + (average_K * measurement_V);
00877 //     }
00878 //     if (max541_midscale_V > 1.0f) {
00879 //         max541.VRef = 2.0 * max541_midscale_V;
00880 //         cmdLine.serial().printf("
00881 //       Test Fixture: MAX541 midscale = %1.3fV, so fullscale = %1.3fV",
00882 //                                 max541_midscale_V, max541.VRef);
00883 //         // Detect whether MAX541 is really connected to MAX32625MBED.AIN0/AIN4
00884 //         voltageV = 1.0f;
00885 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00886 //     }
00887 //     if (SelfTest_has_max541) {
00888 //         voltageV = 0.0f;
00889 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00890 //     }
00891 //     if (SelfTest_has_max541) {
00892 //         voltageV = 2.7f;
00893 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00894 //     }
00895 //     if (SelfTest_has_max541) {
00896 //         voltageV = 1.65f;
00897 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00898 //     }
00899 //     if (SelfTest_has_max541) {
00900 //         voltageV = 2.0f;
00901 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00902 //     }
00903 //     if (SelfTest_has_max541) {
00904 //         voltageV = 0.25f;
00905 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00906 //     }
00907 //     if (SelfTest_has_max541) {
00908 //         voltageV = 0.5f;
00909 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00910 //     }
00911 //     if (SelfTest_has_max541) {
00912 //         voltageV = 1.0f;
00913 //         SelfTest_has_max541 = SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00914 //     }
00915 //     if (SelfTest_has_max541 == false) {
00916 //         // don't fail just because we're missing the test fixture...
00917 //         cmdLine.serial().printf("
00918 //       Test Fixture: MAX541 not present");
00919 //         //~ g_SelfTest_nFail--;
00920 //     }
00921 //     //
00922 //     // TODO1: MAX11131 SelfTest: if Test Fixture: drive MAX541, compare MAX32625MBED.AIN0/AIN4 and MAX11131 AIN0
00923 //     // indirectly verify the reference voltage by reading a known input voltage
00924 //     if (SelfTest_has_max541) {
00925 //         cmdLine.serial().printf("
00926 // ");
00927 //         cmdLine.serial().printf("
00928 //       2.1: TODO1: Check MAX11131 reference voltage using Scan_0001_Manual");
00929 // @future test tinyTester.print("_______")
00930 //         voltageV = 1.0f;
00931 //         SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00932 //         cmdLine.serial().printf("
00933 //       MAX11131.Init()");
00934 //         Init();
00935 //         // 1 ScanManual ch=0 pm=0 id=1
00936 //         channelNumber_0_15 = 0;
00937 //         PowerManagement_0_2 = 0;
00938 //         chan_id_0_1 = 1;
00939 //         cmdLine.serial().printf("
00940 //       MAX11131.channelNumber_0_15=%d", channelNumber_0_15);
00941 //         cmdLine.serial().printf("
00942 //       MAX11131.PowerManagement_0_2=%d", PowerManagement_0_2);
00943 //         cmdLine.serial().printf("
00944 //       MAX11131.chan_id_0_1=%d", chan_id_0_1);
00945 //         NumWords = ScanManual();
00946 //         cmdLine.serial().printf("
00947 //       MAX11131.ScanManual -- NumWords = %d",
00948 //                                 NumWords);
00949 //         NumWords = ScanManual();
00950 //         ReadAINcode();
00951 //         cmdLine.serial().printf("
00952 //       MAX11131.ReadAINcode");
00953 //         AINcode_print_value_externalClock(cmdLine, NumWords);
00954 //         //
00955 //         //  2.1: TODO1: Check MAX11131 reference voltage -- why we read 0xffff 2.4999V here?
00956 //         //
00957 //         cmdLine.serial().printf("
00958 //       MAX11131.ScanManual -- NumWords = %d",
00959 //                                 NumWords);
00960 //         // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
00961 //         // @pre one of the MAX11311_Scan functions was called, setting NumWords
00962 //         ReadAINcode();
00963 //         cmdLine.serial().printf("
00964 //       MAX11131.ReadAINcode");
00965 //         AINcode_print_value_externalClock(cmdLine, NumWords);
00966 //         //
00967 //         //  2.1: TODO1: Check MAX11131 reference voltage -- why we read 0xffff 2.4999V here?
00968 //         //
00969 //         // compare with mbed/Arduino AIN0-AIN3
00970 //         // MAX32625MBED.AIN4 = MAX11131.AIN0
00971 //         channelId = 0;
00972 //         value_u12 = AINcode[channelId];
00973 //         voltageV = VoltageOfCode(value_u12, channelId);
00974 // //
00975 //         // tinyTester.Wait_Output_Settling replaces wait_ms
00976 //         tinyTester.Wait_Output_Settling();
00977 //         // tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
00978 //         tinyTester.err_threshold = 0.100;
00979 //         tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
00980 // //
00981 //     }
00982 //     //
00983 //     if (SelfTest_has_max541) {
00984 //         voltageV = 1.0f;
00985 //         SelfTest_MAX541_Voltage(cmdLine, max541, voltageV);
00986 //     }
00987 //     cmdLine.serial().printf("
00988 // ");
00989 //     cmdLine.serial().printf("
00990 //       3.1: Test Scan_0001_Manual");
00991 // @future test tinyTester.print("_______")
00992 //     cmdLine.serial().printf("
00993 //       MAX11131.Init()");
00994 //     Init();
00995 //     // 1 ScanManual ch=0 pm=0 id=1
00996 //     channelNumber_0_15 = 0;
00997 //     PowerManagement_0_2 = 0;
00998 //     chan_id_0_1 = 1;
00999 //     cmdLine.serial().printf("
01000 //       MAX11131.channelNumber_0_15=%d", channelNumber_0_15);
01001 // @future test tinyTester.print("_______")
01002 //     cmdLine.serial().printf("
01003 //       MAX11131.PowerManagement_0_2=%d", PowerManagement_0_2);
01004 // @future test tinyTester.print("_______")
01005 //     cmdLine.serial().printf("
01006 //       MAX11131.chan_id_0_1=%d", chan_id_0_1);
01007 // @future test tinyTester.print("_______")
01008 //     NumWords = ScanManual();
01009 //     cmdLine.serial().printf("
01010 //       MAX11131.ScanManual -- NumWords = %d",
01011 //                             NumWords);
01012 // @future test tinyTester.print("_______")
01013 //     // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
01014 //     // @pre one of the MAX11311_Scan functions was called, setting NumWords
01015 //     ReadAINcode();
01016 //     cmdLine.serial().printf("
01017 //       MAX11131.ReadAINcode");
01018 // @future test tinyTester.print("_______")
01019 //     AINcode_print_value_externalClock(cmdLine, NumWords);
01020 //     // compare with mbed/Arduino AIN0-AIN3
01021 //     // MAX32625MBED.AIN4 = MAX11131.AIN0
01022 //     channelId = 0;
01023 //     value_u12 = AINcode[channelId];
01024 //     voltageV = VoltageOfCode(value_u12, channelId);
01025 // //
01026 //     // tinyTester.Wait_Output_Settling replaces wait_ms
01027 //     tinyTester.Wait_Output_Settling();
01028 //     // tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
01029 //     tinyTester.err_threshold = 0.100;
01030 //     tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
01031 // //
01032 //     //
01033 //     cmdLine.serial().printf("
01034 // ");
01035 //     cmdLine.serial().printf("
01036 //       3.4: Test Scan_0100_StandardExternalClock");
01037 // @future test tinyTester.print("_______")
01038 //     cmdLine.serial().printf("
01039 //       MAX11131.Init()");
01040 //     Init();
01041 //     // MAX11131 > 4
01042 //     // ScanStandardExternalClock ch=9 pm=0 id=1
01043 //     // ScanRead_nWords_chanID nWords=10
01044 //     //  ch=0 xu=2964 = 0x0b94 = 1.8091V
01045 //     //  ch=1 xu=2227 = 0x08b3 = 1.3593V
01046 //     //  ch=2 xu=1570 = 0x0622 = 0.9583V
01047 //     //  ch=3 xu=865 = 0x0361 = 0.5280V
01048 //     //  ch=4 xu=630 = 0x0276 = 0.3845V
01049 //     //  ch=5 xu=594 = 0x0252 = 0.3625V
01050 //     //  ch=6 xu=461 = 0x01cd = 0.2814V
01051 //     //  ch=7 xu=364 = 0x016c = 0.2222V
01052 //     //  ch=8 xu=480 = 0x01e0 = 0.2930V
01053 //     //  ch=9 xu=616 = 0x0268 = 0.3760V
01054 //     channelNumber_0_15 = 9;
01055 //     PowerManagement_0_2 = 0;
01056 //     chan_id_0_1 = 1;
01057 //     cmdLine.serial().printf("
01058 //       MAX11131.channelNumber_0_15=%d", channelNumber_0_15);
01059 // @future test tinyTester.print("_______")
01060 //     cmdLine.serial().printf("
01061 //       MAX11131.PowerManagement_0_2=%d", PowerManagement_0_2);
01062 // @future test tinyTester.print("_______")
01063 //     cmdLine.serial().printf("
01064 //       MAX11131.chan_id_0_1=%d", chan_id_0_1);
01065 // @future test tinyTester.print("_______")
01066 //     NumWords = ScanStandardExternalClock();
01067 //     cmdLine.serial().printf("
01068 //       MAX11131.ScanStandardExternalClock -- NumWords = %d",
01069 //                             NumWords);
01070 // @future test tinyTester.print("_______")
01071 //     // Read raw ADC codes from device into AINcode[] and RAW_misoData16[]
01072 //     // @pre one of the MAX11311_Scan functions was called, setting NumWords
01073 //     ReadAINcode();
01074 //     cmdLine.serial().printf("
01075 //       MAX11131.ReadAINcode");
01076 // @future test tinyTester.print("_______")
01077 //     // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
01078 //     // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
01079 //     // expect NumWords == channelNumber_0_15 + 1;
01080 //     // expect RAW_misoData16[index] msnybble 0,1,2,3,...
01081 //     AINcode_print_value_externalClock(cmdLine, NumWords);
01082 //     // compare with mbed/Arduino AIN0-AIN3
01083 //     // MAX32625MBED.AIN4 = MAX11131.AIN0
01084 //     channelId = 0;
01085 //     value_u12 = AINcode[channelId];
01086 //     voltageV = VoltageOfCode(value_u12, channelId);
01087 //     // tinyTester.Wait_Output_Settling replaces wait_ms
01088 //     tinyTester.Wait_Output_Settling();
01089 //     // tinyTester.AnalogIn0_Read_Expect_voltageV replaces SelfTest_AnalogInput_Expect_ch_V
01090 //     tinyTester.err_threshold = 0.100;
01091 //     tinyTester.AnalogIn0_Read_Expect_voltageV(voltageV);
01092 //     // compare MAX32625MBED.AIN5 = MAX11131.AIN1
01093 //     //channelId = 1;
01094 //     //value_u12 = AINcode[channelId];
01095 //     //voltageV = VoltageOfCode(value_u12, channelId);
01096 //     //SelfTest_AnalogInput_Expect_ch_V(cmdLine, 5, voltageV, 0.100);
01097 //
01098 //
01099 //
01100 void MAX11131::Init(void)
01101 {
01102     
01103     //----------------------------------------
01104     // Nominal Full-Scale Voltage Reference
01105     VRef = 2.500;
01106     
01107     //----------------------------------------
01108     // define write-only register ADC_MODE_CONTROL
01109     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
01110     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
01111     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
01112     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
01113     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
01114     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
01115     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
01116     
01117     //----------------------------------------
01118     // define write-only register ADC_CONFIGURATION
01119     ADC_CONFIGURATION = 0x8000; //!< mosiData16 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
01120     const int REFSEL_LSB = 10; const int REFSEL_BITS = 0x01; // ADC_CONFIGURATION.REFSEL
01121     const int AVGON_LSB  =  9; const int AVGON_BITS  = 0x01; // ADC_CONFIGURATION.AVGON
01122     const int NAVG_LSB   =  7; const int NAVG_BITS   = 0x03; // ADC_CONFIGURATION.NAVG[1:0]
01123     const int NSCAN_LSB  =  5; const int NSCAN_BITS  = 0x03; // ADC_CONFIGURATION.NSCAN[1:0]
01124     const int SPM_LSB    =  3; const int SPM_BITS    = 0x03; // ADC_CONFIGURATION.SPM[1:0]
01125     const int ECHO_LSB   =  2; const int ECHO_BITS   = 0x01; // ADC_CONFIGURATION.ECHO
01126     
01127     //----------------------------------------
01128     // define write-only registers UNIPOLAR,BIPOLAR,RANGE
01129     UNIPOLAR = 0x8800;          //!< mosiData16 0x8800..0x8FFF format: 1 0 0 0 1 UCH0/1 UCH2/3 UCH4/5 UCH6/7 UCH8/9 UCH10/11 UCH12/13 UCH14/15 PDIFF_COM x x
01130     BIPOLAR = 0x9000;           //!< mosiData16 0x9000..0x97FF format: 1 0 0 1 0 BCH0/1 BCH2/3 BCH4/5 BCH6/7 BCH8/9 BCH10/11 BCH12/13 BCH14/15 x x x
01131     RANGE = 0x9800;             //!< mosiData16 0x9800..0x9FFF format: 1 0 0 1 1 RANGE0/1 RANGE2/3 RANGE4/5 RANGE6/7 RANGE8/9 RANGE10/11 RANGE12/13 RANGE14/15 x x x
01132     const int AIN_0_1_LSB   = 10; // UNIPOLAR.UCH0/1    BIPOLAR.BCH0/1    RANGE.RANGE0/1  
01133     const int AIN_2_3_LSB   =  9; // UNIPOLAR.UCH2/3    BIPOLAR.BCH2/3    RANGE.RANGE2/3  
01134     const int AIN_4_5_LSB   =  8; // UNIPOLAR.UCH4/5    BIPOLAR.BCH4/5    RANGE.RANGE4/5  
01135     const int AIN_6_7_LSB   =  7; // UNIPOLAR.UCH6/7    BIPOLAR.BCH6/7    RANGE.RANGE6/7  
01136     const int AIN_8_9_LSB   =  6; // UNIPOLAR.UCH8/9    BIPOLAR.BCH8/9    RANGE.RANGE8/9  
01137     const int AIN_10_11_LSB =  5; // UNIPOLAR.UCH10/11  BIPOLAR.BCH10/11  RANGE.RANGE10/11
01138     const int AIN_12_13_LSB =  4; // UNIPOLAR.UCH12/13  BIPOLAR.BCH12/13  RANGE.RANGE12/13
01139     const int AIN_14_15_LSB =  3; // UNIPOLAR.UCH14/15  BIPOLAR.BCH14/15  RANGE.RANGE14/15
01140     const int PDIFF_COMM_LSB =  2; const int PDIFF_COMM_BITS =  0x01; // UNIPOLAR.PDIFF_COM
01141     // Summary of Table 8:
01142     // UCH0/1=0, BCH0/1=0, RANGE0/1=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01143     // UCH0/1=1, BCH0/1=0, RANGE0/1=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01144     // UCH0/1=0, BCH0/1=1, RANGE0/1=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01145     // UCH0/1=1, BCH0/1=1, RANGE0/1=0: reserved do not use
01146     // UCH0/1=0, BCH0/1=0, RANGE0/1=1: reserved do not use
01147     // UCH0/1=1, BCH0/1=0, RANGE0/1=1: reserved do not use
01148     // UCH0/1=0, BCH0/1=1, RANGE0/1=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01149     // UCH0/1=1, BCH0/1=1, RANGE0/1=1: reserved do not use
01150     // Both channels of a differential pair must be within Input Voltage Range (dynamic signal range) 0..VREF.
01151     
01152     //----------------------------------------
01153     // define write-only registers CSCAN0,CSCAN1
01154     CSCAN0 = 0xA000;            //!< mosiData16 0xA000..0xA7FF format: 1 0 1 0 0 CHSCAN15 CHSCAN14 CHSCAN13 CHSCAN12 CHSCAN11 CHSCAN10 CHSCAN9 CHSCAN8 x x x
01155     const int CHSCAN15_LSB = 10; // CSCAN0.CHSCAN15
01156     const int CHSCAN14_LSB =  9; // CSCAN0.CHSCAN14
01157     const int CHSCAN13_LSB =  8; // CSCAN0.CHSCAN13
01158     const int CHSCAN12_LSB =  7; // CSCAN0.CHSCAN12
01159     const int CHSCAN11_LSB =  6; // CSCAN0.CHSCAN11
01160     const int CHSCAN10_LSB =  5; // CSCAN0.CHSCAN10
01161     const int CHSCAN9_LSB  =  4; // CSCAN0.CHSCAN9
01162     const int CHSCAN8_LSB  =  3; // CSCAN0.CHSCAN8
01163     CSCAN1 = 0xA800;            //!< mosiData16 0xA800..0xAFFF format: 1 0 1 0 1 CHSCAN7 CHSCAN6 CHSCAN5 CHSCAN4 CHSCAN3 CHSCAN2 CHSCAN1 CHSCAN0 x x x
01164     const int CHSCAN7_LSB = 10; // CSCAN1.CHSCAN7
01165     const int CHSCAN6_LSB =  9; // CSCAN1.CHSCAN6
01166     const int CHSCAN5_LSB =  8; // CSCAN1.CHSCAN5
01167     const int CHSCAN4_LSB =  7; // CSCAN1.CHSCAN4
01168     const int CHSCAN3_LSB =  6; // CSCAN1.CHSCAN3
01169     const int CHSCAN2_LSB =  5; // CSCAN1.CHSCAN2
01170     const int CHSCAN1_LSB =  4; // CSCAN1.CHSCAN1
01171     const int CHSCAN0_LSB =  3; // CSCAN1.CHSCAN0
01172     
01173     //----------------------------------------
01174     // Initialize shadow of write-only register SAMPLESET.
01175     // Do not write to SAMPLESET at this time.
01176     // A write to SAMPLESET must be followed by specified number of pattern entry words.
01177     // See ScanSampleSetExternalClock function for details.
01178     SAMPLESET = 0xB000;         //!< mosiData16 0xB000..0xB7FF format: 1 0 1 1 0 SEQ_LENGTH[7:0] x x x
01179     const int SAMPLESET_LSB   =  3; const int SAMPLESET_BITS   = 0xFF; // SAMPLESET.SEQ_LENGTH[7:0]
01180     
01181     //----------------------------------------
01182     // Reset all registers: ADC_MODE_CONTROL.RESET[1:0] = 2
01183     ADC_MODE_CONTROL &= ~ ((    RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
01184     ADC_MODE_CONTROL |=   ((2 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
01185     
01186     //----------------------------------------
01187     // SPI write ADC MODE CONTROL register
01188     // Send SPI configuration to device
01189     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01190     SPIoutputCS(0); // drive CS low
01191     SPIwrite16bits(ADC_MODE_CONTROL);
01192     SPIoutputCS(1); // drive CS high
01193 
01194 #if REFSEL_0
01195     
01196     //----------------------------------------
01197     // Global setting for all channels: ADC_CONFIGURATION.REFSEL=0: external single-ended reference
01198     // SELECT REFERENCE SINGLE-ENDED OR DIFFERENTIAL
01199     // SELECT REFERENCE SINGLE-ENDED OR DIFFERENTIAL: EXTERNAL SINGLE-ENDED
01200     // SELECT ADC CONFIGURATION register set REFSEL BIT TO 0
01201     ADC_CONFIGURATION &= ~ ((    REFSEL_BITS) << REFSEL_LSB); // ADC_CONFIGURATION.REFSEL=0: external single-ended reference. (For the 16-channel chips: channel AIN15 is available.)
01202 #endif // REFSEL_0
01203 
01204 #if REFSEL_1
01205     
01206     //----------------------------------------
01207     // Global setting for all channels: ADC_CONFIGURATION.REFSEL=1: external differential reference (For the 16-channel chips: channel AIN15 is unavailable, the pin is assigned to REF-.)
01208     // SELECT REFERENCE SINGLE-ENDED OR DIFFERENTIAL
01209     // SELECT REFERENCE SINGLE-ENDED OR DIFFERENTIAL: EXTERNAL DIFFERENTIAL
01210     // SELECT ADC CONFIGURATION register set REFSEL BIT TO 1
01211     ADC_CONFIGURATION |=   ((1 & REFSEL_BITS) << REFSEL_LSB); // ADC_CONFIGURATION.REFSEL=1: external differential reference. (For the 16-channel chips: channel AIN15 is unavailable, the pin is assigned to REF-.)
01212 #endif // REFSEL_1
01213 
01214 #if PDIFF_COMM_0
01215     
01216     //----------------------------------------
01217     // Global setting for all channels: PDIFF_COMM
01218     UNIPOLAR &= ~ ((    PDIFF_COMM_BITS) << PDIFF_COMM_LSB); // UNIPOLAR.PDIFF_COMM=0: all single-ended channels use GND as common
01219 #endif // PDIFF_COMM_0
01220 
01221 #if PDIFF_COMM_1
01222     
01223     //----------------------------------------
01224     // Global setting for all channels: PDIFF_COMM
01225     // SELECT UNIPOLAR AND register set BIT PDIFF_COM TO 1 FOR PSEUDODIFFERENTIAL SELECTION
01226     UNIPOLAR |=   ((1 & PDIFF_COMM_BITS) << PDIFF_COMM_LSB); // UNIPOLAR.PDIFF_COMM=1: all single-ended channels are pseudo-differential with REF- as common
01227 #endif // PDIFF_COMM_1
01228 
01229 #if AIN_0_1_SingleEnded
01230     
01231     //----------------------------------------
01232     // ADC Channels AIN0, AIN1 = Both Single-Ended, Unipolar
01233     // Full Scale = VREF
01234     // Voltage per LSB count = VREF/4096
01235     // AIN0 is a Single-Ended input using Unipolar transfer function.
01236     // AIN1 is a Single-Ended input using Unipolar transfer function.
01237     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01238     // AIN0 voltage must always be between 0 and VREF.
01239     // AIN1 voltage must always be between 0 and VREF.
01240     //
01241     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01242     UNIPOLAR &= ~ (1 << AIN_0_1_LSB);
01243     BIPOLAR  &= ~ (1 << AIN_0_1_LSB);
01244     RANGE    &= ~ (1 << AIN_0_1_LSB);
01245     // UCH0/1=0, BCH0/1=0, RANGE0/1=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01246 #endif // AIN_0_1_SingleEnded
01247 
01248 #if AIN_0_1_DifferentialUnipolar
01249     
01250     //----------------------------------------
01251     // ADC Channels AIN0, AIN1 = Differential Unipolar (AIN0 > AIN1)
01252     // Full Scale = VREF
01253     // Voltage per LSB count = VREF/4096
01254     // AIN0, AIN1 are a Differential pair using Unipolar transfer function.
01255     // AIN0 voltage must always be between 0 and VREF.
01256     // AIN1 voltage must always be between 0 and VREF.
01257     //
01258     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01259     UNIPOLAR |=   (1 << AIN_0_1_LSB);
01260     BIPOLAR  &= ~ (1 << AIN_0_1_LSB);
01261     RANGE    &= ~ (1 << AIN_0_1_LSB);
01262     // UCH0/1=1, BCH0/1=0, RANGE0/1=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01263 #endif // AIN_0_1_DifferentialUnipolar
01264 
01265 #if AIN_0_1_DifferentialBipolarFSVref
01266     
01267     //----------------------------------------
01268     // ADC Channels AIN0, AIN1 = Differential Bipolar
01269     // Full Scale = VREF
01270     // Voltage per LSB count = VREF/4096
01271     // AIN0, AIN1 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01272     // AIN0 voltage must always be between 0 and VREF.
01273     // AIN1 voltage must always be between 0 and VREF.
01274     //
01275     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01276     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01277     UNIPOLAR &= ~ (1 << AIN_0_1_LSB);
01278     BIPOLAR  |=   (1 << AIN_0_1_LSB);
01279     RANGE    &= ~ (1 << AIN_0_1_LSB);
01280     // UCH0/1=0, BCH0/1=1, RANGE0/1=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01281 #endif // AIN_0_1_DifferentialBipolarFSVref
01282 
01283 #if AIN_0_1_DifferentialBipolarFS2Vref
01284     
01285     //----------------------------------------
01286     // ADC Channels AIN0, AIN1 = Differential Bipolar
01287     // Full Scale = 2 * VREF
01288     // Voltage per LSB count = VREF/2048
01289     // AIN0, AIN1 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01290     // AIN0 voltage must always be between 0 and VREF.
01291     // AIN1 voltage must always be between 0 and VREF.
01292     //
01293     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01294     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01295     UNIPOLAR &= ~ (1 << AIN_0_1_LSB);
01296     BIPOLAR  |=   (1 << AIN_0_1_LSB);
01297     RANGE    |=   (1 << AIN_0_1_LSB);
01298     // UCH0/1=0, BCH0/1=1, RANGE0/1=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01299 #endif // AIN_0_1_DifferentialBipolarFS2Vref
01300 
01301 #if AIN_2_3_SingleEnded
01302     
01303     //----------------------------------------
01304     // ADC Channels AIN2, AIN3 = Both Single-Ended, Unipolar
01305     // Full Scale = VREF
01306     // Voltage per LSB count = VREF/4096
01307     // AIN2 is a Single-Ended input using Unipolar transfer function.
01308     // AIN3 is a Single-Ended input using Unipolar transfer function.
01309     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01310     // AIN2 voltage must always be between 0 and VREF.
01311     // AIN3 voltage must always be between 0 and VREF.
01312     //
01313     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01314     UNIPOLAR &= ~ (1 << AIN_2_3_LSB);
01315     BIPOLAR  &= ~ (1 << AIN_2_3_LSB);
01316     RANGE    &= ~ (1 << AIN_2_3_LSB);
01317     // UCH2/3=0, BCH2/3=0, RANGE2/3=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01318 #endif // AIN_2_3_SingleEnded
01319 
01320 #if AIN_2_3_DifferentialUnipolar
01321     
01322     //----------------------------------------
01323     // ADC Channels AIN2, AIN3 = Differential Unipolar (AIN2 > AIN3)
01324     // Full Scale = VREF
01325     // Voltage per LSB count = VREF/4096
01326     // AIN2, AIN3 are a Differential pair using Unipolar transfer function.
01327     // AIN2 voltage must always be between 0 and VREF.
01328     // AIN3 voltage must always be between 0 and VREF.
01329     //
01330     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01331     UNIPOLAR |=   (1 << AIN_2_3_LSB);
01332     BIPOLAR  &= ~ (1 << AIN_2_3_LSB);
01333     RANGE    &= ~ (1 << AIN_2_3_LSB);
01334     // UCH2/3=1, BCH2/3=0, RANGE2/3=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01335 #endif // AIN_2_3_DifferentialUnipolar
01336 
01337 #if AIN_2_3_DifferentialBipolarFSVref
01338     
01339     //----------------------------------------
01340     // ADC Channels AIN2, AIN3 = Differential Bipolar
01341     // Full Scale = VREF
01342     // Voltage per LSB count = VREF/4096
01343     // AIN2, AIN3 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01344     // AIN2 voltage must always be between 0 and VREF.
01345     // AIN3 voltage must always be between 0 and VREF.
01346     //
01347     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01348     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01349     UNIPOLAR &= ~ (1 << AIN_2_3_LSB);
01350     BIPOLAR  |=   (1 << AIN_2_3_LSB);
01351     RANGE    &= ~ (1 << AIN_2_3_LSB);
01352     // UCH2/3=0, BCH2/3=1, RANGE2/3=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01353 #endif // AIN_2_3_DifferentialBipolarFSVref
01354 
01355 #if AIN_2_3_DifferentialBipolarFS2Vref
01356     
01357     //----------------------------------------
01358     // ADC Channels AIN2, AIN3 = Differential Bipolar
01359     // Full Scale = 2 * VREF
01360     // Voltage per LSB count = VREF/2048
01361     // AIN2, AIN3 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01362     // AIN2 voltage must always be between 0 and VREF.
01363     // AIN3 voltage must always be between 0 and VREF.
01364     //
01365     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01366     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01367     UNIPOLAR &= ~ (1 << AIN_2_3_LSB);
01368     BIPOLAR  |=   (1 << AIN_2_3_LSB);
01369     RANGE    |=   (1 << AIN_2_3_LSB);
01370     // UCH2/3=0, BCH2/3=1, RANGE2/3=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01371 #endif // AIN_2_3_DifferentialBipolarFS2Vref
01372 
01373 #if AIN_4_5_SingleEnded
01374     
01375     //----------------------------------------
01376     // ADC Channels AIN4, AIN5 = Both Single-Ended, Unipolar
01377     // Full Scale = VREF
01378     // Voltage per LSB count = VREF/4096
01379     // AIN4 is a Single-Ended input using Unipolar transfer function.
01380     // AIN5 is a Single-Ended input using Unipolar transfer function.
01381     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01382     // AIN4 voltage must always be between 0 and VREF.
01383     // AIN5 voltage must always be between 0 and VREF.
01384     //
01385     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01386     UNIPOLAR &= ~ (1 << AIN_4_5_LSB);
01387     BIPOLAR  &= ~ (1 << AIN_4_5_LSB);
01388     RANGE    &= ~ (1 << AIN_4_5_LSB);
01389     // UCH4/5=0, BCH4/5=0, RANGE4/5=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01390 #endif // AIN_4_5_SingleEnded
01391 
01392 #if AIN_4_5_DifferentialUnipolar
01393     
01394     //----------------------------------------
01395     // ADC Channels AIN4, AIN5 = Differential Unipolar (AIN4 > AIN5)
01396     // Full Scale = VREF
01397     // Voltage per LSB count = VREF/4096
01398     // AIN4, AIN5 are a Differential pair using Unipolar transfer function.
01399     // AIN4 voltage must always be between 0 and VREF.
01400     // AIN5 voltage must always be between 0 and VREF.
01401     //
01402     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01403     UNIPOLAR |=   (1 << AIN_4_5_LSB);
01404     BIPOLAR  &= ~ (1 << AIN_4_5_LSB);
01405     RANGE    &= ~ (1 << AIN_4_5_LSB);
01406     // UCH4/5=1, BCH4/5=0, RANGE4/5=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01407 #endif // AIN_4_5_DifferentialUnipolar
01408 
01409 #if AIN_4_5_DifferentialBipolarFSVref
01410     
01411     //----------------------------------------
01412     // ADC Channels AIN4, AIN5 = Differential Bipolar
01413     // Full Scale = VREF
01414     // Voltage per LSB count = VREF/4096
01415     // AIN4, AIN5 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01416     // AIN4 voltage must always be between 0 and VREF.
01417     // AIN5 voltage must always be between 0 and VREF.
01418     //
01419     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01420     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01421     UNIPOLAR &= ~ (1 << AIN_4_5_LSB);
01422     BIPOLAR  |=   (1 << AIN_4_5_LSB);
01423     RANGE    &= ~ (1 << AIN_4_5_LSB);
01424     // UCH4/5=0, BCH4/5=1, RANGE4/5=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01425 #endif // AIN_4_5_DifferentialBipolarFSVref
01426 
01427 #if AIN_4_5_DifferentialBipolarFS2Vref
01428     
01429     //----------------------------------------
01430     // ADC Channels AIN4, AIN5 = Differential Bipolar
01431     // Full Scale = 2 * VREF
01432     // Voltage per LSB count = VREF/2048
01433     // AIN4, AIN5 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01434     // AIN4 voltage must always be between 0 and VREF.
01435     // AIN5 voltage must always be between 0 and VREF.
01436     //
01437     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01438     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01439     UNIPOLAR &= ~ (1 << AIN_4_5_LSB);
01440     BIPOLAR  |=   (1 << AIN_4_5_LSB);
01441     RANGE    |=   (1 << AIN_4_5_LSB);
01442     // UCH4/5=0, BCH4/5=1, RANGE4/5=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01443 #endif // AIN_4_5_DifferentialBipolarFS2Vref
01444 
01445 #if AIN_6_7_SingleEnded
01446     
01447     //----------------------------------------
01448     // ADC Channels AIN6, AIN7 = Both Single-Ended, Unipolar
01449     // Full Scale = VREF
01450     // Voltage per LSB count = VREF/4096
01451     // AIN6 is a Single-Ended input using Unipolar transfer function.
01452     // AIN7 is a Single-Ended input using Unipolar transfer function.
01453     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01454     // AIN6 voltage must always be between 0 and VREF.
01455     // AIN7 voltage must always be between 0 and VREF.
01456     //
01457     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01458     UNIPOLAR &= ~ (1 << AIN_6_7_LSB);
01459     BIPOLAR  &= ~ (1 << AIN_6_7_LSB);
01460     RANGE    &= ~ (1 << AIN_6_7_LSB);
01461     // UCH6/7=0, BCH6/7=0, RANGE6/7=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01462 #endif // AIN_6_7_SingleEnded
01463 
01464 #if AIN_6_7_DifferentialUnipolar
01465     
01466     //----------------------------------------
01467     // ADC Channels AIN6, AIN7 = Differential Unipolar (AIN6 > AIN7)
01468     // Full Scale = VREF
01469     // Voltage per LSB count = VREF/4096
01470     // AIN6, AIN7 are a Differential pair using Unipolar transfer function.
01471     // AIN6 voltage must always be between 0 and VREF.
01472     // AIN7 voltage must always be between 0 and VREF.
01473     //
01474     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01475     UNIPOLAR |=   (1 << AIN_6_7_LSB);
01476     BIPOLAR  &= ~ (1 << AIN_6_7_LSB);
01477     RANGE    &= ~ (1 << AIN_6_7_LSB);
01478     // UCH6/7=1, BCH6/7=0, RANGE6/7=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01479 #endif // AIN_6_7_DifferentialUnipolar
01480 
01481 #if AIN_6_7_DifferentialBipolarFSVref
01482     
01483     //----------------------------------------
01484     // ADC Channels AIN6, AIN7 = Differential Bipolar
01485     // Full Scale = VREF
01486     // Voltage per LSB count = VREF/4096
01487     // AIN6, AIN7 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01488     // AIN6 voltage must always be between 0 and VREF.
01489     // AIN7 voltage must always be between 0 and VREF.
01490     //
01491     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01492     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01493     UNIPOLAR &= ~ (1 << AIN_6_7_LSB);
01494     BIPOLAR  |=   (1 << AIN_6_7_LSB);
01495     RANGE    &= ~ (1 << AIN_6_7_LSB);
01496     // UCH6/7=0, BCH6/7=1, RANGE6/7=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01497 #endif // AIN_6_7_DifferentialBipolarFSVref
01498 
01499 #if AIN_6_7_DifferentialBipolarFS2Vref
01500     
01501     //----------------------------------------
01502     // ADC Channels AIN6, AIN7 = Differential Bipolar
01503     // Full Scale = 2 * VREF
01504     // Voltage per LSB count = VREF/2048
01505     // AIN6, AIN7 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01506     // AIN6 voltage must always be between 0 and VREF.
01507     // AIN7 voltage must always be between 0 and VREF.
01508     //
01509     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01510     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01511     UNIPOLAR &= ~ (1 << AIN_6_7_LSB);
01512     BIPOLAR  |=   (1 << AIN_6_7_LSB);
01513     RANGE    |=   (1 << AIN_6_7_LSB);
01514     // UCH6/7=0, BCH6/7=1, RANGE6/7=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01515 #endif // AIN_6_7_DifferentialBipolarFS2Vref
01516 
01517 #if AIN_8_9_SingleEnded
01518     
01519     //----------------------------------------
01520     // ADC Channels AIN8, AIN9 = Both Single-Ended, Unipolar
01521     // Full Scale = VREF
01522     // Voltage per LSB count = VREF/4096
01523     // AIN8 is a Single-Ended input using Unipolar transfer function.
01524     // AIN9 is a Single-Ended input using Unipolar transfer function.
01525     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01526     // AIN8 voltage must always be between 0 and VREF.
01527     // AIN9 voltage must always be between 0 and VREF.
01528     //
01529     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01530     UNIPOLAR &= ~ (1 << AIN_8_9_LSB);
01531     BIPOLAR  &= ~ (1 << AIN_8_9_LSB);
01532     RANGE    &= ~ (1 << AIN_8_9_LSB);
01533     // UCH8/9=0, BCH8/9=0, RANGE8/9=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01534 #endif // AIN_8_9_SingleEnded
01535 
01536 #if AIN_8_9_DifferentialUnipolar
01537     
01538     //----------------------------------------
01539     // ADC Channels AIN8, AIN9 = Differential Unipolar (AIN8 > AIN9)
01540     // Full Scale = VREF
01541     // Voltage per LSB count = VREF/4096
01542     // AIN8, AIN9 are a Differential pair using Unipolar transfer function.
01543     // AIN8 voltage must always be between 0 and VREF.
01544     // AIN9 voltage must always be between 0 and VREF.
01545     //
01546     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01547     UNIPOLAR |=   (1 << AIN_8_9_LSB);
01548     BIPOLAR  &= ~ (1 << AIN_8_9_LSB);
01549     RANGE    &= ~ (1 << AIN_8_9_LSB);
01550     // UCH8/9=1, BCH8/9=0, RANGE8/9=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01551 #endif // AIN_8_9_DifferentialUnipolar
01552 
01553 #if AIN_8_9_DifferentialBipolarFSVref
01554     
01555     //----------------------------------------
01556     // ADC Channels AIN8, AIN9 = Differential Bipolar
01557     // Full Scale = VREF
01558     // Voltage per LSB count = VREF/4096
01559     // AIN8, AIN9 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01560     // AIN8 voltage must always be between 0 and VREF.
01561     // AIN9 voltage must always be between 0 and VREF.
01562     //
01563     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01564     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01565     UNIPOLAR &= ~ (1 << AIN_8_9_LSB);
01566     BIPOLAR  |=   (1 << AIN_8_9_LSB);
01567     RANGE    &= ~ (1 << AIN_8_9_LSB);
01568     // UCH8/9=0, BCH8/9=1, RANGE8/9=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01569 #endif // AIN_8_9_DifferentialBipolarFSVref
01570 
01571 #if AIN_8_9_DifferentialBipolarFS2Vref
01572     
01573     //----------------------------------------
01574     // ADC Channels AIN8, AIN9 = Differential Bipolar
01575     // Full Scale = 2 * VREF
01576     // Voltage per LSB count = VREF/2048
01577     // AIN8, AIN9 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01578     // AIN8 voltage must always be between 0 and VREF.
01579     // AIN9 voltage must always be between 0 and VREF.
01580     //
01581     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01582     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01583     UNIPOLAR &= ~ (1 << AIN_8_9_LSB);
01584     BIPOLAR  |=   (1 << AIN_8_9_LSB);
01585     RANGE    |=   (1 << AIN_8_9_LSB);
01586     // UCH8/9=0, BCH8/9=1, RANGE8/9=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01587 #endif // AIN_8_9_DifferentialBipolarFS2Vref
01588 
01589 #if AIN_10_11_SingleEnded
01590     
01591     //----------------------------------------
01592     // ADC Channels AIN10, AIN11 = Both Single-Ended, Unipolar
01593     // Full Scale = VREF
01594     // Voltage per LSB count = VREF/4096
01595     // AIN10 is a Single-Ended input using Unipolar transfer function.
01596     // AIN11 is a Single-Ended input using Unipolar transfer function.
01597     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01598     // AIN10 voltage must always be between 0 and VREF.
01599     // AIN11 voltage must always be between 0 and VREF.
01600     //
01601     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01602     UNIPOLAR &= ~ (1 << AIN_10_11_LSB);
01603     BIPOLAR  &= ~ (1 << AIN_10_11_LSB);
01604     RANGE    &= ~ (1 << AIN_10_11_LSB);
01605     // UCH10/11=0, BCH10/11=0, RANGE10/11=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01606 #endif // AIN_10_11_SingleEnded
01607 
01608 #if AIN_10_11_DifferentialUnipolar
01609     
01610     //----------------------------------------
01611     // ADC Channels AIN10, AIN11 = Differential Unipolar (AIN10 > AIN11)
01612     // Full Scale = VREF
01613     // Voltage per LSB count = VREF/4096
01614     // AIN10, AIN11 are a Differential pair using Unipolar transfer function.
01615     // AIN10 voltage must always be between 0 and VREF.
01616     // AIN11 voltage must always be between 0 and VREF.
01617     //
01618     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01619     UNIPOLAR |=   (1 << AIN_10_11_LSB);
01620     BIPOLAR  &= ~ (1 << AIN_10_11_LSB);
01621     RANGE    &= ~ (1 << AIN_10_11_LSB);
01622     // UCH10/11=1, BCH10/11=0, RANGE10/11=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01623 #endif // AIN_10_11_DifferentialUnipolar
01624 
01625 #if AIN_10_11_DifferentialBipolarFSVref
01626     
01627     //----------------------------------------
01628     // ADC Channels AIN10, AIN11 = Differential Bipolar
01629     // Full Scale = VREF
01630     // Voltage per LSB count = VREF/4096
01631     // AIN10, AIN11 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01632     // AIN10 voltage must always be between 0 and VREF.
01633     // AIN11 voltage must always be between 0 and VREF.
01634     //
01635     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01636     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01637     UNIPOLAR &= ~ (1 << AIN_10_11_LSB);
01638     BIPOLAR  |=   (1 << AIN_10_11_LSB);
01639     RANGE    &= ~ (1 << AIN_10_11_LSB);
01640     // UCH10/11=0, BCH10/11=1, RANGE10/11=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01641 #endif // AIN_10_11_DifferentialBipolarFSVref
01642 
01643 #if AIN_10_11_DifferentialBipolarFS2Vref
01644     
01645     //----------------------------------------
01646     // ADC Channels AIN10, AIN11 = Differential Bipolar
01647     // Full Scale = 2 * VREF
01648     // Voltage per LSB count = VREF/2048
01649     // AIN10, AIN11 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01650     // AIN10 voltage must always be between 0 and VREF.
01651     // AIN11 voltage must always be between 0 and VREF.
01652     //
01653     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01654     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01655     UNIPOLAR &= ~ (1 << AIN_10_11_LSB);
01656     BIPOLAR  |=   (1 << AIN_10_11_LSB);
01657     RANGE    |=   (1 << AIN_10_11_LSB);
01658     // UCH10/11=0, BCH10/11=1, RANGE10/11=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01659 #endif // AIN_10_11_DifferentialBipolarFS2Vref
01660 
01661 #if AIN_12_13_SingleEnded
01662     
01663     //----------------------------------------
01664     // ADC Channels AIN12, AIN13 = Both Single-Ended, Unipolar
01665     // Full Scale = VREF
01666     // Voltage per LSB count = VREF/4096
01667     // AIN12 is a Single-Ended input using Unipolar transfer function.
01668     // AIN13 is a Single-Ended input using Unipolar transfer function.
01669     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01670     // AIN12 voltage must always be between 0 and VREF.
01671     // AIN13 voltage must always be between 0 and VREF.
01672     //
01673     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01674     UNIPOLAR &= ~ (1 << AIN_12_13_LSB);
01675     BIPOLAR  &= ~ (1 << AIN_12_13_LSB);
01676     RANGE    &= ~ (1 << AIN_12_13_LSB);
01677     // UCH12/13=0, BCH12/13=0, RANGE12/13=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01678 #endif // AIN_12_13_SingleEnded
01679 
01680 #if AIN_12_13_DifferentialUnipolar
01681     
01682     //----------------------------------------
01683     // ADC Channels AIN12, AIN13 = Differential Unipolar (AIN12 > AIN13)
01684     // Full Scale = VREF
01685     // Voltage per LSB count = VREF/4096
01686     // AIN12, AIN13 are a Differential pair using Unipolar transfer function.
01687     // AIN12 voltage must always be between 0 and VREF.
01688     // AIN13 voltage must always be between 0 and VREF.
01689     //
01690     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01691     UNIPOLAR |=   (1 << AIN_12_13_LSB);
01692     BIPOLAR  &= ~ (1 << AIN_12_13_LSB);
01693     RANGE    &= ~ (1 << AIN_12_13_LSB);
01694     // UCH12/13=1, BCH12/13=0, RANGE12/13=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01695 #endif // AIN_12_13_DifferentialUnipolar
01696 
01697 #if AIN_12_13_DifferentialBipolarFSVref
01698     
01699     //----------------------------------------
01700     // ADC Channels AIN12, AIN13 = Differential Bipolar
01701     // Full Scale = VREF
01702     // Voltage per LSB count = VREF/4096
01703     // AIN12, AIN13 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01704     // AIN12 voltage must always be between 0 and VREF.
01705     // AIN13 voltage must always be between 0 and VREF.
01706     //
01707     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01708     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01709     UNIPOLAR &= ~ (1 << AIN_12_13_LSB);
01710     BIPOLAR  |=   (1 << AIN_12_13_LSB);
01711     RANGE    &= ~ (1 << AIN_12_13_LSB);
01712     // UCH12/13=0, BCH12/13=1, RANGE12/13=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01713 #endif // AIN_12_13_DifferentialBipolarFSVref
01714 
01715 #if AIN_12_13_DifferentialBipolarFS2Vref
01716     
01717     //----------------------------------------
01718     // ADC Channels AIN12, AIN13 = Differential Bipolar
01719     // Full Scale = 2 * VREF
01720     // Voltage per LSB count = VREF/2048
01721     // AIN12, AIN13 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01722     // AIN12 voltage must always be between 0 and VREF.
01723     // AIN13 voltage must always be between 0 and VREF.
01724     //
01725     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01726     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01727     UNIPOLAR &= ~ (1 << AIN_12_13_LSB);
01728     BIPOLAR  |=   (1 << AIN_12_13_LSB);
01729     RANGE    |=   (1 << AIN_12_13_LSB);
01730     // UCH12/13=0, BCH12/13=1, RANGE12/13=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01731 #endif // AIN_12_13_DifferentialBipolarFS2Vref
01732 
01733 #if AIN_14_15_SingleEnded
01734     
01735     //----------------------------------------
01736     // ADC Channels AIN14, AIN15 = Both Single-Ended, Unipolar
01737     // Full Scale = VREF
01738     // Voltage per LSB count = VREF/4096
01739     // AIN14 is a Single-Ended input using Unipolar transfer function.
01740     // AIN15 is a Single-Ended input using Unipolar transfer function.
01741     // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01742     // AIN14 voltage must always be between 0 and VREF.
01743     // AIN15 voltage must always be between 0 and VREF.
01744     //
01745     // SELECT UNIPOLAR AND BIPOLAR register set PER CHANNEL UCH(X)/(X+1) AND BCH(X)/(X+1) TO 0 FOR SINGLE-ENDED SELECTION
01746     UNIPOLAR &= ~ (1 << AIN_14_15_LSB);
01747     BIPOLAR  &= ~ (1 << AIN_14_15_LSB);
01748     RANGE    &= ~ (1 << AIN_14_15_LSB);
01749     // UCH14/15=0, BCH14/15=0, RANGE14/15=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
01750 #endif // AIN_14_15_SingleEnded
01751 
01752 #if AIN_14_15_DifferentialUnipolar
01753     
01754     //----------------------------------------
01755     // ADC Channels AIN14, AIN15 = Differential Unipolar (AIN14 > AIN15)
01756     // Full Scale = VREF
01757     // Voltage per LSB count = VREF/4096
01758     // AIN14, AIN15 are a Differential pair using Unipolar transfer function.
01759     // AIN14 voltage must always be between 0 and VREF.
01760     // AIN15 voltage must always be between 0 and VREF.
01761     //
01762     // SELECT UNIPOLAR register set PER CHANNEL UCH(X)/(X+1) TO 1 FOR UNIPOLAR
01763     UNIPOLAR |=   (1 << AIN_14_15_LSB);
01764     BIPOLAR  &= ~ (1 << AIN_14_15_LSB);
01765     RANGE    &= ~ (1 << AIN_14_15_LSB);
01766     // UCH14/15=1, BCH14/15=0, RANGE14/15=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01767 #endif // AIN_14_15_DifferentialUnipolar
01768 
01769 #if AIN_14_15_DifferentialBipolarFSVref
01770     
01771     //----------------------------------------
01772     // ADC Channels AIN14, AIN15 = Differential Bipolar
01773     // Full Scale = VREF
01774     // Voltage per LSB count = VREF/4096
01775     // AIN14, AIN15 are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01776     // AIN14 voltage must always be between 0 and VREF.
01777     // AIN15 voltage must always be between 0 and VREF.
01778     //
01779     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01780     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 0 +/-VREF+/2
01781     UNIPOLAR &= ~ (1 << AIN_14_15_LSB);
01782     BIPOLAR  |=   (1 << AIN_14_15_LSB);
01783     RANGE    &= ~ (1 << AIN_14_15_LSB);
01784     // UCH14/15=0, BCH14/15=1, RANGE14/15=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
01785 #endif // AIN_14_15_DifferentialBipolarFSVref
01786 
01787 #if AIN_14_15_DifferentialBipolarFS2Vref
01788     
01789     //----------------------------------------
01790     // ADC Channels AIN14, AIN15 = Differential Bipolar
01791     // Full Scale = 2 * VREF
01792     // Voltage per LSB count = VREF/2048
01793     // AIN14, AIN15 are a Differential pair using Bipolar transfer function with range (+/-)Vref
01794     // AIN14 voltage must always be between 0 and VREF.
01795     // AIN15 voltage must always be between 0 and VREF.
01796     //
01797     // SELECT BIPOLAR register set PER CHANNEL BCH(X)/(X+1) TO 1 FOR BIPOLAR FULLY DIFFERENTIAL
01798     // SELECT RANGE register set PER CHANNEL PAIR RANGE(X)/(X+1) TO 1 +/-VREF+
01799     UNIPOLAR &= ~ (1 << AIN_14_15_LSB);
01800     BIPOLAR  |=   (1 << AIN_14_15_LSB);
01801     RANGE    |=   (1 << AIN_14_15_LSB);
01802     // UCH14/15=0, BCH14/15=1, RANGE14/15=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01803 #endif // AIN_14_15_DifferentialBipolarFS2Vref
01804     
01805     //----------------------------------------
01806     // SPI write ADC CONFIGURATION register
01807     // Send SPI configuration to device
01808     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01809     SPIoutputCS(0); // drive CS low
01810     SPIwrite16bits(ADC_CONFIGURATION);
01811     SPIoutputCS(1); // drive CS high
01812     
01813     //----------------------------------------
01814     // SPI write UNIPOLAR BIPOLAR RANGE registers
01815     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01816     SPIoutputCS(0); // drive CS low
01817     SPIwrite16bits(UNIPOLAR);
01818     SPIoutputCS(1); // drive CS high
01819     SPIoutputCS(0); // drive CS low
01820     SPIwrite16bits(BIPOLAR);
01821     SPIoutputCS(1); // drive CS high
01822     SPIoutputCS(0); // drive CS low
01823     SPIwrite16bits(RANGE);
01824     SPIoutputCS(1); // drive CS high
01825     
01826     //----------------------------------------
01827     // SPI write CSCAN0 CSCAN1 registers
01828     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01829     SPIoutputCS(0); // drive CS low
01830     SPIwrite16bits(CSCAN0);
01831     SPIoutputCS(1); // drive CS high
01832     SPIoutputCS(0); // drive CS low
01833     SPIwrite16bits(CSCAN1);
01834     SPIoutputCS(1); // drive CS high
01835 }
01836 
01837 //----------------------------------------
01838 // Menu item 'IS'
01839 // ADC Channels AIN(channelId), AIN(channelId+1) = Both Single-Ended, Unipolar
01840 // Full Scale = VREF
01841 // Voltage per LSB count = VREF/4096
01842 // AIN(channelId) is a Single-Ended input using Unipolar transfer function.
01843 // AIN(channelId+1) is a Single-Ended input using Unipolar transfer function.
01844 // If PDIFF_COM_1, both are Pseudo-Differential with REF- as common.
01845 // AIN(channelId) voltage must always be between 0 and VREF.
01846 // AIN(channelId+1) voltage must always be between 0 and VREF.
01847 //
01848 void MAX11131::Reconfigure_SingleEnded(int channel_0_15)
01849 {
01850     
01851     //----------------------------------------
01852     // UCH(ch)/(ch+1)=0, BCH(ch)/(ch+1)=0, RANGE(ch)/(ch+1)=0:
01853     // AIN(ch)/AIN(ch+1) two independent single-ended inputs,
01854     // unipolar code (Full Scale = VREF, LSB = VREF/4096)
01855     // 
01856     const int channelPairIndex = channel_0_15 / 2;
01857     const int bitmask = (1 << (10 - channelPairIndex));
01858     UNIPOLAR &= ~ bitmask;
01859     BIPOLAR  &= ~ bitmask;
01860     RANGE    &= ~ bitmask;
01861     
01862     //----------------------------------------
01863     // SPI write UNIPOLAR BIPOLAR RANGE registers
01864     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01865     SPIoutputCS(0); // drive CS low
01866     SPIwrite16bits(UNIPOLAR);
01867     SPIoutputCS(1); // drive CS high
01868     SPIoutputCS(0); // drive CS low
01869     SPIwrite16bits(BIPOLAR);
01870     SPIoutputCS(1); // drive CS high
01871     SPIoutputCS(0); // drive CS low
01872     SPIwrite16bits(RANGE);
01873     SPIoutputCS(1); // drive CS high
01874 }
01875 
01876 //----------------------------------------
01877 // Menu item 'IU'
01878 // ADC Channels AIN(channelId), AIN(channelId+1) = Differential Unipolar (AIN(channelId) > AIN(channelId+1))
01879 // Full Scale = VREF
01880 // Voltage per LSB count = VREF/4096
01881 // AIN(channelId), AIN(channelId+1) are a Differential pair using Unipolar transfer function.
01882 // AIN(channelId) voltage must always be between 0 and VREF.
01883 // AIN(channelId+1) voltage must always be between 0 and VREF.
01884 //
01885 void MAX11131::Reconfigure_DifferentialUnipolar(int channel_0_15)
01886 {
01887     
01888     //----------------------------------------
01889     // UCH(ch)/(ch+1)=1, BCH(ch)/(ch+1)=0, RANGE(ch)/(ch+1)=0:
01890     // AIN(ch)/AIN(ch+1) differential input pair,
01891     // unipolar code (AIN(ch)>AIN(ch+1)) (Full Scale = VREF, LSB = VREF/4096)
01892     // 
01893     const int channelPairIndex = channel_0_15 / 2;
01894     const int bitmask = (1 << (10 - channelPairIndex));
01895     UNIPOLAR |=   bitmask;
01896     BIPOLAR  &= ~ bitmask;
01897     RANGE    &= ~ bitmask;
01898     // UCH0/1=1, BCH0/1=0, RANGE0/1=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
01899     
01900     //----------------------------------------
01901     // SPI write UNIPOLAR BIPOLAR RANGE registers
01902     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01903     SPIoutputCS(0); // drive CS low
01904     SPIwrite16bits(UNIPOLAR);
01905     SPIoutputCS(1); // drive CS high
01906     SPIoutputCS(0); // drive CS low
01907     SPIwrite16bits(BIPOLAR);
01908     SPIoutputCS(1); // drive CS high
01909     SPIoutputCS(0); // drive CS low
01910     SPIwrite16bits(RANGE);
01911     SPIoutputCS(1); // drive CS high
01912 }
01913 
01914 //----------------------------------------
01915 // Menu item 'IB'
01916 // ADC Channels AIN(channelId), AIN(channelId+1) = Differential Bipolar
01917 // Full Scale = VREF
01918 // Voltage per LSB count = VREF/4096
01919 // AIN(channelId), AIN(channelId+1) are a Differential pair using Bipolar transfer function with range (+/-)(1/2)Vref
01920 // AIN(channelId) voltage must always be between 0 and VREF.
01921 // AIN(channelId+1) voltage must always be between 0 and VREF.
01922 //
01923 void MAX11131::Reconfigure_DifferentialBipolarFSVref(int channel_0_15)
01924 {
01925     
01926     //----------------------------------------
01927     // UCH(ch)/(ch+1)=0, BCH(ch)/(ch+1)=1, RANGE(ch)/(ch+1)=0:
01928     // AIN(ch)/AIN(ch+1) differential input pair (+/-)(1/2)Vref,
01929     // bipolar code (Full Scale = VREF, LSB = VREF/4096)
01930     // 
01931     const int channelPairIndex = channel_0_15 / 2;
01932     const int bitmask = (1 << (10 - channelPairIndex));
01933     UNIPOLAR &= ~ bitmask;
01934     BIPOLAR  |=   bitmask;
01935     RANGE    &= ~ bitmask;
01936     
01937     //----------------------------------------
01938     // SPI write UNIPOLAR BIPOLAR RANGE registers
01939     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01940     SPIoutputCS(0); // drive CS low
01941     SPIwrite16bits(UNIPOLAR);
01942     SPIoutputCS(1); // drive CS high
01943     SPIoutputCS(0); // drive CS low
01944     SPIwrite16bits(BIPOLAR);
01945     SPIoutputCS(1); // drive CS high
01946     SPIoutputCS(0); // drive CS low
01947     SPIwrite16bits(RANGE);
01948     SPIoutputCS(1); // drive CS high
01949 }
01950 
01951 //----------------------------------------
01952 // Menu item 'IR'
01953 // ADC Channels AIN(channelId), AIN(channelId+1) = Differential Bipolar
01954 // Full Scale = 2 * VREF
01955 // Voltage per LSB count = VREF/2048
01956 // AIN(channelId), AIN(channelId+1) are a Differential pair using Bipolar transfer function with range (+/-)Vref
01957 // AIN(channelId) voltage must always be between 0 and VREF.
01958 // AIN(channelId+1) voltage must always be between 0 and VREF.
01959 //
01960 void MAX11131::Reconfigure_DifferentialBipolarFS2Vref(int channel_0_15)
01961 {
01962     
01963     //----------------------------------------
01964     // UCH(ch)/(ch+1)=0, BCH(ch)/(ch+1)=1, RANGE(ch)/(ch+1)=1:
01965     // AIN(ch)/AIN(ch+1) differential input pair (+/-)Vref,
01966     // bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01967     // 
01968     const int channelPairIndex = channel_0_15 / 2;
01969     const int bitmask = (1 << (10 - channelPairIndex));
01970     UNIPOLAR &= ~ bitmask;
01971     BIPOLAR  |=   bitmask;
01972     RANGE    |=   bitmask;
01973     // UCH0/1=0, BCH0/1=1, RANGE0/1=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
01974     
01975     //----------------------------------------
01976     // SPI write UNIPOLAR BIPOLAR RANGE registers
01977     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
01978     SPIoutputCS(0); // drive CS low
01979     SPIwrite16bits(UNIPOLAR);
01980     SPIoutputCS(1); // drive CS high
01981     SPIoutputCS(0); // drive CS low
01982     SPIwrite16bits(BIPOLAR);
01983     SPIoutputCS(1); // drive CS high
01984     SPIoutputCS(0); // drive CS low
01985     SPIwrite16bits(RANGE);
01986     SPIoutputCS(1); // drive CS high
01987 }
01988 
01989 //----------------------------------------
01990 // SCAN_0000_NOP
01991 //
01992 // Shift 16 bits out of ADC, without changing configuration.
01993 // Note: @return data format depends on CHAN_ID bit:
01994 //     "CH[3:0] DATA[11:0]" when CHAN_ID = 1, or
01995 //     "0 DATA[11:0] x x x" when CHAN_ID = 0.
01996 int16_t MAX11131::ScanRead(void)
01997 {
01998     
01999     //----------------------------------------
02000     // Read SPI data from device while MOSI (Maxim DIN) is 0. Effectively ADC_MODE_CONTROL SCAN[3:0] = SCAN_0000_NOP = 0
02001     SPI_MOSI_Semantic = 0; // 0:Nothing 1:regWrite 2:sampleSetPattern
02002     SPIoutputCS(0); // drive CS low
02003     int16_t misoData16 = SPIread16bits();
02004     SPIoutputCS(1); // drive CS high
02005     // For external clock modes, the data format returned depends on the CHAN_ID bit.
02006     //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02007     //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02008     // For internal clock modes, the data format always includes the channel address.
02009     //     misoData16 = CH[3:0] DATA[11:0]
02010     return misoData16;
02011 }
02012 
02013 //----------------------------------------
02014 // SCAN_0000_NOP
02015 //
02016 // Read raw ADC codes from device into AINcode[] and RAW_misoData16[].
02017 // If internal clock mode with SWCNV=0, measurements will be triggered using CNVST pin.
02018 //
02019 // @pre one of the Scan functions was called, setting NumWords
02020 // @param[in] NumWords: number of words to be read from the FIFO
02021 // @post RAW_misoData16[index] contains the raw SPI Master-In,Slave-Out data
02022 // @post AINcode[NUM_CHANNELS] contains the latest readings in LSBs
02023 //
02024 void MAX11131::ReadAINcode(void)
02025 {
02026     
02027     //----------------------------------------
02028     // loop index for RAW_misoData16[SAMPLESET_MAX_ENTRIES];
02029     int index;
02030     
02031     //----------------------------------------
02032     // If internal clock mode with SWCNV=0, trigger measurement using CNVST pin and wait for EOC pin.
02033       if (isExternalClock == 0)
02034       {
02035         if (swcnv_0_1 == 0)
02036         {
02037           // SWCNV=0: trigger measurement by driving CNVST/AIN14 pin low
02038           // for a minimum active-low pulse duration of 5ns. (AIN14 is not available)
02039           // One CNVST pulse scans all requested channels and stores the results in the FIFO.
02040           CNVSToutputPulseLow();
02041         }
02042         // wait for EOC low (internal clock mode end of conversion)
02043         EOCinputWaitUntilLow();
02044       }
02045     
02046     //----------------------------------------
02047     // Read raw ADC codes from device into AINcode[] and RAW_misoData16[].
02048       // For external clock modes, the data format returned depends on the CHAN_ID bit.
02049       //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02050       //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02051       // For internal clock modes, the data format always includes the channel address.
02052       //     misoData16 = CH[3:0] DATA[11:0]
02053       switch(ScanMode)
02054       {
02055         //----------------------------------------
02056         // read data words
02057         // For internal clock modes, the data format always includes the channel address.
02058         //     misoData16 = CH[3:0] DATA[11:0]
02059       case SCAN_0000_NOP:
02060       case SCAN_0011_StandardInternalClock:
02061       case SCAN_0101_UpperInternalClock:
02062       case SCAN_0111_CustomInternalClock:
02063       default:
02064           for (index = 0; index < NumWords; index++) {
02065             RAW_misoData16[index] = ScanRead();
02066             // For internal clock modes, the data format always includes the channel address.
02067             //     misoData16 = CH[3:0] DATA[11:0]
02068             int16_t value_u12 = (RAW_misoData16[index] & 0x0FFF);
02069             int channelId = ((RAW_misoData16[index] >> 12) & 0x000F);
02070             AINcode[channelId] = value_u12;
02071           }
02072         break;
02073         //----------------------------------------
02074         // read data words
02075         // For external clock modes, the data format returned depends on the CHAN_ID bit.
02076         //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02077         //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02078         // For internal clock modes, the data format always includes the channel address.
02079         //     misoData16 = CH[3:0] DATA[11:0]
02080       case SCAN_0001_Manual:
02081       case SCAN_0100_StandardExternalClock:
02082       case SCAN_0110_UpperExternalClock:
02083       case SCAN_1000_CustomExternalClock:
02084       case SCAN_1001_SampleSetExternalClock:
02085         if (chan_id_0_1 != 0) {
02086           for (index = 0; index < NumWords; index++) {
02087             RAW_misoData16[index] = ScanRead();
02088             // For internal clock modes, the data format always includes the channel address.
02089             //     misoData16 = CH[3:0] DATA[11:0]
02090             int16_t value_u12 = (RAW_misoData16[index] & 0x0FFF);
02091             int channelId = ((RAW_misoData16[index] >> 12) & 0x000F);
02092             AINcode[channelId] = value_u12;
02093           }
02094         } else {
02095           for (index = 0; index < NumWords; index++) {
02096             RAW_misoData16[index] = ScanRead();
02097             int16_t value_u12 = ((RAW_misoData16[index] >> 3) & 0x0FFF);
02098             int channelId = channelNumber_0_15;
02099             AINcode[channelId] = value_u12;
02100           }
02101         }
02102         break;
02103         //----------------------------------------
02104         // read data words and calculate mean, stddev
02105       case SCAN_0010_Repeat:
02106         // ScanRead_nWords_chanID_mean(NumWords); // TODO1: missing function
02107         // was this function AINcode_print_value_chanID_mean(int nWords) in main?
02108         // But this function prints to standard output so can't be inside the driver.
02109         for (index = 0; index < NumWords; index++) {
02110           RAW_misoData16[index] = ScanRead();
02111         }
02112         break;
02113       }
02114 }
02115 
02116 //----------------------------------------
02117 // Sign-Extend a right-aligned MAX11131 code into a signed 2's complement value.
02118 // Supports the bipolar transfer functions.
02119 // @param[in] value_u12: raw 12-bit MAX11131 code (right justified).
02120 // @return sign-extended 2's complement value.
02121 //
02122 int32_t MAX11131::TwosComplementValue(uint32_t regValue)
02123 {
02124     const uint16_t SIGN_BIT_12BIT = 0x0800;
02125     const uint16_t FULL_SCALE_CODE_12BIT = 0x0fff;
02126     if (((regValue & SIGN_BIT_12BIT) != 0) && !((regValue & (SIGN_BIT_12BIT << 1)) != 0))
02127     {
02128         // (bSignBitNegative && !bExtendedSignBitNegative)
02129         // Twos_Complement negative value
02130         int32_t Offset_regValue = (int32_t)(regValue - (FULL_SCALE_CODE_12BIT + 1));
02131         return Offset_regValue;
02132     }
02133     // Twos_Complement positive value or zero
02134     return (int32_t)regValue;
02135 }
02136 
02137 //----------------------------------------
02138 // Return the physical voltage corresponding to MAX11131 code.
02139 // Does not perform any offset or gain correction.
02140 // @pre VRef = Voltage of REF input, in Volts
02141 // @param[in] value_u12: raw 12-bit MAX11131 code (right justified).
02142 // @param[in] channelId: AIN channel number.
02143 // @return physical voltage corresponding to MAX11131 code.
02144 //
02145 double MAX11131::VoltageOfCode(int16_t value_u12, int channelId)
02146 {
02147     int channelPairIndex = channelId / 2;
02148     // format: 1 0 0 0 1 UCH0/1 UCH2/3 UCH4/5 UCH6/7 UCH8/9 UCH10/11 UCH12/13 UCH14/15 PDIFF_COM x x
02149     int UCHn = (UNIPOLAR >> (10 - channelPairIndex)) & 0x01;
02150     int BCHn = (BIPOLAR >> (10 - channelPairIndex)) & 0x01;
02151     int RANGEn = (RANGE >> (10 - channelPairIndex)) & 0x01;
02152     if (UCHn)
02153     {
02154         // UCH0/1=1, BCH0/1=0, RANGE0/1=0: AIN0/AIN1 differential input pair, unipolar code (AIN0>AIN1) (Full Scale = VREF, LSB = VREF/4096)
02155         return (value_u12 * VRef / 4096);
02156     }
02157     else
02158     {
02159         if (BCHn)
02160         {
02161             if (RANGEn)
02162             {
02163                 // UCH0/1=0, BCH0/1=1, RANGE0/1=1: AIN0/AIN1 differential input pair (+/-)Vref, bipolar code (Full Scale = 2VREF, LSB = VREF/2048)
02164                 return (TwosComplementValue(value_u12) * VRef / 2048);
02165             }
02166             else
02167             {
02168                 // UCH0/1=0, BCH0/1=1, RANGE0/1=0: AIN0/AIN1 differential input pair (+/-)(1/2)Vref, bipolar code (Full Scale = VREF, LSB = VREF/4096)
02169                 return (TwosComplementValue(value_u12) * VRef / 4096);
02170             }
02171         }
02172         else
02173         {
02174             // UCH0/1=0, BCH0/1=0, RANGE0/1=0: AIN0/AIN1 two independent single-ended inputs, unipolar code (Full Scale = VREF, LSB = VREF/4096)
02175             return (value_u12 * VRef / 4096);
02176         }
02177     }
02178 }
02179 
02180 //----------------------------------------
02181 // SCAN_0001_Manual
02182 //
02183 // Measure ADC channel channelNumber_0_15 once.
02184 // External clock mode.
02185 // @param[in] channelNumber_0_15: AIN Channel Number
02186 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
02187 // @param[in] chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
02188 // @return number of ScanRead() words needed to retrieve the data.
02189 // @post NumWords = number of words to be read from the FIFO
02190 // For external clock modes, the data format depends on CHAN_ID.
02191 //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02192 //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02193 //
02194 int MAX11131::ScanManual(void)
02195 {
02196     
02197     //----------------------------------------
02198     // define write-only register ADC_MODE_CONTROL
02199     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
02200     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
02201     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
02202     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02203     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
02204     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
02205     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
02206     
02207     //----------------------------------------
02208     // Apply a soft reset when changing from internal to external clock mode.
02209     int needFIFOreset = (isExternalClock != 1);
02210     if (needFIFOreset) {
02211         // Apply a soft reset when changing from internal to external clock mode.
02212         ADC_MODE_CONTROL = ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02213         // Send SPI configuration to device
02214         SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02215         SPIoutputCS(0); // drive CS low
02216         SPIwrite16bits(ADC_MODE_CONTROL);
02217         SPIoutputCS(1); // drive CS high
02218         ADC_MODE_CONTROL = 0;
02219     }
02220     
02221     //----------------------------------------
02222     // number of words to read
02223     NumWords = 1;
02224     
02225     //----------------------------------------
02226     // External Clock Mode
02227     isExternalClock = 1;
02228     
02229     //----------------------------------------
02230     // update device driver global variable
02231     ScanMode = SCAN_0001_Manual;
02232     
02233     //----------------------------------------
02234     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_0001_Manual = 1
02235     //~ const int SCAN_0001_Manual = 1; // replaced local const with enum
02236     ADC_MODE_CONTROL |=   ((SCAN_0001_Manual & SCAN_BITS) << SCAN_LSB);
02237     
02238     //----------------------------------------
02239     // ADC MODE CONTROL register set CHSEL[3:0] TO channel number
02240     ADC_MODE_CONTROL |=   ((channelNumber_0_15 & CHSEL_BITS) << CHSEL_LSB);
02241     
02242     //----------------------------------------
02243     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
02244     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
02245     
02246     //----------------------------------------
02247     // ADC MODE CONTROL REGISTER SELECT THE CHAN_ID BIT
02248     // (applicable to external clock mode only)
02249     // For external clock modes, the data format returned depends on the CHAN_ID bit.
02250     //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02251     //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02252     // For internal clock modes, the data format always includes the channel address.
02253     //     misoData16 = CH[3:0] DATA[11:0]
02254     ADC_MODE_CONTROL |=   ((chan_id_0_1 & CHAN_ID_BITS) << CHAN_ID_LSB);
02255     
02256     //----------------------------------------
02257     // SPI write ADC MODE CONTROL register
02258     // Send SPI configuration to device
02259     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02260     SPIoutputCS(0); // drive CS low
02261     SPIwrite16bits(ADC_MODE_CONTROL);
02262     SPIoutputCS(1); // drive CS high
02263     
02264     //----------------------------------------
02265     // return number of words to read
02266     return NumWords;
02267 }
02268 
02269 //----------------------------------------
02270 // SCAN_0010_Repeat
02271 //
02272 // Measure ADC channel channelNumber_0_15 repeatedly with averaging.
02273 // Internal clock mode.
02274 // @param[in] channelNumber_0_15: AIN Channel Number
02275 // @param[in] average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
02276 //     average_0_4_8_16_32=0 to disable averaging.
02277 // @param[in] nscan_4_8_12_16: Number of ScanRead() words to report.
02278 // @param[in] swcnv_0_1: ADC_MODE_CONTROL.SWCNV
02279 //     SWCNV=0: trigger measurement by driving CNVST pin low.
02280 //         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
02281 //     SWCNV=1: trigger measurement on SPI CS rising edge.
02282 //         CS must be held low for minimum of 17 SCLK cycles.
02283 //         CNVST pin is not used. (AIN14 is available)
02284 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
02285 // @return number of ScanRead() words needed to retrieve the data.
02286 // @post NumWords = number of words to be read from the FIFO
02287 // For internal clock modes, the data format always includes the channel address.
02288 //     misoData16 = CH[3:0] DATA[11:0]
02289 //
02290 int MAX11131::ScanRepeat(void)
02291 {
02292     
02293     //----------------------------------------
02294     // number of words to read
02295     NumWords = (nscan_4_8_12_16);
02296     
02297     //----------------------------------------
02298     // Internal Clock Mode
02299     isExternalClock = 0;
02300     
02301     //----------------------------------------
02302     // update device driver global variable
02303     ScanMode = SCAN_0010_Repeat;
02304     
02305     //----------------------------------------
02306     // define write-only register ADC_MODE_CONTROL
02307     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
02308     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
02309     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
02310     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02311     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
02312     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
02313     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
02314     
02315     //----------------------------------------
02316     // define write-only register ADC_CONFIGURATION
02317     ADC_CONFIGURATION = 0x8000; //!< mosiData16 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
02318     const int REFSEL_LSB = 10; const int REFSEL_BITS = 0x01; // ADC_CONFIGURATION.REFSEL
02319     const int AVGON_LSB  =  9; const int AVGON_BITS  = 0x01; // ADC_CONFIGURATION.AVGON
02320     const int NAVG_LSB   =  7; const int NAVG_BITS   = 0x03; // ADC_CONFIGURATION.NAVG[1:0]
02321     const int NSCAN_LSB  =  5; const int NSCAN_BITS  = 0x03; // ADC_CONFIGURATION.NSCAN[1:0]
02322     const int SPM_LSB    =  3; const int SPM_BITS    = 0x03; // ADC_CONFIGURATION.SPM[1:0]
02323     const int ECHO_LSB   =  2; const int ECHO_BITS   = 0x01; // ADC_CONFIGURATION.ECHO
02324     
02325     //----------------------------------------
02326     // if average, ADC CONFIGURATION register set AVG and NAVG[1:0]
02327     // (applicable to internal clock mode only)
02328     // if average, ADC CONFIGURATION register set AVG ON BIT TO 1
02329     // if average, ADC CONFIGURATION register set NAVG[1:0] TO N
02330     if (average_0_4_8_16_32 == 4) {
02331         // Enable Averaging of 4 samples (AVGON=1, NAVG[1:0]=0)
02332         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02333         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02334         ADC_CONFIGURATION |=   ((0 & NAVG_BITS) << NAVG_LSB);
02335     } else if (average_0_4_8_16_32 == 8) {
02336         // Enable Averaging of 8 samples (AVGON=1, NAVG[1:0]=1)
02337         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02338         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02339         ADC_CONFIGURATION |=   ((1 & NAVG_BITS) << NAVG_LSB);
02340     } else if (average_0_4_8_16_32 == 16) {
02341         // Enable Averaging of 16 samples (AVGON=1, NAVG[1:0]=2)
02342         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02343         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02344         ADC_CONFIGURATION |=   ((2 & NAVG_BITS) << NAVG_LSB);
02345     } else if (average_0_4_8_16_32 == 32) {
02346         // Enable Averaging of 32 samples (AVGON=1, NAVG[1:0]=3)
02347         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02348         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02349         ADC_CONFIGURATION |=   ((3 & NAVG_BITS) << NAVG_LSB);
02350     } else {
02351         // Disable Averaging (AVGON=0, NAVG[1:0]=0)
02352         ADC_CONFIGURATION &= ~ ((    AVGON_BITS) << AVGON_LSB);
02353         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02354     }
02355     
02356     //----------------------------------------
02357     // ADC CONFIGURATION register set NSCAN[1:0] for scan count
02358     // (applicable to SCAN_0010_Repeat only)
02359     if (nscan_4_8_12_16 == 4) {
02360         // Set scan count 4
02361         ADC_CONFIGURATION &= ~ ((    NSCAN_BITS) << NSCAN_LSB);
02362         ADC_CONFIGURATION |=   ((0 & NSCAN_BITS) << NSCAN_LSB);
02363     } else if (nscan_4_8_12_16 == 8) {
02364         // Set scan count 8
02365         ADC_CONFIGURATION &= ~ ((    NSCAN_BITS) << NSCAN_LSB);
02366         ADC_CONFIGURATION |=   ((1 & NSCAN_BITS) << NSCAN_LSB);
02367     } else if (nscan_4_8_12_16 == 12) {
02368         // Set scan count 12
02369         ADC_CONFIGURATION &= ~ ((    NSCAN_BITS) << NSCAN_LSB);
02370         ADC_CONFIGURATION |=   ((2 & NSCAN_BITS) << NSCAN_LSB);
02371     } else if (nscan_4_8_12_16 == 16) {
02372         // Set scan count 16
02373         ADC_CONFIGURATION &= ~ ((    NSCAN_BITS) << NSCAN_LSB);
02374         ADC_CONFIGURATION |=   ((3 & NSCAN_BITS) << NSCAN_LSB);
02375     }
02376     
02377     //----------------------------------------
02378     // SPI write ADC CONFIGURATION register
02379     // Send SPI configuration to device
02380     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02381     SPIoutputCS(0); // drive CS low
02382     SPIwrite16bits(ADC_CONFIGURATION);
02383     SPIoutputCS(1); // drive CS high
02384     
02385     //----------------------------------------
02386     // Reset FIFO: ADC_MODE_CONTROL.RESET[1:0] = 1   Apply a soft reset when changing from internal to external clock mode.
02387     ADC_MODE_CONTROL &= ~ ((    RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02388     ADC_MODE_CONTROL |=   ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02389     
02390     //----------------------------------------
02391     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_0010_Repeat = 2
02392     //~ const int SCAN_0010_Repeat = 2; // replaced local const with enum
02393     ADC_MODE_CONTROL |=   ((SCAN_0010_Repeat & SCAN_BITS) << SCAN_LSB);
02394     
02395     //----------------------------------------
02396     // ADC MODE CONTROL register set CHSEL[3:0] TO channel number
02397     ADC_MODE_CONTROL |=   ((channelNumber_0_15 & CHSEL_BITS) << CHSEL_LSB);
02398     
02399     //----------------------------------------
02400     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
02401     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
02402     
02403     //----------------------------------------
02404     // ADC MODE CONTROL register set SWCNV if CNVST pin is not used
02405     // ADC MODE CONTROL REGISTER SELECT THE RIGHT SWCNV BIT
02406     // (applicable to internal clock mode only)
02407     // SWCNV=1: trigger measurement on SPI CS rising edge; CNVST pin is not used. (AIN14 is available)
02408     // SWCNV=0: trigger measurement by driving CNVST pin low for a minimum active-low pulse duration of 5ns. (AIN14 is not available)
02409     if (swcnv_0_1) {
02410         ADC_MODE_CONTROL |=   ((swcnv_0_1 & SWCNV_BITS) << SWCNV_LSB);
02411     } else {
02412         ADC_MODE_CONTROL &= ~ ((            SWCNV_BITS) << SWCNV_LSB);
02413     }
02414     
02415     //----------------------------------------
02416     // SPI write ADC MODE CONTROL register
02417     // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
02418     // Send SPI configuration to device
02419     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02420     SPIoutputCS(0); // drive CS low
02421     if (swcnv_0_1) {
02422       // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
02423       // NOTE: Figure 7 Internal Conversions with SWCNV=1 has an error, the 17th SCLK is mislabeled as "16" should be "17".
02424       SPIwrite24bits(ADC_MODE_CONTROL, 0);
02425     } else {
02426       SPIwrite16bits(ADC_MODE_CONTROL);
02427     }
02428     SPIoutputCS(1); // drive CS high
02429     
02430     //----------------------------------------
02431     // return number of words to read
02432     return NumWords;
02433 }
02434 
02435 //----------------------------------------
02436 // SCAN_0011_StandardInternalClock
02437 //
02438 // Measure ADC channels in sequence from AIN0 to channelNumber_0_15.
02439 // Internal clock mode.
02440 // @param[in] channelNumber_0_15: AIN Channel Number
02441 // @param[in] average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
02442 //     average_0_4_8_16_32=0 to disable averaging.
02443 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
02444 // @param[in] swcnv_0_1: ADC_MODE_CONTROL.SWCNV
02445 //     SWCNV=0: trigger measurement by driving CNVST pin low.
02446 //         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
02447 //     SWCNV=1: trigger measurement on SPI CS rising edge.
02448 //         CS must be held low for minimum of 17 SCLK cycles.
02449 //         CNVST pin is not used. (AIN14 is available)
02450 // @return number of ScanRead() words needed to retrieve the data.
02451 // @post NumWords = number of words to be read from the FIFO
02452 // For internal clock modes, the data format always includes the channel address.
02453 //     misoData16 = CH[3:0] DATA[11:0]
02454 //
02455 int MAX11131::ScanStandardInternalClock(void)
02456 {
02457     
02458     //----------------------------------------
02459     // number of words to read
02460     NumWords = (1 + channelNumber_0_15);
02461     
02462     //----------------------------------------
02463     // Internal Clock Mode
02464     isExternalClock = 0;
02465     
02466     //----------------------------------------
02467     // update device driver global variable
02468     ScanMode = SCAN_0011_StandardInternalClock;
02469     
02470     //----------------------------------------
02471     // define write-only register ADC_MODE_CONTROL
02472     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
02473     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
02474     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
02475     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02476     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
02477     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
02478     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
02479     
02480     //----------------------------------------
02481     // define write-only register ADC_CONFIGURATION
02482     ADC_CONFIGURATION = 0x8000; //!< mosiData16 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
02483     const int REFSEL_LSB = 10; const int REFSEL_BITS = 0x01; // ADC_CONFIGURATION.REFSEL
02484     const int AVGON_LSB  =  9; const int AVGON_BITS  = 0x01; // ADC_CONFIGURATION.AVGON
02485     const int NAVG_LSB   =  7; const int NAVG_BITS   = 0x03; // ADC_CONFIGURATION.NAVG[1:0]
02486     const int NSCAN_LSB  =  5; const int NSCAN_BITS  = 0x03; // ADC_CONFIGURATION.NSCAN[1:0]
02487     const int SPM_LSB    =  3; const int SPM_BITS    = 0x03; // ADC_CONFIGURATION.SPM[1:0]
02488     const int ECHO_LSB   =  2; const int ECHO_BITS   = 0x01; // ADC_CONFIGURATION.ECHO
02489     
02490     //----------------------------------------
02491     // if average, ADC CONFIGURATION register set AVG and NAVG[1:0]
02492     // (applicable to internal clock mode only)
02493     // if average, ADC CONFIGURATION register set AVG ON BIT TO 1
02494     // if average, ADC CONFIGURATION register set NAVG[1:0] TO N
02495     if (average_0_4_8_16_32 == 4) {
02496         // Enable Averaging of 4 samples (AVGON=1, NAVG[1:0]=0)
02497         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02498         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02499         ADC_CONFIGURATION |=   ((0 & NAVG_BITS) << NAVG_LSB);
02500     } else if (average_0_4_8_16_32 == 8) {
02501         // Enable Averaging of 8 samples (AVGON=1, NAVG[1:0]=1)
02502         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02503         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02504         ADC_CONFIGURATION |=   ((1 & NAVG_BITS) << NAVG_LSB);
02505     } else if (average_0_4_8_16_32 == 16) {
02506         // Enable Averaging of 16 samples (AVGON=1, NAVG[1:0]=2)
02507         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02508         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02509         ADC_CONFIGURATION |=   ((2 & NAVG_BITS) << NAVG_LSB);
02510     } else if (average_0_4_8_16_32 == 32) {
02511         // Enable Averaging of 32 samples (AVGON=1, NAVG[1:0]=3)
02512         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02513         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02514         ADC_CONFIGURATION |=   ((3 & NAVG_BITS) << NAVG_LSB);
02515     } else {
02516         // Disable Averaging (AVGON=0, NAVG[1:0]=0)
02517         ADC_CONFIGURATION &= ~ ((    AVGON_BITS) << AVGON_LSB);
02518         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02519     }
02520     
02521     //----------------------------------------
02522     // SPI write ADC CONFIGURATION register
02523     // Send SPI configuration to device
02524     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02525     SPIoutputCS(0); // drive CS low
02526     SPIwrite16bits(ADC_CONFIGURATION);
02527     SPIoutputCS(1); // drive CS high
02528     
02529     //----------------------------------------
02530     // Reset FIFO: ADC_MODE_CONTROL.RESET[1:0] = 1   Apply a soft reset when changing from internal to external clock mode.
02531     ADC_MODE_CONTROL &= ~ ((    RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02532     ADC_MODE_CONTROL |=   ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02533     
02534     //----------------------------------------
02535     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_0011_StandardInternalClock = 3
02536     //~ const int SCAN_0011_StandardInternalClock = 3; // replaced local const with enum
02537     ADC_MODE_CONTROL |=   ((SCAN_0011_StandardInternalClock & SCAN_BITS) << SCAN_LSB);
02538     
02539     //----------------------------------------
02540     // ADC MODE CONTROL register set CHSEL[3:0] TO channel number
02541     ADC_MODE_CONTROL |=   ((channelNumber_0_15 & CHSEL_BITS) << CHSEL_LSB);
02542     
02543     //----------------------------------------
02544     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
02545     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
02546     
02547     //----------------------------------------
02548     // ADC MODE CONTROL register set SWCNV if CNVST pin is not used
02549     // ADC MODE CONTROL REGISTER SELECT THE RIGHT SWCNV BIT
02550     // (applicable to internal clock mode only)
02551     // SWCNV=1: trigger measurement on SPI CS rising edge; CNVST pin is not used. (AIN14 is available)
02552     // SWCNV=0: trigger measurement by driving CNVST pin low for a minimum active-low pulse duration of 5ns. (AIN14 is not available)
02553     if (swcnv_0_1) {
02554         ADC_MODE_CONTROL |=   ((swcnv_0_1 & SWCNV_BITS) << SWCNV_LSB);
02555     } else {
02556         ADC_MODE_CONTROL &= ~ ((            SWCNV_BITS) << SWCNV_LSB);
02557     }
02558     
02559     //----------------------------------------
02560     // SPI write ADC MODE CONTROL register
02561     // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
02562     // Send SPI configuration to device
02563     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02564     SPIoutputCS(0); // drive CS low
02565     if (swcnv_0_1) {
02566       // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
02567       // NOTE: Figure 7 Internal Conversions with SWCNV=1 has an error, the 17th SCLK is mislabeled as "16" should be "17".
02568       SPIwrite24bits(ADC_MODE_CONTROL, 0);
02569     } else {
02570       SPIwrite16bits(ADC_MODE_CONTROL);
02571     }
02572     SPIoutputCS(1); // drive CS high
02573     
02574     //----------------------------------------
02575     // return number of words to read
02576     return NumWords;
02577 }
02578 
02579 //----------------------------------------
02580 // SCAN_0100_StandardExternalClock
02581 //
02582 // Measure ADC channels in sequence from AIN0 to channelNumber_0_15.
02583 // External clock mode.
02584 // @param[in] channelNumber_0_15: AIN Channel Number
02585 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
02586 // @param[in] chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
02587 // @return number of ScanRead() words needed to retrieve the data.
02588 // @post NumWords = number of words to be read from the FIFO
02589 // For external clock modes, the data format depends on CHAN_ID.
02590 //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02591 //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02592 //
02593 int MAX11131::ScanStandardExternalClock(void)
02594 {
02595     
02596     //----------------------------------------
02597     // define write-only register ADC_MODE_CONTROL
02598     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
02599     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
02600     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
02601     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02602     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
02603     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
02604     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
02605     
02606     //----------------------------------------
02607     // Apply a soft reset when changing from internal to external clock mode.
02608     int needFIFOreset = (isExternalClock != 1);
02609     if (needFIFOreset) {
02610         // Apply a soft reset when changing from internal to external clock mode.
02611         ADC_MODE_CONTROL = ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02612         // Send SPI configuration to device
02613         SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02614         SPIoutputCS(0); // drive CS low
02615         SPIwrite16bits(ADC_MODE_CONTROL);
02616         SPIoutputCS(1); // drive CS high
02617         ADC_MODE_CONTROL = 0;
02618     }
02619     
02620     //----------------------------------------
02621     // number of words to read
02622     NumWords = (1 + channelNumber_0_15);
02623     
02624     //----------------------------------------
02625     // External Clock Mode
02626     isExternalClock = 1;
02627     
02628     //----------------------------------------
02629     // update device driver global variable
02630     ScanMode = SCAN_0100_StandardExternalClock;
02631     
02632     //----------------------------------------
02633     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_0100_StandardExternalClock = 4
02634     //~ const int SCAN_0100_StandardExternalClock = 4; // replaced local const with enum
02635     ADC_MODE_CONTROL |=   ((SCAN_0100_StandardExternalClock & SCAN_BITS) << SCAN_LSB);
02636     
02637     //----------------------------------------
02638     // ADC MODE CONTROL register set CHSEL[3:0] TO channel number
02639     ADC_MODE_CONTROL |=   ((channelNumber_0_15 & CHSEL_BITS) << CHSEL_LSB);
02640     
02641     //----------------------------------------
02642     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
02643     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
02644     
02645     //----------------------------------------
02646     // ADC MODE CONTROL REGISTER SELECT THE CHAN_ID BIT
02647     // (applicable to external clock mode only)
02648     // For external clock modes, the data format returned depends on the CHAN_ID bit.
02649     //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02650     //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02651     // For internal clock modes, the data format always includes the channel address.
02652     //     misoData16 = CH[3:0] DATA[11:0]
02653     ADC_MODE_CONTROL |=   ((chan_id_0_1 & CHAN_ID_BITS) << CHAN_ID_LSB);
02654     
02655     //----------------------------------------
02656     // SPI write ADC MODE CONTROL register
02657     // Send SPI configuration to device
02658     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02659     SPIoutputCS(0); // drive CS low
02660     SPIwrite16bits(ADC_MODE_CONTROL);
02661     SPIoutputCS(1); // drive CS high
02662     
02663     //----------------------------------------
02664     // return number of words to read
02665     return NumWords;
02666 }
02667 
02668 //----------------------------------------
02669 // SCAN_0101_UpperInternalClock
02670 //
02671 // Measure ADC channels in sequence from channelNumber_0_15 to AIN15.
02672 // Internal clock mode.
02673 // @param[in] channelNumber_0_15: AIN Channel Number
02674 // @param[in] average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
02675 //     average_0_4_8_16_32=0 to disable averaging.
02676 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
02677 // @param[in] swcnv_0_1: ADC_MODE_CONTROL.SWCNV
02678 //     SWCNV=0: trigger measurement by driving CNVST pin low.
02679 //         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
02680 //     SWCNV=1: trigger measurement on SPI CS rising edge.
02681 //         CS must be held low for minimum of 17 SCLK cycles.
02682 //         CNVST pin is not used. (AIN14 is available)
02683 // @return number of ScanRead() words needed to retrieve the data.
02684 // @post NumWords = number of words to be read from the FIFO
02685 // For internal clock modes, the data format always includes the channel address.
02686 //     misoData16 = CH[3:0] DATA[11:0]
02687 //
02688 int MAX11131::ScanUpperInternalClock(void)
02689 {
02690     
02691     //----------------------------------------
02692     // number of words to read
02693     NumWords = (16 - channelNumber_0_15);
02694     
02695     //----------------------------------------
02696     // Internal Clock Mode
02697     isExternalClock = 0;
02698     
02699     //----------------------------------------
02700     // update device driver global variable
02701     ScanMode = SCAN_0101_UpperInternalClock;
02702     
02703     //----------------------------------------
02704     // define write-only register ADC_MODE_CONTROL
02705     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
02706     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
02707     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
02708     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02709     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
02710     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
02711     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
02712     
02713     //----------------------------------------
02714     // define write-only register ADC_CONFIGURATION
02715     ADC_CONFIGURATION = 0x8000; //!< mosiData16 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
02716     const int REFSEL_LSB = 10; const int REFSEL_BITS = 0x01; // ADC_CONFIGURATION.REFSEL
02717     const int AVGON_LSB  =  9; const int AVGON_BITS  = 0x01; // ADC_CONFIGURATION.AVGON
02718     const int NAVG_LSB   =  7; const int NAVG_BITS   = 0x03; // ADC_CONFIGURATION.NAVG[1:0]
02719     const int NSCAN_LSB  =  5; const int NSCAN_BITS  = 0x03; // ADC_CONFIGURATION.NSCAN[1:0]
02720     const int SPM_LSB    =  3; const int SPM_BITS    = 0x03; // ADC_CONFIGURATION.SPM[1:0]
02721     const int ECHO_LSB   =  2; const int ECHO_BITS   = 0x01; // ADC_CONFIGURATION.ECHO
02722     
02723     //----------------------------------------
02724     // if average, ADC CONFIGURATION register set AVG and NAVG[1:0]
02725     // (applicable to internal clock mode only)
02726     // if average, ADC CONFIGURATION register set AVG ON BIT TO 1
02727     // if average, ADC CONFIGURATION register set NAVG[1:0] TO N
02728     if (average_0_4_8_16_32 == 4) {
02729         // Enable Averaging of 4 samples (AVGON=1, NAVG[1:0]=0)
02730         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02731         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02732         ADC_CONFIGURATION |=   ((0 & NAVG_BITS) << NAVG_LSB);
02733     } else if (average_0_4_8_16_32 == 8) {
02734         // Enable Averaging of 8 samples (AVGON=1, NAVG[1:0]=1)
02735         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02736         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02737         ADC_CONFIGURATION |=   ((1 & NAVG_BITS) << NAVG_LSB);
02738     } else if (average_0_4_8_16_32 == 16) {
02739         // Enable Averaging of 16 samples (AVGON=1, NAVG[1:0]=2)
02740         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02741         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02742         ADC_CONFIGURATION |=   ((2 & NAVG_BITS) << NAVG_LSB);
02743     } else if (average_0_4_8_16_32 == 32) {
02744         // Enable Averaging of 32 samples (AVGON=1, NAVG[1:0]=3)
02745         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
02746         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02747         ADC_CONFIGURATION |=   ((3 & NAVG_BITS) << NAVG_LSB);
02748     } else {
02749         // Disable Averaging (AVGON=0, NAVG[1:0]=0)
02750         ADC_CONFIGURATION &= ~ ((    AVGON_BITS) << AVGON_LSB);
02751         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
02752     }
02753     
02754     //----------------------------------------
02755     // SPI write ADC CONFIGURATION register
02756     // Send SPI configuration to device
02757     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02758     SPIoutputCS(0); // drive CS low
02759     SPIwrite16bits(ADC_CONFIGURATION);
02760     SPIoutputCS(1); // drive CS high
02761     
02762     //----------------------------------------
02763     // Reset FIFO: ADC_MODE_CONTROL.RESET[1:0] = 1   Apply a soft reset when changing from internal to external clock mode.
02764     ADC_MODE_CONTROL &= ~ ((    RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02765     ADC_MODE_CONTROL |=   ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02766     
02767     //----------------------------------------
02768     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_0101_UpperInternalClock = 5
02769     //~ const int SCAN_0101_UpperInternalClock = 5; // replaced local const with enum
02770     ADC_MODE_CONTROL |=   ((SCAN_0101_UpperInternalClock & SCAN_BITS) << SCAN_LSB);
02771     
02772     //----------------------------------------
02773     // ADC MODE CONTROL register set CHSEL[3:0] TO channel number
02774     ADC_MODE_CONTROL |=   ((channelNumber_0_15 & CHSEL_BITS) << CHSEL_LSB);
02775     
02776     //----------------------------------------
02777     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
02778     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
02779     
02780     //----------------------------------------
02781     // ADC MODE CONTROL register set SWCNV if CNVST pin is not used
02782     // ADC MODE CONTROL REGISTER SELECT THE RIGHT SWCNV BIT
02783     // (applicable to internal clock mode only)
02784     // SWCNV=1: trigger measurement on SPI CS rising edge; CNVST pin is not used. (AIN14 is available)
02785     // SWCNV=0: trigger measurement by driving CNVST pin low for a minimum active-low pulse duration of 5ns. (AIN14 is not available)
02786     if (swcnv_0_1) {
02787         ADC_MODE_CONTROL |=   ((swcnv_0_1 & SWCNV_BITS) << SWCNV_LSB);
02788     } else {
02789         ADC_MODE_CONTROL &= ~ ((            SWCNV_BITS) << SWCNV_LSB);
02790     }
02791     
02792     //----------------------------------------
02793     // SPI write ADC MODE CONTROL register
02794     // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
02795     // Send SPI configuration to device
02796     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02797     SPIoutputCS(0); // drive CS low
02798     if (swcnv_0_1) {
02799       // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
02800       // NOTE: Figure 7 Internal Conversions with SWCNV=1 has an error, the 17th SCLK is mislabeled as "16" should be "17".
02801       SPIwrite24bits(ADC_MODE_CONTROL, 0);
02802     } else {
02803       SPIwrite16bits(ADC_MODE_CONTROL);
02804     }
02805     SPIoutputCS(1); // drive CS high
02806     
02807     //----------------------------------------
02808     // return number of words to read
02809     return NumWords;
02810 }
02811 
02812 //----------------------------------------
02813 // SCAN_0110_UpperExternalClock
02814 //
02815 // Measure ADC channels in sequence from channelNumber_0_15 to AIN15.
02816 // External clock mode.
02817 // @param[in] channelNumber_0_15: AIN Channel Number
02818 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
02819 // @param[in] chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
02820 // @return number of ScanRead() words needed to retrieve the data.
02821 // @post NumWords = number of words to be read from the FIFO
02822 // For external clock modes, the data format depends on CHAN_ID.
02823 //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02824 //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02825 //
02826 int MAX11131::ScanUpperExternalClock(void)
02827 {
02828     
02829     //----------------------------------------
02830     // define write-only register ADC_MODE_CONTROL
02831     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
02832     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
02833     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
02834     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02835     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
02836     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
02837     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
02838     
02839     //----------------------------------------
02840     // Apply a soft reset when changing from internal to external clock mode.
02841     int needFIFOreset = (isExternalClock != 1);
02842     if (needFIFOreset) {
02843         // Apply a soft reset when changing from internal to external clock mode.
02844         ADC_MODE_CONTROL = ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02845         // Send SPI configuration to device
02846         SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02847         SPIoutputCS(0); // drive CS low
02848         SPIwrite16bits(ADC_MODE_CONTROL);
02849         SPIoutputCS(1); // drive CS high
02850         ADC_MODE_CONTROL = 0;
02851     }
02852     
02853     //----------------------------------------
02854     // number of words to read
02855     NumWords = (16 - channelNumber_0_15);
02856     
02857     //----------------------------------------
02858     // External Clock Mode
02859     isExternalClock = 1;
02860     
02861     //----------------------------------------
02862     // update device driver global variable
02863     ScanMode = SCAN_0110_UpperExternalClock;
02864     
02865     //----------------------------------------
02866     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_0110_UpperExternalClock = 6
02867     //~ const int SCAN_0110_UpperExternalClock = 6; // replaced local const with enum
02868     ADC_MODE_CONTROL |=   ((SCAN_0110_UpperExternalClock & SCAN_BITS) << SCAN_LSB);
02869     
02870     //----------------------------------------
02871     // ADC MODE CONTROL register set CHSEL[3:0] TO channel number
02872     ADC_MODE_CONTROL |=   ((channelNumber_0_15 & CHSEL_BITS) << CHSEL_LSB);
02873     
02874     //----------------------------------------
02875     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
02876     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
02877     
02878     //----------------------------------------
02879     // ADC MODE CONTROL REGISTER SELECT THE CHAN_ID BIT
02880     // (applicable to external clock mode only)
02881     // For external clock modes, the data format returned depends on the CHAN_ID bit.
02882     //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
02883     //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
02884     // For internal clock modes, the data format always includes the channel address.
02885     //     misoData16 = CH[3:0] DATA[11:0]
02886     ADC_MODE_CONTROL |=   ((chan_id_0_1 & CHAN_ID_BITS) << CHAN_ID_LSB);
02887     
02888     //----------------------------------------
02889     // SPI write ADC MODE CONTROL register
02890     // Send SPI configuration to device
02891     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
02892     SPIoutputCS(0); // drive CS low
02893     SPIwrite16bits(ADC_MODE_CONTROL);
02894     SPIoutputCS(1); // drive CS high
02895     
02896     //----------------------------------------
02897     // return number of words to read
02898     return NumWords;
02899 }
02900 
02901 //----------------------------------------
02902 // SCAN_0111_CustomInternalClock
02903 //
02904 // Measure selected ADC channels in sequence from AIN0 to AIN15,
02905 //     using only the channels enabled by enabledChannelsMask.
02906 //     Bit 0x0001 enables AIN0.
02907 //     Bit 0x0002 enables AIN1.
02908 //     Bit 0x0004 enables AIN2.
02909 //     Bit 0x0008 enables AIN3.
02910 //     Bit 0x0010 enables AIN4.
02911 //     Bit 0x0020 enables AIN5.
02912 //     Bit 0x0040 enables AIN6.
02913 //     Bit 0x0080 enables AIN7.
02914 //     Bit 0x0100 enables AIN8.
02915 //     Bit 0x0200 enables AIN9.
02916 //     Bit 0x0400 enables AIN10.
02917 //     Bit 0x0800 enables AIN11.
02918 //     Bit 0x1000 enables AIN12.
02919 //     Bit 0x2000 enables AIN13.
02920 //     Bit 0x4000 enables AIN14.
02921 //     Bit 0x8000 enables AIN15.
02922 // Internal clock mode.
02923 // @param[in] enabledChannelsMask: Bitmap of AIN Channels to scan.
02924 // @param[in] average_0_4_8_16_32: Number of samples averaged per ScanRead() word.
02925 //     average_0_4_8_16_32=0 to disable averaging.
02926 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
02927 // @param[in] swcnv_0_1: ADC_MODE_CONTROL.SWCNV
02928 //     SWCNV=0: trigger measurement by driving CNVST pin low.
02929 //         Minimum active-low pulse duration of 5ns. (AIN14 is not available)
02930 //     SWCNV=1: trigger measurement on SPI CS rising edge.
02931 //         CS must be held low for minimum of 17 SCLK cycles.
02932 //         CNVST pin is not used. (AIN14 is available)
02933 // @return number of ScanRead() words needed to retrieve the data.
02934 // @post NumWords = number of words to be read from the FIFO
02935 // For internal clock modes, the data format always includes the channel address.
02936 //     misoData16 = CH[3:0] DATA[11:0]
02937 //
02938 int MAX11131::ScanCustomInternalClock(void)
02939 {
02940     
02941     //----------------------------------------
02942     // count nWords = number of set bits in enabledChannelsMask
02943     uint16_t bitMask;
02944     int nWords = 0;
02945     for (bitMask = 0x8000; bitMask != 0; bitMask = bitMask / 2)
02946     {
02947         if (enabledChannelsMask & bitMask)
02948         {
02949             nWords++;
02950         }
02951     }
02952     
02953     //----------------------------------------
02954     // number of words to read
02955     NumWords = nWords;
02956     
02957     //----------------------------------------
02958     // Internal Clock Mode
02959     isExternalClock = 0;
02960     
02961     //----------------------------------------
02962     // update device driver global variable
02963     ScanMode = SCAN_0111_CustomInternalClock;
02964     
02965     //----------------------------------------
02966     // define write-only register ADC_MODE_CONTROL
02967     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
02968     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
02969     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
02970     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
02971     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
02972     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
02973     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
02974     
02975     //----------------------------------------
02976     // define write-only register ADC_CONFIGURATION
02977     ADC_CONFIGURATION = 0x8000; //!< mosiData16 0x8000..0x87FF format: 1 0 0 0 0 REFSEL AVGON NAVG[1:0] NSCAN[1:0] SPM[1:0] ECHO 0 0
02978     const int REFSEL_LSB = 10; const int REFSEL_BITS = 0x01; // ADC_CONFIGURATION.REFSEL
02979     const int AVGON_LSB  =  9; const int AVGON_BITS  = 0x01; // ADC_CONFIGURATION.AVGON
02980     const int NAVG_LSB   =  7; const int NAVG_BITS   = 0x03; // ADC_CONFIGURATION.NAVG[1:0]
02981     const int NSCAN_LSB  =  5; const int NSCAN_BITS  = 0x03; // ADC_CONFIGURATION.NSCAN[1:0]
02982     const int SPM_LSB    =  3; const int SPM_BITS    = 0x03; // ADC_CONFIGURATION.SPM[1:0]
02983     const int ECHO_LSB   =  2; const int ECHO_BITS   = 0x01; // ADC_CONFIGURATION.ECHO
02984     
02985     //----------------------------------------
02986     // define write-only registers CSCAN0,CSCAN1
02987     CSCAN0 = 0xA000;            //!< mosiData16 0xA000..0xA7FF format: 1 0 1 0 0 CHSCAN15 CHSCAN14 CHSCAN13 CHSCAN12 CHSCAN11 CHSCAN10 CHSCAN9 CHSCAN8 x x x
02988     const int CHSCAN15_LSB = 10; // CSCAN0.CHSCAN15
02989     const int CHSCAN14_LSB =  9; // CSCAN0.CHSCAN14
02990     const int CHSCAN13_LSB =  8; // CSCAN0.CHSCAN13
02991     const int CHSCAN12_LSB =  7; // CSCAN0.CHSCAN12
02992     const int CHSCAN11_LSB =  6; // CSCAN0.CHSCAN11
02993     const int CHSCAN10_LSB =  5; // CSCAN0.CHSCAN10
02994     const int CHSCAN9_LSB  =  4; // CSCAN0.CHSCAN9
02995     const int CHSCAN8_LSB  =  3; // CSCAN0.CHSCAN8
02996     CSCAN1 = 0xA800;            //!< mosiData16 0xA800..0xAFFF format: 1 0 1 0 1 CHSCAN7 CHSCAN6 CHSCAN5 CHSCAN4 CHSCAN3 CHSCAN2 CHSCAN1 CHSCAN0 x x x
02997     const int CHSCAN7_LSB = 10; // CSCAN1.CHSCAN7
02998     const int CHSCAN6_LSB =  9; // CSCAN1.CHSCAN6
02999     const int CHSCAN5_LSB =  8; // CSCAN1.CHSCAN5
03000     const int CHSCAN4_LSB =  7; // CSCAN1.CHSCAN4
03001     const int CHSCAN3_LSB =  6; // CSCAN1.CHSCAN3
03002     const int CHSCAN2_LSB =  5; // CSCAN1.CHSCAN2
03003     const int CHSCAN1_LSB =  4; // CSCAN1.CHSCAN1
03004     const int CHSCAN0_LSB =  3; // CSCAN1.CHSCAN0
03005     
03006     //----------------------------------------
03007     // if average, ADC CONFIGURATION register set AVG and NAVG[1:0]
03008     // (applicable to internal clock mode only)
03009     // if average, ADC CONFIGURATION register set AVG ON BIT TO 1
03010     // if average, ADC CONFIGURATION register set NAVG[1:0] TO N
03011     if (average_0_4_8_16_32 == 4) {
03012         // Enable Averaging of 4 samples (AVGON=1, NAVG[1:0]=0)
03013         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
03014         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
03015         ADC_CONFIGURATION |=   ((0 & NAVG_BITS) << NAVG_LSB);
03016     } else if (average_0_4_8_16_32 == 8) {
03017         // Enable Averaging of 8 samples (AVGON=1, NAVG[1:0]=1)
03018         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
03019         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
03020         ADC_CONFIGURATION |=   ((1 & NAVG_BITS) << NAVG_LSB);
03021     } else if (average_0_4_8_16_32 == 16) {
03022         // Enable Averaging of 16 samples (AVGON=1, NAVG[1:0]=2)
03023         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
03024         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
03025         ADC_CONFIGURATION |=   ((2 & NAVG_BITS) << NAVG_LSB);
03026     } else if (average_0_4_8_16_32 == 32) {
03027         // Enable Averaging of 32 samples (AVGON=1, NAVG[1:0]=3)
03028         ADC_CONFIGURATION |=   ((1 & AVGON_BITS) << AVGON_LSB);
03029         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
03030         ADC_CONFIGURATION |=   ((3 & NAVG_BITS) << NAVG_LSB);
03031     } else {
03032         // Disable Averaging (AVGON=0, NAVG[1:0]=0)
03033         ADC_CONFIGURATION &= ~ ((    AVGON_BITS) << AVGON_LSB);
03034         ADC_CONFIGURATION &= ~ ((    NAVG_BITS) << NAVG_LSB);
03035     }
03036     
03037     //----------------------------------------
03038     // SPI write ADC CONFIGURATION register
03039     // Send SPI configuration to device
03040     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03041     SPIoutputCS(0); // drive CS low
03042     SPIwrite16bits(ADC_CONFIGURATION);
03043     SPIoutputCS(1); // drive CS high
03044     
03045     //----------------------------------------
03046     // SET CSCAN0 CSCAN1 REGISTERS from enabledChannelsMask
03047     CSCAN0 = 0xA000 | (((enabledChannelsMask >> 8) & 0xFF) << 3); // CSCAN0.CHSCAN[15:8]
03048     CSCAN1 = 0xA800 | (((enabledChannelsMask) & 0xFF) << 3); // CSCAN1.CHSCAN[7:0]
03049     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03050     SPIoutputCS(0); // drive CS low
03051     SPIwrite16bits(CSCAN0);
03052     SPIoutputCS(1); // drive CS high
03053     SPIoutputCS(0); // drive CS low
03054     SPIwrite16bits(CSCAN1);
03055     SPIoutputCS(1); // drive CS high
03056     
03057     //----------------------------------------
03058     // Reset FIFO: ADC_MODE_CONTROL.RESET[1:0] = 1   Apply a soft reset when changing from internal to external clock mode.
03059     ADC_MODE_CONTROL &= ~ ((    RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
03060     ADC_MODE_CONTROL |=   ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
03061     
03062     //----------------------------------------
03063     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_0111_CustomInternalClock = 7
03064     //~ const int SCAN_0111_CustomInternalClock = 7; // replaced local const with enum
03065     ADC_MODE_CONTROL |=   ((SCAN_0111_CustomInternalClock & SCAN_BITS) << SCAN_LSB);
03066     
03067     //----------------------------------------
03068     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
03069     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
03070     
03071     //----------------------------------------
03072     // ADC MODE CONTROL register set SWCNV if CNVST pin is not used
03073     // ADC MODE CONTROL REGISTER SELECT THE RIGHT SWCNV BIT
03074     // (applicable to internal clock mode only)
03075     // SWCNV=1: trigger measurement on SPI CS rising edge; CNVST pin is not used. (AIN14 is available)
03076     // SWCNV=0: trigger measurement by driving CNVST pin low for a minimum active-low pulse duration of 5ns. (AIN14 is not available)
03077     if (swcnv_0_1) {
03078         ADC_MODE_CONTROL |=   ((swcnv_0_1 & SWCNV_BITS) << SWCNV_LSB);
03079     } else {
03080         ADC_MODE_CONTROL &= ~ ((            SWCNV_BITS) << SWCNV_LSB);
03081     }
03082     
03083     //----------------------------------------
03084     // SPI write ADC MODE CONTROL register
03085     // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
03086     // Send SPI configuration to device
03087     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03088     SPIoutputCS(0); // drive CS low
03089     if (swcnv_0_1) {
03090       // If SWCNV=1 then CS must be held low for at least 17 SCLK cycles.
03091       // NOTE: Figure 7 Internal Conversions with SWCNV=1 has an error, the 17th SCLK is mislabeled as "16" should be "17".
03092       SPIwrite24bits(ADC_MODE_CONTROL, 0);
03093     } else {
03094       SPIwrite16bits(ADC_MODE_CONTROL);
03095     }
03096     SPIoutputCS(1); // drive CS high
03097     
03098     //----------------------------------------
03099     // return number of words to read
03100     return NumWords;
03101 }
03102 
03103 //----------------------------------------
03104 // SCAN_1000_CustomExternalClock
03105 //
03106 // Measure selected ADC channels in sequence from AIN0 to AIN15,
03107 //     using only the channels enabled by enabledChannelsMask.
03108 //     Bit 0x0001 enables AIN0.
03109 //     Bit 0x0002 enables AIN1.
03110 //     Bit 0x0004 enables AIN2.
03111 //     Bit 0x0008 enables AIN3.
03112 //     Bit 0x0010 enables AIN4.
03113 //     Bit 0x0020 enables AIN5.
03114 //     Bit 0x0040 enables AIN6.
03115 //     Bit 0x0080 enables AIN7.
03116 //     Bit 0x0100 enables AIN8.
03117 //     Bit 0x0200 enables AIN9.
03118 //     Bit 0x0400 enables AIN10.
03119 //     Bit 0x0800 enables AIN11.
03120 //     Bit 0x1000 enables AIN12.
03121 //     Bit 0x2000 enables AIN13.
03122 //     Bit 0x4000 enables AIN14.
03123 //     Bit 0x8000 enables AIN15.
03124 // External clock mode.
03125 // @param[in] enabledChannelsMask: Bitmap of AIN Channels to scan.
03126 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
03127 // @param[in] chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
03128 // @return number of ScanRead() words needed to retrieve the data.
03129 // @post NumWords = number of words to be read from the FIFO
03130 // For external clock modes, the data format depends on CHAN_ID.
03131 //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
03132 //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
03133 //
03134 int MAX11131::ScanCustomExternalClock(void)
03135 {
03136     
03137     //----------------------------------------
03138     // count nWords = number of set bits in enabledChannelsMask
03139     uint16_t bitMask;
03140     int nWords = 0;
03141     for (bitMask = 0x8000; bitMask != 0; bitMask = bitMask / 2)
03142     {
03143         if (enabledChannelsMask & bitMask)
03144         {
03145             nWords++;
03146         }
03147     }
03148     
03149     //----------------------------------------
03150     // define write-only register ADC_MODE_CONTROL
03151     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
03152     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
03153     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
03154     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
03155     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
03156     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
03157     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
03158     
03159     //----------------------------------------
03160     // Apply a soft reset when changing from internal to external clock mode.
03161     int needFIFOreset = (isExternalClock != 1);
03162     if (needFIFOreset) {
03163         // Apply a soft reset when changing from internal to external clock mode.
03164         ADC_MODE_CONTROL = ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
03165         // Send SPI configuration to device
03166         SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03167         SPIoutputCS(0); // drive CS low
03168         SPIwrite16bits(ADC_MODE_CONTROL);
03169         SPIoutputCS(1); // drive CS high
03170         ADC_MODE_CONTROL = 0;
03171     }
03172     
03173     //----------------------------------------
03174     // number of words to read
03175     NumWords = nWords;
03176     
03177     //----------------------------------------
03178     // External Clock Mode
03179     isExternalClock = 1;
03180     
03181     //----------------------------------------
03182     // update device driver global variable
03183     ScanMode = SCAN_1000_CustomExternalClock;
03184     
03185     //----------------------------------------
03186     // define write-only registers CSCAN0,CSCAN1
03187     CSCAN0 = 0xA000;            //!< mosiData16 0xA000..0xA7FF format: 1 0 1 0 0 CHSCAN15 CHSCAN14 CHSCAN13 CHSCAN12 CHSCAN11 CHSCAN10 CHSCAN9 CHSCAN8 x x x
03188     const int CHSCAN15_LSB = 10; // CSCAN0.CHSCAN15
03189     const int CHSCAN14_LSB =  9; // CSCAN0.CHSCAN14
03190     const int CHSCAN13_LSB =  8; // CSCAN0.CHSCAN13
03191     const int CHSCAN12_LSB =  7; // CSCAN0.CHSCAN12
03192     const int CHSCAN11_LSB =  6; // CSCAN0.CHSCAN11
03193     const int CHSCAN10_LSB =  5; // CSCAN0.CHSCAN10
03194     const int CHSCAN9_LSB  =  4; // CSCAN0.CHSCAN9
03195     const int CHSCAN8_LSB  =  3; // CSCAN0.CHSCAN8
03196     CSCAN1 = 0xA800;            //!< mosiData16 0xA800..0xAFFF format: 1 0 1 0 1 CHSCAN7 CHSCAN6 CHSCAN5 CHSCAN4 CHSCAN3 CHSCAN2 CHSCAN1 CHSCAN0 x x x
03197     const int CHSCAN7_LSB = 10; // CSCAN1.CHSCAN7
03198     const int CHSCAN6_LSB =  9; // CSCAN1.CHSCAN6
03199     const int CHSCAN5_LSB =  8; // CSCAN1.CHSCAN5
03200     const int CHSCAN4_LSB =  7; // CSCAN1.CHSCAN4
03201     const int CHSCAN3_LSB =  6; // CSCAN1.CHSCAN3
03202     const int CHSCAN2_LSB =  5; // CSCAN1.CHSCAN2
03203     const int CHSCAN1_LSB =  4; // CSCAN1.CHSCAN1
03204     const int CHSCAN0_LSB =  3; // CSCAN1.CHSCAN0
03205     
03206     //----------------------------------------
03207     // SET CSCAN0 CSCAN1 REGISTERS from enabledChannelsMask
03208     CSCAN0 = 0xA000 | (((enabledChannelsMask >> 8) & 0xFF) << 3); // CSCAN0.CHSCAN[15:8]
03209     CSCAN1 = 0xA800 | (((enabledChannelsMask) & 0xFF) << 3); // CSCAN1.CHSCAN[7:0]
03210     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03211     SPIoutputCS(0); // drive CS low
03212     SPIwrite16bits(CSCAN0);
03213     SPIoutputCS(1); // drive CS high
03214     SPIoutputCS(0); // drive CS low
03215     SPIwrite16bits(CSCAN1);
03216     SPIoutputCS(1); // drive CS high
03217     
03218     //----------------------------------------
03219     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_1000_CustomExternalClock = 8
03220     //~ const int SCAN_1000_CustomExternalClock = 8; // replaced local const with enum
03221     ADC_MODE_CONTROL |=   ((SCAN_1000_CustomExternalClock & SCAN_BITS) << SCAN_LSB);
03222     
03223     //----------------------------------------
03224     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
03225     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
03226     
03227     //----------------------------------------
03228     // ADC MODE CONTROL REGISTER SELECT THE CHAN_ID BIT
03229     // (applicable to external clock mode only)
03230     // For external clock modes, the data format returned depends on the CHAN_ID bit.
03231     //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
03232     //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
03233     // For internal clock modes, the data format always includes the channel address.
03234     //     misoData16 = CH[3:0] DATA[11:0]
03235     ADC_MODE_CONTROL |=   ((chan_id_0_1 & CHAN_ID_BITS) << CHAN_ID_LSB);
03236     
03237     //----------------------------------------
03238     // SPI write ADC MODE CONTROL register
03239     // Send SPI configuration to device
03240     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03241     SPIoutputCS(0); // drive CS low
03242     SPIwrite16bits(ADC_MODE_CONTROL);
03243     SPIoutputCS(1); // drive CS high
03244     
03245     //----------------------------------------
03246     // return number of words to read
03247     return NumWords;
03248 }
03249 
03250 //----------------------------------------
03251 // SCAN_1001_SampleSetExternalClock
03252 //
03253 // Measure ADC channels in an arbitrary pattern.
03254 //     Channels can be visited in any order, with repetition allowed.
03255 // External clock mode.
03256 // @pre enabledChannelsPatternLength_1_256: number of channel selections
03257 // @pre enabledChannelsPattern: array containing channel selection pattern
03258 //     In the array, one channel select per byte.
03259 //     In the SPI interface, immediately after SAMPLESET register is written,
03260 //     each byte encodes two channelNumber selections.
03261 //     The high 4 bits encode the first channelNumber.
03262 //     (((enabledChannelsPattern[0]) & 0x0F) << 4) | ((enabledChannelsPattern[1]) & 0x0F)
03263 //     If it is an odd number of channels, additional nybbles will be ignored.
03264 //     CS will be asserted low during the entire SAMPLESET pattern selection.
03265 // @param[in] enabledChannelsPattern: array of channel select, one channel per byte
03266 // @param[in] PowerManagement_0_2: 0=Normal, 1=AutoShutdown, 2=AutoStandby
03267 // @param[in] chan_id_0_1: ADC_MODE_CONTROL.CHAN_ID
03268 // @return number of ScanRead() words needed to retrieve the data.
03269 // @post NumWords = number of words to be read from the FIFO
03270 // For external clock modes, the data format depends on CHAN_ID.
03271 //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
03272 //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
03273 //
03274 int MAX11131::ScanSampleSetExternalClock(void)
03275 {
03276     
03277     //----------------------------------------
03278     // define write-only register ADC_MODE_CONTROL
03279     ADC_MODE_CONTROL = 0;       //!< mosiData16 0x0000..0x7FFF format: 0 SCAN[3:0] CHSEL[3:0] RESET[1:0] PM[1:0] CHAN_ID SWCNV 0
03280     const int SCAN_LSB    = 11; const int SCAN_BITS    = 0x0F; //!< ADC_MODE_CONTROL.SCAN[3:0] ADC Scan Control (command)
03281     const int CHSEL_LSB   =  7; const int CHSEL_BITS   = 0x0F; //!< ADC_MODE_CONTROL.CHSEL[3:0] Analog Input Channel Select AIN0..AIN15
03282     const int RESET_LSB   =  5; const int RESET_BITS   = 0x03; //!< ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
03283     const int PM_LSB      =  3; const int PM_BITS      = 0x03; //!< ADC_MODE_CONTROL.PM[1:0] Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
03284     const int CHAN_ID_LSB =  2; const int CHAN_ID_BITS = 0x01; //!< ADC_MODE_CONTROL.CHAN_ID
03285     const int SWCNV_LSB   =  1; const int SWCNV_BITS   = 0x01; //!< ADC_MODE_CONTROL.SWCNV
03286     
03287     //----------------------------------------
03288     // Apply a soft reset when changing from internal to external clock mode.
03289     int needFIFOreset = (isExternalClock != 1);
03290     if (needFIFOreset) {
03291         // Apply a soft reset when changing from internal to external clock mode.
03292         ADC_MODE_CONTROL = ((1 & RESET_BITS) << RESET_LSB); // ADC_MODE_CONTROL.RESET[1:0] Reset 0=Normal 1=ResetFIFO 2=ResetAllRegisters 3=reserved
03293         // Send SPI configuration to device
03294         SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03295         SPIoutputCS(0); // drive CS low
03296         SPIwrite16bits(ADC_MODE_CONTROL);
03297         SPIoutputCS(1); // drive CS high
03298         ADC_MODE_CONTROL = 0;
03299     }
03300     
03301     //----------------------------------------
03302     // number of words to read
03303     NumWords = ((enabledChannelsPatternLength_1_256 != 0) ? enabledChannelsPatternLength_1_256 : 256 );
03304     
03305     //----------------------------------------
03306     // External Clock Mode
03307     isExternalClock = 1;
03308     
03309     //----------------------------------------
03310     // update device driver global variable
03311     ScanMode = SCAN_1001_SampleSetExternalClock;
03312     
03313     //----------------------------------------
03314     // Initialize shadow of write-only register SAMPLESET.
03315     // Do not write to SAMPLESET at this time.
03316     // A write to SAMPLESET must be followed by specified number of pattern entry words.
03317     // See ScanSampleSetExternalClock function for details.
03318     SAMPLESET = 0xB000;         //!< mosiData16 0xB000..0xB7FF format: 1 0 1 1 0 SEQ_LENGTH[7:0] x x x
03319     const int SAMPLESET_LSB   =  3; const int SAMPLESET_BITS   = 0xFF; // SAMPLESET.SEQ_LENGTH[7:0]
03320     
03321     //----------------------------------------
03322     // SampleSet register set SEQ_DEPTH[7:0] TO SET CHANNEL CAPTURE DEPTH; FOLLOW SampleSet REGISTER WITH CHANNEL PATTERN OF THE SAME SIZE AS SEQUENCE DEPTH
03323     // NOTE: SAMPLESET.SEQ_LENGTH[7:0] is the number of channel entries in the pattern.
03324     // NOTE: Each channel entry is 4 bits. The first 4 bits are the first channel in the sequence.
03325     // NOTE: Channels can be repeated in any arbitrary order.
03326     // NOTE: The channel entry pattern is sent immediately after writing SAMPLESET.
03327     // NOTE: Keep CS low during the entire SAMPLESET pattern entry.
03328     const int seq_length_minus_one_0_255 = enabledChannelsPatternLength_1_256 - 1;
03329     SAMPLESET = 0xB000;
03330     //SAMPLESET &= ~ ((                             SAMPLESET_BITS) << SAMPLESET_LSB);
03331     SAMPLESET |=   ((seq_length_minus_one_0_255 & SAMPLESET_BITS) << SAMPLESET_LSB);
03332     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03333     SPIoutputCS(0); // drive CS low
03334     SPIwrite16bits(SAMPLESET); // SAMPLESET must be followed by several more bytes, length specified by SEQ_LENGTH[7:0]
03335     // pack enabledChannelsPattern[index] into nybbles
03336     SPIoutputCS(1); // drive CS high
03337     // NOTE: Send the sampleset pattern, with 4 entries packed into each 16-bit SPI word. Pad unused entries with 0.
03338     SPI_MOSI_Semantic = 2; // 0:Nothing 1:regWrite 2:sampleSetPattern
03339     SPIoutputCS(0); // drive CS low
03340     // NOTE: Keep CS low during the entire SAMPLESET pattern entry.
03341     int entryIndex;
03342     for (entryIndex = 0; entryIndex < enabledChannelsPatternLength_1_256; entryIndex += 4)
03343     {
03344         uint16_t pack4channels = 0;
03345         pack4channels |= (((enabledChannelsPattern[entryIndex + 0]) & 0x0F) << 12);
03346         if ((entryIndex + 1) < enabledChannelsPatternLength_1_256) {
03347             pack4channels |= (((enabledChannelsPattern[entryIndex + 1]) & 0x0F) << 8);
03348         }
03349         if ((entryIndex + 2) < enabledChannelsPatternLength_1_256) {
03350             pack4channels |= (((enabledChannelsPattern[entryIndex + 2]) & 0x0F) << 4);
03351         }
03352         if ((entryIndex + 3) < enabledChannelsPatternLength_1_256) {
03353             pack4channels |=   ((enabledChannelsPattern[entryIndex + 3]) & 0x0F);
03354         }
03355         SPIwrite16bits(pack4channels);
03356     }
03357     SPIoutputCS(1); // drive CS high
03358     
03359     //----------------------------------------
03360     // ADC MODE CONTROL register set SCAN[3:0] TO SCAN_1001_SampleSetExternalClock = 9
03361     //~ const int SCAN_1001_SampleSetExternalClock = 9; // replaced local const with enum
03362     ADC_MODE_CONTROL |=   ((SCAN_1001_SampleSetExternalClock & SCAN_BITS) << SCAN_LSB);
03363     
03364     //----------------------------------------
03365     // ADC MODE CONTROL register set CHSEL[3:0] TO channel number
03366     ADC_MODE_CONTROL |=   ((0 & CHSEL_BITS) << CHSEL_LSB);
03367     
03368     //----------------------------------------
03369     // ADC MODE CONTROL REGISTER SELECT THE PM[1:0] BITS
03370     ADC_MODE_CONTROL |=   ((PowerManagement_0_2 & PM_BITS) << PM_LSB);
03371     
03372     //----------------------------------------
03373     // ADC MODE CONTROL REGISTER SELECT THE CHAN_ID BIT
03374     // (applicable to external clock mode only)
03375     // For external clock modes, the data format returned depends on the CHAN_ID bit.
03376     //     when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
03377     //     when CHAN_ID = 1: misoData16 = CH[3:0] DATA[11:0]
03378     // For internal clock modes, the data format always includes the channel address.
03379     //     misoData16 = CH[3:0] DATA[11:0]
03380     ADC_MODE_CONTROL |=   ((chan_id_0_1 & CHAN_ID_BITS) << CHAN_ID_LSB);
03381     
03382     //----------------------------------------
03383     // SPI write ADC MODE CONTROL register
03384     // Send SPI configuration to device
03385     SPI_MOSI_Semantic = 1; // 0:Nothing 1:regWrite 2:sampleSetPattern
03386     SPIoutputCS(0); // drive CS low
03387     SPIwrite16bits(ADC_MODE_CONTROL);
03388     SPIoutputCS(1); // drive CS high
03389     
03390     //----------------------------------------
03391     // return number of words to read
03392     return NumWords;
03393 }
03394 
03395 //----------------------------------------
03396 // Example configure and perform some measurements in ScanManual mode.
03397 // @param[out] pd_mean = address for double mean (avearge)
03398 // @param[out] pd_variance = address for double variance (variance)
03399 // @param[out] pd_stddev = address for double stddev (standard deviation)
03400 // @param[out] pd_Sx = address for double Sx (sum of all X)
03401 // @param[out] pd_Sxx = address for double Sxx (sum of squares of each X)
03402 void MAX11131::Example_ScanManual(int channelNumber_0_15, int nWords, 
03403   double* pd_mean, double* pd_variance, double* pd_stddev, 
03404   double* pd_Sx, double* pd_Sxx)
03405 {
03406     
03407     //----------------------------------------
03408     // configure and perform some measurements in ScanManual mode
03409     Init();
03410     channelNumber_0_15 = channelNumber_0_15; // Analog Input Channel Select AIN0..
03411     PowerManagement_0_2 = 0; // Power Management 0=Normal, 1=AutoShutdown, 2=AutoStandby 3=reserved
03412     chan_id_0_1 = 1; // when CHAN_ID = 0: misoData16 = 0 DATA[11:0] x x x
03413     // const int nWords = 100;
03414     double Sx = 0;
03415     double Sxx = 0;
03416     int index;
03417     ScanManual();
03418     for (index = 0; index < nWords; index++)
03419     {
03420         int16_t misoData16 = ScanRead();
03421         // For internal clock modes, the data format always includes the channel address.
03422         //     misoData16 = CH[3:0] DATA[11:0]
03423         int16_t value_u12 = (misoData16 & 0x0FFF);
03424         int channelId = ((misoData16 >> 12) & 0x000F);
03425         Sx = Sx + value_u12;
03426         Sxx = Sxx + ((double)value_u12 * value_u12);
03427     }
03428     if (pd_Sx != 0) {
03429         *(pd_Sx) = Sx;
03430     }
03431     if (pd_Sxx != 0) {
03432         *(pd_Sxx) = Sxx;
03433     }
03434     if (pd_mean != 0) {
03435         *(pd_mean) = Sx / nWords;
03436     }
03437     if (nWords >= 2)
03438     {
03439         if (pd_variance != 0) {
03440             // TODO1: is this variance calculation too naive to work reliably?
03441             // see https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
03442             *(pd_variance) = (Sxx - ( Sx * Sx / nWords) ) / (nWords - 1);
03443         }
03444         if (pd_stddev != 0) {
03445             extern double sqrt(double);
03446             *(pd_stddev) = sqrt( *(pd_variance) );
03447         }
03448     }
03449 }
03450 
03451 
03452 // End of file