Library for the MAX31856 Precision Thermocouple to Digital Converter with Linearization

Dependents:   MAX31856_example_program

Fork of MAX31856 by Central Applications - Mbed Code repo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX31856.cpp Source File

MAX31856.cpp

Go to the documentation of this file.
00001 /******************************************************************//**
00002 * @file MAX31856.cpp
00003 *
00004 * @author Devin Alexander
00005 *
00006 * @version 1.0
00007 *
00008 * Started: SEPTEMBER 14th 2017
00009 *
00010 * Updated: 
00011 *
00012 * @brief Source file for MAX3185 class
00013 *
00014 ***********************************************************************
00015 *
00016 * @copyright 
00017 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
00018 *
00019 * Permission is hereby granted, free of charge, to any person obtaining a
00020 * copy of this software and associated documentation files (the "Software"),
00021 * to deal in the Software without restriction, including without limitation
00022 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00023 * and/or sell copies of the Software, and to permit persons to whom the
00024 * Software is furnished to do so, subject to the following conditions:
00025 *
00026 * The above copyright notice and this permission notice shall be included
00027 * in all copies or substantial portions of the Software.
00028 *
00029 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00030 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00031 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00032 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00033 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00034 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00035 * OTHER DEALINGS IN THE SOFTWARE.
00036 *
00037 * Except as contained in this notice, the name of Maxim Integrated
00038 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00039 * Products, Inc. Branding Policy.
00040 *
00041 * The mere transfer of this software does not imply any licenses
00042 * of trade secrets, proprietary technology, copyrights, patents,
00043 * trademarks, maskwork rights, or any other form of intellectual
00044 * property whatsoever. Maxim Integrated Products, Inc. retains all
00045 * ownership rights.
00046 **********************************************************************/
00047 
00048 #include <mbed.h>
00049 #include "MAX31856.h"
00050 
00051 #define LOG(args...)    printf(args)
00052 
00053 //*****************************************************************************
00054 MAX31856::MAX31856(SPI& _spi, PinName _ncs, uint8_t _type, uint8_t _fltr, uint8_t _samples, uint8_t _conversion_mode) : spi(_spi), ncs(_ncs), samples(_samples) {  
00055     spi.format(8,3); //configure the correct SPI mode to beable to program the registers intially correctly
00056     setThermocoupleType(_type);
00057     setEmiFilterFreq(_fltr);
00058     setNumSamplesAvg(_samples);
00059     setConversionMode(_conversion_mode);
00060 }
00061 
00062 
00063 //*****************************************************************************
00064 float MAX31856::readTC()
00065 {    
00066     //Check and see if the MAX31856 is set to conversion mode ALWAYS ON
00067     if (conversion_mode==0) {   //means that the conversion mode is normally off
00068         setOneShotMode(CR0_1_SHOT_MODE_ONE_CONVERSION); // turn on the one shot mode for singular conversion
00069         thermocouple_conversion_count=0; //reset the conversion count back to zero to make sure minimum conversion time reflects one shot mode requirements
00070     }
00071     
00072     //calculate minimum wait time for conversions
00073     calculateDelayTime();
00074     
00075     //initialize other info for the read functionality
00076     int32_t temp;
00077     uint8_t buf_read[3], buf_write[3]={ADDRESS_LTCBH_READ,ADDRESS_LTCBM_READ,ADDRESS_LTCBL_READ};
00078     
00079     bool read_thermocouple_temp=checkFaultsThermocoupleConnection(); //check and see if there are any faults that prohibit a normal read of the register
00080     
00081     if(read_thermocouple_temp){ //no faults with connection are present so continue on with normal read of temperature
00082         uint32_t time = us_ticker_read();
00083         uint32_t duration = time - lastReadTime;
00084         if (duration > conversion_time) {   // more than current conversion time
00085             for(int i=0; i<3; i++) {
00086                 spiEnable();
00087                 buf_read[i]=spi.write(buf_write[i]);
00088                 buf_read[i]=spi.write(buf_write[i]);
00089                 spiDisable();
00090             }   
00091             
00092             //Convert the registers contents into the correct value
00093             temp =((buf_read[0] & 0xFF) << 11);       //Shift Byte 2 into place
00094             temp|=((buf_read[1] & 0xFF) << 3);        //Shift Byte 1 into place
00095             temp|=((buf_read[2] & 0xFF) >> 5);        //Shift Byte 0 into place
00096             float val=(temp/128.0f);                  //Divide the binary string by 2 to the 7th power
00097             return val;
00098         }
00099     }
00100     thermocouple_conversion_count++; //iterate the conversion count to speed up time in between future converions in always on mode
00101     
00102     checkFaultsThermocoupleThresholds();  //print any faults to the terminal
00103     return 0;
00104 }
00105 
00106 
00107 //*****************************************************************************
00108 float MAX31856::readCJ()
00109 {
00110     int32_t temp;
00111     uint8_t buf_read[3], buf_write=ADDRESS_CJTH_READ;
00112     
00113     spiEnable();
00114     for(int i=0; i<3; i++)
00115     {
00116         buf_read[i]=spi.write(buf_write);
00117     }
00118     spiDisable();
00119     
00120     //Convert the registers contents into the correct value
00121     temp =((int32_t)(buf_read[1] << 6));        //Shift the MSB into place
00122     temp|=((int32_t)(buf_read[2] >> 2));        //Shift the LSB into place
00123     float val=((float)(temp/64.0));             //Divide the binary string by 2 to the 6th power
00124     
00125     checkFaultsColdJunctionThresholds(); //print any faults to the terminal
00126     
00127     return val;
00128 }
00129 
00130 //*****************************************************************************
00131 uint8_t MAX31856::checkFaultsThermocoupleThresholds()
00132 {  
00133     uint8_t fault_byte=registerReadByte(ADDRESS_SR_READ); //Read contents of fault status register
00134     uint8_t temp[2], return_int;
00135     for(int i=0; i<2; i++)
00136         temp[i]=fault_byte;
00137     
00138     //Check if any of the faults for thermocouple connection are triggered
00139     if      ((fault_byte&0x4C)==0) //means no fault is detected for thermocouple thresholds
00140         return_int=0;
00141     else {
00142         if ((fault_byte&0x40)==0) {   //check if normal operation of thermocouple is true
00143             if      (temp[0]&0x08) {
00144                 LOG("FAULT! Thermocouple temp is higher than the threshold that is set!\r\n");
00145                 return_int=1;
00146             }
00147             else if (temp[1]&0x04) {
00148                 LOG("FAULT! Thermocouple temp is lower than the threshold that is set!\r\n");
00149                 return_int=2;
00150             }
00151         }
00152         else {                      //Thermocouples is operating outside of normal range
00153             LOG("FAULT! Thermocouple temperature is out of range for specific type of thermocouple!\r\n");
00154             if      (temp[0]&0x08) {
00155                 LOG("FAULT! Thermocouple temp is higher than the threshold that is set!\r\n");
00156                 return_int=4;
00157             }
00158             else if (temp[1]&0x04) {
00159                 LOG("FAULT! Thermocouple temp is lower than the threshold that is set!\r\n");
00160                 return_int=5;
00161             }
00162             else                    //no other faults are flagged besides unnatural operation
00163                 return_int=3; 
00164         }
00165     }
00166     return return_int;
00167 }
00168 
00169 //*****************************************************************************
00170 uint8_t MAX31856::checkFaultsColdJunctionThresholds()
00171 {  
00172     uint8_t fault_byte=registerReadByte(ADDRESS_SR_READ); //Read contents of fault status register
00173     uint8_t temp[2], return_int;
00174     for(int i=0; i<2; i++)
00175         temp[i]=fault_byte;
00176     
00177     //Check if any of the faults for thermocouple connection are triggered
00178     if      ((fault_byte&0xB0)==0)  //means no fault is detected for cold junction thresholds
00179         return_int=0;
00180     else {
00181         if ((fault_byte&0x80)==0) {   //check if normal operation of cold junction is true
00182             if      (temp[0]&0x20) {
00183                 LOG("FAULT! Cold Junction temp is higher than the threshold that is set!\r\n");
00184                 return_int=1;
00185             }
00186             else if (temp[1]&0x10) {
00187                 LOG("FAULT! Cold Junction temp is lower than the threshold that is set!\r\n");
00188                 return_int=2;
00189             }
00190         }
00191         else {                      //Cold Junction is operating outside of normal range
00192             LOG("FAULT! Cold Junction temperature is out of range for specific type of thermocouple!\r\n");
00193             if      (temp[0]&0x20) {
00194                 LOG("FAULT! Cold Junction temp is higher than the threshold that is set!\r\n");
00195                 return_int=4;
00196             }
00197             else if (temp[1]&0x10) {
00198                 LOG("FAULT! Cold Junction temp is lower than the threshold that is set!\r\n");
00199                 return_int=5;
00200             }
00201             else                    //no other faults are flagged besides unnatural operation
00202                 return_int=3;
00203         }
00204     }
00205     return return_int;
00206 }
00207 
00208 //*****************************************************************************
00209 bool MAX31856::checkFaultsThermocoupleConnection()
00210 {
00211     uint8_t fault_byte=registerReadByte(ADDRESS_SR_READ); //Read contents of fault status register
00212     uint8_t temp[2];
00213     for(int i=0; i<2; i++)
00214         temp[i]=fault_byte;
00215     
00216     //Check if any of the faults for thermocouple connection are triggered
00217     if (fault_byte==0) //means no fault is detected
00218         return_val=1;
00219     else{    
00220         if (temp[0]&0x02) {
00221             LOG("Overvotage/Undervoltage Fault triggered! Input voltage is negative or the voltage is greater than Vdd! Please check thermocouple connection!\r\n");
00222             return_val=0;
00223         }
00224         if (temp[1]&0x01) {
00225             LOG("Open circuit fault detected! Please check thermocouple connection!\r\n");
00226             return_val=0;
00227         }
00228     }
00229     return return_val;
00230 }
00231 
00232 
00233 //Register:CR0    Bits: 7
00234 //*****************************************************************************
00235 bool MAX31856::setConversionMode(uint8_t val) 
00236 {
00237     if      (val==CR0_CONV_MODE_NORMALLY_OFF) {
00238         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_7, val);
00239         conversion_mode=0;
00240         LOG("Register containing\t\tsetConversionMode\t\twas programmed with the parameter\t\tCR0_CONV_MODE_NORMALLY_OFF\r\n");
00241     } 
00242     else if (val==CR0_CONV_MODE_NORMALLY_ON) {
00243         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_7, val);
00244         conversion_mode=1;
00245         LOG("Register containing\t\tsetConversionMode\t\twas programmed with the parameter\t\tCR0_CONV_MODE_NORMALLY_ON\r\n");
00246     }
00247     else {
00248         LOG("Incorrect parameter selected for Control Register 0 (CR0) bit 7. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00249         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00250     }
00251     return return_val;
00252 }
00253 
00254 
00255 //Register:CR0    Bits: 6
00256 //*****************************************************************************
00257 bool MAX31856::setOneShotMode(uint8_t val) 
00258 {
00259     if      (val==CR0_1_SHOT_MODE_NO_CONVERSION) 
00260         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_6, val);
00261     else if (val==CR0_1_SHOT_MODE_ONE_CONVERSION)
00262         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_6, val);
00263     else {
00264         LOG("Incorrect parameter selected for Control Register 0 (CR0) bit 6. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00265         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00266     }
00267     return return_val;
00268 }
00269 
00270 
00271 //Register:CR0    Bits: 5:4
00272 //*****************************************************************************
00273 bool MAX31856::setOpenCircuitFaultDetection(uint8_t val) 
00274 {
00275     if      (val==CR0_OC_DETECT_DISABLED) { 
00276         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_5_4, val);
00277         LOG("Register containing\t\tsetOpenCircuitFaultDetection\t\twas programmed with the parameter\t\tCR0_OC_DETECT_DISABLED\r\n");
00278     }
00279     else if (val==CR0_OC_DETECT_ENABLED_R_LESS_5k) {  
00280         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_5_4, val);
00281         LOG("Register containing\t\tsetOpenCircuitFaultDetection\t\twas programmed with the parameter\t\tCR0_OC_DETECT_ENABLED_R_LESS_5k\r\n");
00282     }
00283     else if (val==CR0_OC_DETECT_ENABLED_TC_LESS_2ms) {
00284         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_5_4, val);
00285         LOG("Register containing\t\tsetOpenCircuitFaultDetection\t\twas programmed with the parameter\t\tCR0_OC_DETECT_ENABLED_TC_LESS_2ms\r\n");
00286     }
00287     else if (val==CR0_OC_DETECT_ENABLED_TC_MORE_2ms) { 
00288         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_5_4, val);
00289         LOG("Register containing\t\tsetOpenCircuitFaultDetection\t\twas programmed with the parameter\t\tCR0_OC_DETECT_ENABLED_TC_MORE_2ms\r\n");
00290     }
00291     else {
00292         LOG("Incorrect parameter selected for Control Register 0 (CR0) bits 5:4. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00293         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00294     }
00295     return return_val;
00296 }
00297 
00298 
00299 //Register:CR0    Bits: 3
00300 //*****************************************************************************
00301 bool MAX31856::setColdJunctionDisable(uint8_t val) 
00302 {
00303     if (val==CR0_COLD_JUNC_ENABLE) { 
00304         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_3, val);
00305         cold_junction_enabled=1;
00306         LOG("Register containing\t\tsetColdJunctionDisable\t\twas programmed with the parameter\t\tCR0_COLD_JUNC_ENABLE\r\n");
00307     }
00308     else if (val==CR0_COLD_JUNC_DISABLE) {
00309         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_3, val);
00310         cold_junction_enabled=0;
00311         LOG("Register containing\t\tsetColdJunctionDisable\t\twas programmed with the parameter\t\tCR0_COLD_JUNC_DISABLE\r\n");
00312     }
00313     else {
00314         LOG("Incorrect parameter selected for Control Register 0 (CR0) bit 3. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00315         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00316     }
00317     return return_val;
00318 }
00319 
00320 
00321 //Register:CR0    Bits: 2
00322 //*****************************************************************************
00323 bool MAX31856::setFaultMode(uint8_t val) 
00324 {
00325     if      (val==CR0_FAULT_MODE_COMPARATOR) {
00326         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_2, val);
00327         LOG("Register containing\t\tsetFaultMode\t\twas programmed with the parameter\t\tCR0_FAULT_MODE_COMPARATOR\r\n");
00328     }
00329     else if (val==CR0_FAULT_MODE_INTERUPT) {
00330         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_2, val);
00331         LOG("Register containing\t\tsetFaultMode\t\twas programmed with the parameter\t\tCR0_FAULT_MODE_INTERUPT\r\n");
00332     }
00333     else {
00334         LOG("Incorrect parameter selected for Control Register 0 (CR0) bit 2. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00335         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00336     }
00337     return return_val;
00338 }
00339 
00340 
00341 //Register:CR0    Bits: 1
00342 //*****************************************************************************
00343 bool MAX31856::setFaultStatusClear(uint8_t val) 
00344 {
00345     if      (val==CR0_FAULTCLR_DEFAULT_VAL) { 
00346         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_1, val);
00347         LOG("Register containing\t\tsetFaultStatusClear\t\twas programmed with the parameter\t\tCR0_FAULTCLR_DEFAULT_VAL\r\n");
00348     }
00349     else if (val==CR0_FAULTCLR_RETURN_FAULTS_TO_ZERO) { 
00350         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_1, val);
00351         LOG("Register containing\t\tsetFaultStatusClear\t\twas programmed with the parameter\t\tCR0_FAULTCLR_RETURN_FAULTS_TO_ZERO\r\n");
00352     }
00353     else {
00354         LOG("Incorrect parameter selected for Control Register 0 (CR0) bit 1. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00355         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00356     }
00357     return return_val;
00358 }
00359 
00360 
00361 //Register:CR0    Bits: 0
00362 //*****************************************************************************
00363 bool MAX31856::setEmiFilterFreq(uint8_t val) 
00364 {
00365     if      (val==CR0_FILTER_OUT_60Hz) {
00366         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_0, val);
00367         filter_mode=0;
00368         LOG("Register containing\t\tsetEmiFilterFreq\t\twas programmed with the parameter\t\tCR0_FILTER_OUT_60Hz\r\n");
00369     }
00370     else if (val==CR0_FILTER_OUT_50Hz) {
00371         return_val=registerReadWriteByte(ADDRESS_CR0_READ, ADDRESS_CR0_WRITE, CR0_CLEAR_BITS_0, val);
00372         filter_mode=1;
00373         LOG("Register containing\t\tsetEmiFilterFreq\t\twas programmed with the parameter\t\tCR0_FILTER_OUT_50Hz\r\n");
00374     }
00375     else {
00376         LOG("Incorrect parameter selected for Control Register 0 (CR0) bit 0. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00377         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00378     }
00379     return return_val;
00380 }
00381 
00382 
00383 //Register:CR1    Bits: 6:4
00384 //*****************************************************************************
00385 bool MAX31856::setNumSamplesAvg(uint8_t val) 
00386 {   
00387     if      (val==CR1_AVG_TC_SAMPLES_1) {
00388         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_6_4, val);
00389         samples=1;
00390         LOG("Register containing\t\tsetNumSamplesAvg\t\twas programmed with the parameter\t\tCR1_AVG_TC_SAMPLES_1\r\n");
00391     }
00392     else if (val==CR1_AVG_TC_SAMPLES_2) {
00393         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_6_4, val);
00394         samples=2;
00395         LOG("Register containing\t\tsetNumSamplesAvg\t\twas programmed with the parameter\t\tCR1_AVG_TC_SAMPLES_2\r\n");
00396     }
00397     else if (val==CR1_AVG_TC_SAMPLES_4) {
00398         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_6_4, val);
00399         samples=4;
00400         LOG("Register containing\t\tsetNumSamplesAvg\t\twas programmed with the parameter\t\tCR1_AVG_TC_SAMPLES_4\r\n");
00401     }
00402     else if (val==CR1_AVG_TC_SAMPLES_8) {
00403         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_6_4, val);
00404         samples=8;
00405         LOG("Register containing\t\tsetNumSamplesAvg\t\twas programmed with the parameter\t\tCR1_AVG_TC_SAMPLES_8\r\n");
00406     }
00407     else if (val==CR1_AVG_TC_SAMPLES_16) {
00408         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_6_4, val);
00409         samples=16;
00410         LOG("Register containing\t\tsetNumSamplesAvg\t\twas programmed with the parameter\t\tCR1_AVG_TC_SAMPLES_16\r\n");
00411     }
00412     else {
00413         LOG("Incorrect parameter selected for Control Register 1 (CR1) bits 6:4. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00414         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00415     }
00416     return return_val;
00417 }
00418 
00419 
00420 //Register:CR1    Bits: 3:0
00421 //*****************************************************************************
00422 bool MAX31856::setThermocoupleType(uint8_t val) 
00423 {   
00424     if      (val==CR1_TC_TYPE_B) {
00425         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00426         voltage_mode=false;
00427         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_B\r\n");
00428     }
00429     else if (val==CR1_TC_TYPE_E) {
00430         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00431         voltage_mode=false;
00432         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_E\r\n");
00433     }
00434     else if (val==CR1_TC_TYPE_J) {
00435         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00436         voltage_mode=false;
00437         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_J\r\n");
00438     }
00439     else if (val==CR1_TC_TYPE_K) {
00440         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00441         voltage_mode=false;
00442         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_K\r\n");
00443     }
00444     else if (val==CR1_TC_TYPE_N) {
00445         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00446         voltage_mode=false;
00447         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_N\r\n");
00448     }
00449     else if (val==CR1_TC_TYPE_R) {
00450         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00451         voltage_mode=false;
00452         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_R\r\n");
00453     }
00454     else if (val==CR1_TC_TYPE_S) {
00455         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00456         voltage_mode=false;
00457         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_S\r\n");
00458     }
00459     else if (val==CR1_TC_TYPE_T) {
00460         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00461         voltage_mode=false;
00462         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_T\r\n");
00463     }
00464     else if (val==CR1_TC_TYPE_VOLT_MODE_GAIN_8) {
00465         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00466         voltage_mode=true;
00467         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_VOLT_MODE_GAIN_8\r\n");
00468     }
00469     else if (val==CR1_TC_TYPE_VOLT_MODE_GAIN_32) {
00470         return_val=registerReadWriteByte(ADDRESS_CR1_READ, ADDRESS_CR1_WRITE, CR1_CLEAR_BITS_3_0, val);
00471         voltage_mode=true;
00472         LOG("Register containing\t\tsetThermocoupleType\t\twas programmed with the parameter\t\tCR1_TC_TYPE_VOLT_MODE_GAIN_32\r\n");
00473     }
00474     else {
00475         LOG("Incorrect parameter selected for Control Register 1 (CR1) bits 3:0. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00476         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00477     }
00478     return return_val;
00479 }
00480 
00481 
00482 //Register:MASK    Bits: 5:0
00483 //*****************************************************************************
00484 bool MAX31856::setFaultMasks(uint8_t val, bool enable) 
00485 {
00486     if(enable)
00487         val=0;
00488     if      (val==MASK_CJ_FAULT_THRESHOLD_HIGH) {          //Cold Junction High Threshold Fault Mask
00489         return_val=registerReadWriteByte(ADDRESS_MASK_READ, ADDRESS_MASK_WRITE, MASK_CLEAR_BITS_5, val);
00490         LOG("Register containing\t\tsetFaultMasks\t\twas programmed with the parameter\t\tMASK_CJ_FAULT_THRESHOLD_HIGH\r\n");
00491     }
00492     else if (val==MASK_CJ_FAULT_THRESHOLD_LOW) {           //Cold Junction Low  Threshold Fault Mask
00493         return_val=registerReadWriteByte(ADDRESS_MASK_READ, ADDRESS_MASK_WRITE, MASK_CLEAR_BITS_4, val);
00494         LOG("Register containing\t\tsetFaultMasks\t\twas programmed with the parameter\t\tMASK_CJ_FAULT_THRESHOLD_LOW\r\n");
00495     }
00496     else if (val==MASK_TC_FAULT_THRESHOLD_HIGH) {          //Thermocouple High Threshold Fault Mask
00497         return_val=registerReadWriteByte(ADDRESS_MASK_READ, ADDRESS_MASK_WRITE, MASK_CLEAR_BITS_3, val);
00498         LOG("Register containing\t\tsetFaultMasks\t\twas programmed with the parameter\t\tMASK_TC_FAULT_THRESHOLD_HIGH\r\n");
00499     }
00500     else if (val==MASK_TC_FAULT_THRESHOLD_LOW) {           //Thermocouple Low  Threshold Fault Mask
00501         return_val=registerReadWriteByte(ADDRESS_MASK_READ, ADDRESS_MASK_WRITE, MASK_CLEAR_BITS_2, val);
00502         LOG("Register containing\t\tsetFaultMasks\t\twas programmed with the parameter\t\tMASK_TC_FAULT_THRESHOLD_LOW\r\n");
00503     }
00504     else if (val==MASK_OVER_UNDER_VOLT_FAULT) {            //Over-Voltage/Under-Voltage Input Fault Mask
00505         return_val=registerReadWriteByte(ADDRESS_MASK_READ, ADDRESS_MASK_WRITE, MASK_CLEAR_BITS_1, val);
00506         LOG("Register containing\t\tsetFaultMasks\t\twas programmed with the parameter\t\tMASK_OVER_UNDER_VOLT_FAULT\r\n");
00507     }
00508     else if (val==MASK_OPEN_CIRCUIT_FAULT) {               //Thermocouple Open-Circuit Fault Mask
00509         return_val=registerReadWriteByte(ADDRESS_MASK_READ, ADDRESS_MASK_WRITE, MASK_CLEAR_BITS_0, val);
00510         LOG("Register containing\t\tsetFaultMasks\t\twas programmed with the parameter\t\tMASK_OPEN_CIRCUIT_FAULT\r\n");
00511     }
00512     else {
00513         LOG("Incorrect parameter selected for Mask Register bits 5:0. Default value not changed.\r\nPlease see MAX31856.h for list of valid parameters. \r\n"); 
00514         return_val=0; //returns a 0 to flag that the parameter wasn't programmed due to wrong parameter in function call
00515     }
00516     return return_val;
00517 }
00518 
00519 
00520 //Register:MASK    Bits: 5:0
00521 //******************************************************************************
00522 bool MAX31856::setFaultThresholds(uint8_t val, float temperature) 
00523 {
00524     if      (val==MASK_CJ_FAULT_THRESHOLD_HIGH) {          //Cold Junction High Threshold Fault Mask
00525         int8_t temperature_byte=temperature;
00526         return_val=registerWriteByte(ADDRESS_CJHF_WRITE, temperature_byte);
00527     }
00528     else if (val==MASK_CJ_FAULT_THRESHOLD_LOW) {           //Cold Junction Low  Threshold Fault Mask
00529         int8_t temperature_byte=temperature;
00530         return_val=registerWriteByte(ADDRESS_CJLF_WRITE, temperature_byte);
00531     }
00532     else if (val==MASK_TC_FAULT_THRESHOLD_HIGH) {          //Thermocouple High Threshold Fault Mask
00533         int8_t temperature_byte[2];
00534         int16_t temperature_multi_byte =temperature*4.0;
00535         //now split up the 16bit int into two bytes to program the registers with
00536         temperature_byte[0]=((uint8_t)((temperature_multi_byte)&(0xFF00) >> 8));
00537         temperature_byte[1]=((uint8_t)((temperature_multi_byte)&(0x00FF)));
00538         
00539         return_val=registerWriteByte(ADDRESS_LTHFTH_WRITE, temperature_byte[0]);
00540         return_val=registerWriteByte(ADDRESS_LTHFTL_WRITE, temperature_byte[1]);
00541     }
00542     else if (val==MASK_TC_FAULT_THRESHOLD_LOW) {          //Thermocouple LOW Threshold Fault Mask
00543         int8_t temperature_byte[2];
00544         int16_t temperature_multi_byte =temperature*4.0;
00545         //now split up the 16bit int into two bytes to program the registers with
00546         temperature_byte[0]=((uint8_t)((temperature_multi_byte)&(0xFF00) >> 8));
00547         temperature_byte[1]=((uint8_t)((temperature_multi_byte)&(0x00FF)));
00548         
00549         return_val=registerWriteByte(ADDRESS_LTHFTH_WRITE, temperature_byte[0]);
00550         return_val=registerWriteByte(ADDRESS_LTHFTL_WRITE, temperature_byte[1]);
00551     }
00552     else 
00553         LOG("Please select correct threshold register to program with the correct value!\r\n");
00554     return return_val;
00555 }
00556 
00557 //******************************************************************************
00558 bool MAX31856::coldJunctionOffset(float temperature)
00559 {
00560     if (temperature > 7.9375 || temperature < -8.0) {
00561         LOG("Input value to offest the cold junction point is non valid. enter in value in range -8 to +7.9375\r\n");
00562         return_val = 0;
00563     }
00564     int8_t temp_val=temperature*16.0f; //normalize the value to get rid of decimal and shorten it to size of register
00565     return_val=registerWriteByte(ADDRESS_CJTO_WRITE, temp_val); //write the byte to cold junction offset register
00566     return return_val;
00567 }
00568 
00569 
00570 //The following functions are for internal library use only
00571 //******************************************************************************
00572 void MAX31856::spiEnable() 
00573 {
00574     ncs=0; //Set CS low to start transmission (interrupts conversion)
00575     return;
00576 }
00577 
00578 
00579 //******************************************************************************
00580 void MAX31856::spiDisable() 
00581 {
00582     ncs=1; //Set CS high to stop transmission (restarts conversion)
00583     return;
00584 }
00585 
00586 
00587 //******************************************************************************
00588 bool MAX31856::registerReadWriteByte(uint8_t read_address, uint8_t write_address, int clear_bits, uint8_t val) 
00589 {   
00590     uint8_t buf_read[2];
00591     
00592     //Read the current contents of a register
00593     spiEnable();
00594     for(int i=0; i<2; i++) {
00595         buf_read[i]=spi.write(read_address);
00596     }
00597     spiDisable();
00598     
00599     //Modify contents pulled from the register 
00600     buf_read[1]&=clear_bits;    //Clear the contents of bits of parameter you are trying to clear for later or equal operation
00601     buf_read[1]|=val;       //Bitwise OR the input parameter with cleaned buf_read[1] to create new byte
00602     val=buf_read[1];
00603     
00604     //Write the updated byte to the register 
00605     spiEnable();
00606     buf_read[0]=spi.write(write_address);
00607     buf_read[1]=spi.write(val);
00608     spiDisable();
00609     return 1;
00610 }
00611 
00612 
00613 //******************************************************************************
00614 bool MAX31856::registerWriteByte(uint8_t write_address, uint8_t val) 
00615 {   
00616     //Write the updated byte to the register 
00617     spiEnable();
00618     spi.write(write_address);
00619     spi.write(val);
00620     spiDisable();
00621     return true;
00622 }
00623 
00624 //******************************************************************************
00625 uint8_t MAX31856::registerReadByte(uint8_t read_address) 
00626 {
00627     uint8_t buf_read, buf_write=read_address;
00628     spiEnable();
00629     buf_read=spi.write(buf_write);
00630     buf_read=spi.write(buf_write);
00631     spiDisable();
00632     return buf_read;
00633 }
00634 
00635 //******************************************************************************
00636 void MAX31856::calculateDelayTime() {
00637     uint32_t temp_int;
00638     
00639     if      (conversion_mode==0 || thermocouple_conversion_count==0) {
00640         if (filter_mode==0)  //60Hz
00641             temp_int=82+(samples-1)*33.33f;
00642         else                 //50Hz
00643             temp_int=98+(samples-1)*40.00f;
00644     }
00645     else  { 
00646         if (filter_mode==0)  //60Hz
00647             temp_int=82+(samples-1)*16.67f;
00648         else                //50Hz
00649             temp_int=98+(samples-1)*20.00f;
00650     }
00651     
00652     if (cold_junction_enabled==0) //cold junction is disabled enabling 25 millisecond faster conversion times
00653         temp_int=temp_int-25;
00654     conversion_time=1000*temp_int; //set private member conversion time to calculated minimum wait time in microseconds
00655     return;
00656 }
00657 
00658 //*****************************************************************************
00659 MAX31856::~MAX31856(void) 
00660 {
00661   //empty block
00662 }
00663