Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MAX11410BOB_24bit_ADC MAX11410BOB_Serial_Tester
MAX11410.cpp
00001 // /******************************************************************************* 00002 // * Copyright (C) 2020 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 MAX11410.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 "MAX11410.h" 00043 00044 // Device Name = MAX11410 00045 // Device Description = 1.9ksps, Low-Power, Serial SPI 24-Bit, 10-Channel, Differential/Single-Ended Input, SAR ADC 00046 // Device DeviceBriefDescription = 24-bit 1.9ksps Delta-Sigma ADC 00047 // Device Manufacturer = Maxim Integrated 00048 // Device PartNumber = MAX11410ATI+ 00049 // Device RegValue_Width = DataWidth16bit_HL 00050 // 00051 // ADC MaxOutputDataRate = 1.9ksps 00052 // ADC NumChannels = 10 00053 // ADC ResolutionBits = 24 00054 // 00055 // SPI CS = ActiveLow 00056 // SPI FrameStart = CS 00057 // SPI CPOL = 0 00058 // SPI CPHA = 0 00059 // SPI MOSI and MISO Data are both stable on Rising edge of SCLK 00060 // SPI SCLK Idle Low 00061 // SPI SCLKMaxMHz = 8 00062 // SPI SCLKMinMHz = 0 00063 // 00064 00065 // CODE GENERATOR: class constructor definition 00066 MAX11410::MAX11410(SPI &spi, DigitalOut &cs_pin, // SPI interface 00067 // CODE GENERATOR: class constructor definition gpio InputPin pins 00068 // CODE GENERATOR: class constructor definition gpio OutputPin pins 00069 // CODE GENERATOR: class constructor definition ic_variant 00070 MAX11410_ic_t ic_variant) 00071 // CODE GENERATOR: class constructor initializer list 00072 : m_spi(spi), m_cs_pin(cs_pin), // SPI interface 00073 // CODE GENERATOR: class constructor initializer list gpio InputPin pins 00074 // CODE GENERATOR: class constructor initializer list gpio OutputPin pins 00075 // CODE GENERATOR: class constructor initializer list ic_variant 00076 m_ic_variant(ic_variant) 00077 { 00078 // CODE GENERATOR: class constructor definition SPI interface initialization 00079 // 00080 // SPI CS = ActiveLow 00081 // SPI FrameStart = CS 00082 m_SPI_cs_state = 1; 00083 if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected 00084 m_cs_pin = m_SPI_cs_state; 00085 } 00086 00087 // SPI CPOL = 0 00088 // SPI CPHA = 0 00089 // SPI MOSI and MISO Data are both stable on Rising edge of SCLK 00090 // SPI SCLK Idle Low 00091 m_SPI_dataMode = 0; //SPI_MODE0; // CPOL=0,CPHA=0: Rising Edge stable; SCLK idle Low 00092 m_spi.format(8,m_SPI_dataMode); // int bits_must_be_8, int mode=0_3 CPOL=0,CPHA=0 00093 00094 // SPI SCLKMaxMHz = 8 00095 // SPI SCLKMinMHz = 0 00096 //#define SPI_SCLK_Hz 48000000 // 48MHz 00097 //#define SPI_SCLK_Hz 24000000 // 24MHz 00098 //#define SPI_SCLK_Hz 12000000 // 12MHz 00099 //#define SPI_SCLK_Hz 6000000 // 6MHz 00100 //#define SPI_SCLK_Hz 4000000 // 4MHz 00101 //#define SPI_SCLK_Hz 2000000 // 2MHz 00102 //#define SPI_SCLK_Hz 1000000 // 1MHz 00103 m_SPI_SCLK_Hz = 8000000; // 8MHz; MAX11410 limit is 8MHz 00104 m_spi.frequency(m_SPI_SCLK_Hz); 00105 00106 } 00107 00108 // CODE GENERATOR: class destructor definition 00109 MAX11410::~MAX11410() 00110 { 00111 // do nothing 00112 } 00113 00114 // CODE GENERATOR: spi_frequency setter definition 00115 /// set SPI SCLK frequency 00116 void MAX11410::spi_frequency(int spi_sclk_Hz) 00117 { 00118 m_SPI_SCLK_Hz = spi_sclk_Hz; 00119 m_spi.frequency(m_SPI_SCLK_Hz); 00120 } 00121 00122 // CODE GENERATOR: omit global g_MAX11410_device 00123 // CODE GENERATOR: extern function declarations 00124 // CODE GENERATOR: extern function requirement MAX11410::SPIoutputCS 00125 // Assert SPI Chip Select 00126 // SPI chip-select for MAX11410 00127 // 00128 inline void MAX11410::SPIoutputCS(int isLogicHigh) 00129 { 00130 // CODE GENERATOR: extern function definition for function SPIoutputCS 00131 // CODE GENERATOR: extern function definition for standard SPI interface function SPIoutputCS(int isLogicHigh) 00132 m_SPI_cs_state = isLogicHigh; 00133 if (m_cs_pin.is_connected()) { // avoid mbed runtime error if pin is NC not connected 00134 m_cs_pin = m_SPI_cs_state; 00135 } 00136 } 00137 00138 // CODE GENERATOR: extern function requirement MAX11410::SPIwrite16bits 00139 // SPI write 16 bits 00140 // SPI interface to MAX11410 shift 16 bits mosiData into MAX11410 DIN 00141 // 00142 void MAX11410::SPIwrite16bits(int16_t mosiData16) 00143 { 00144 // CODE GENERATOR: extern function definition for function SPIwrite16bits 00145 // TODO1: CODE GENERATOR: extern function definition for standard SPI interface function SPIwrite16bits(int16_t mosiData16) 00146 size_t byteCount = 2; 00147 static char mosiData[2]; 00148 static char misoData[2]; 00149 mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte 00150 mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte 00151 // 00152 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00153 //~ noInterrupts(); 00154 // 00155 //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin 00156 // 00157 unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount); 00158 //~ m_spi.transfer(mosiData8_FF0000); 00159 //~ m_spi.transfer(mosiData16_00FF00); 00160 //~ m_spi.transfer(mosiData16_0000FF); 00161 // 00162 //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin 00163 // 00164 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00165 //~ interrupts(); 00166 // Optional Diagnostic function to print SPI transactions 00167 if (onSPIprint) 00168 { 00169 onSPIprint(byteCount, (uint8_t*)mosiData, (uint8_t*)misoData); 00170 } 00171 // 00172 // VERIFY: SPIwrite24bits print diagnostic information 00173 //cmdLine.serial().printf(" MOSI->")); 00174 //cmdLine.serial().printf(" 0x")); 00175 //Serial.print( (mosiData8_FF0000 & 0xFF), HEX); 00176 //cmdLine.serial().printf(" 0x")); 00177 //Serial.print( (mosiData16_00FF00 & 0xFF), HEX); 00178 //cmdLine.serial().printf(" 0x")); 00179 //Serial.print( (mosiData16_0000FF & 0xFF), HEX); 00180 // hex dump mosiData[0..byteCount-1] 00181 #if 0 // HAS_MICROUSBSERIAL 00182 cmdLine_microUSBserial.serial().printf("\r\nSPI"); 00183 if (byteCount > 7) { 00184 cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount); 00185 } 00186 cmdLine_microUSBserial.serial().printf(" MOSI->"); 00187 for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) 00188 { 00189 cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); 00190 } 00191 // hex dump misoData[0..byteCount-1] 00192 cmdLine_microUSBserial.serial().printf(" MISO<-"); 00193 for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) 00194 { 00195 cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); 00196 } 00197 cmdLine_microUSBserial.serial().printf(" "); 00198 #endif 00199 #if 0 // HAS_DAPLINK_SERIAL 00200 cmdLine_DAPLINKserial.serial().printf("\r\nSPI"); 00201 if (byteCount > 7) { 00202 cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount); 00203 } 00204 cmdLine_DAPLINKserial.serial().printf(" MOSI->"); 00205 for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) 00206 { 00207 cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); 00208 } 00209 // hex dump misoData[0..byteCount-1] 00210 cmdLine_DAPLINKserial.serial().printf(" MISO<-"); 00211 for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) 00212 { 00213 cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); 00214 } 00215 cmdLine_DAPLINKserial.serial().printf(" "); 00216 #endif 00217 // VERIFY: DIAGNOSTIC: print MAX5715 device register write 00218 // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF); 00219 // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF); 00220 // 00221 // int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF; 00222 // return misoData16; 00223 } 00224 00225 // CODE GENERATOR: extern function requirement MAX11410::SPIreadWrite16bits 00226 // SPI read and write 16 bits 00227 // SPI interface to MAX11410 shift 16 bits mosiData16 into MAX11410 DIN 00228 // while simultaneously capturing 16 bits miso data from MAX11410 DOUT 00229 // 00230 int16_t MAX11410::SPIreadWrite16bits(int16_t mosiData16) 00231 { 00232 // CODE GENERATOR: extern function definition for function SPIreadWrite16bits 00233 // TODO1: CODE GENERATOR: extern function definition for standard SPI interface function SPIreadWrite16bits(int16_t mosiData16) 00234 size_t byteCount = 2; 00235 static char mosiData[2]; 00236 static char misoData[2]; 00237 mosiData[0] = (char)((mosiData16 >> 8) & 0xFF); // MSByte 00238 mosiData[1] = (char)((mosiData16 >> 0) & 0xFF); // LSByte 00239 // 00240 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00241 //~ noInterrupts(); 00242 // 00243 //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin 00244 // 00245 unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount); 00246 //~ m_spi.transfer(mosiData8_FF0000); 00247 //~ m_spi.transfer(mosiData16_00FF00); 00248 //~ m_spi.transfer(mosiData16_0000FF); 00249 // 00250 //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin 00251 // 00252 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00253 //~ interrupts(); 00254 // Optional Diagnostic function to print SPI transactions 00255 if (onSPIprint) 00256 { 00257 onSPIprint(byteCount, (uint8_t*)mosiData, (uint8_t*)misoData); 00258 } 00259 // 00260 // VERIFY: SPIwrite24bits print diagnostic information 00261 //cmdLine.serial().printf(" MOSI->")); 00262 //cmdLine.serial().printf(" 0x")); 00263 //Serial.print( (mosiData8_FF0000 & 0xFF), HEX); 00264 //cmdLine.serial().printf(" 0x")); 00265 //Serial.print( (mosiData16_00FF00 & 0xFF), HEX); 00266 //cmdLine.serial().printf(" 0x")); 00267 //Serial.print( (mosiData16_0000FF & 0xFF), HEX); 00268 // hex dump mosiData[0..byteCount-1] 00269 #if 0 // HAS_MICROUSBSERIAL 00270 cmdLine_microUSBserial.serial().printf("\r\nSPI"); 00271 if (byteCount > 7) { 00272 cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount); 00273 } 00274 cmdLine_microUSBserial.serial().printf(" MOSI->"); 00275 for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) 00276 { 00277 cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); 00278 } 00279 // hex dump misoData[0..byteCount-1] 00280 cmdLine_microUSBserial.serial().printf(" MISO<-"); 00281 for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) 00282 { 00283 cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); 00284 } 00285 cmdLine_microUSBserial.serial().printf(" "); 00286 #endif 00287 #if 0 // HAS_DAPLINK_SERIAL 00288 cmdLine_DAPLINKserial.serial().printf("\r\nSPI"); 00289 if (byteCount > 7) { 00290 cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount); 00291 } 00292 cmdLine_DAPLINKserial.serial().printf(" MOSI->"); 00293 for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) 00294 { 00295 cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); 00296 } 00297 // hex dump misoData[0..byteCount-1] 00298 cmdLine_DAPLINKserial.serial().printf(" MISO<-"); 00299 for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) 00300 { 00301 cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); 00302 } 00303 cmdLine_DAPLINKserial.serial().printf(" "); 00304 #endif 00305 // VERIFY: DIAGNOSTIC: print MAX5715 device register write 00306 // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF); 00307 // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF); 00308 // 00309 //int misoData16 = (misoData16_FF00 << 8) | misoData16_00FF; 00310 int misoData16 = (misoData[0] << 8) | misoData[1]; 00311 return misoData16; 00312 } 00313 00314 // CODE GENERATOR: extern function requirement MAX11410::SPIreadWrite32bits 00315 // SPI read and write 32 bits 00316 // SPI interface to MAX11410 shift 32 bits mosiData into MAX11410 DIN 00317 // while simultaneously capturing 32 bits miso data from MAX11410 DOUT 00318 // 00319 int32_t MAX11410::SPIreadWrite32bits(int32_t mosiData32) 00320 { 00321 // CODE GENERATOR: extern function definition for function SPIreadWrite32bits 00322 // TODO1: CODE GENERATOR: extern function definition for standard SPI interface function SPIreadWrite32bits(int32_t mosiData32) 00323 size_t byteCount = 4; 00324 static char mosiData[4]; 00325 static char misoData[4]; 00326 mosiData[0] = (char)((mosiData32 >> 24) & 0xFF); // MSByte 00327 mosiData[1] = (char)((mosiData32 >> 16) & 0xFF); 00328 mosiData[2] = (char)((mosiData32 >> 8) & 0xFF); 00329 mosiData[3] = (char)((mosiData32 >> 0) & 0xFF); // LSByte 00330 // 00331 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00332 //~ noInterrupts(); 00333 // 00334 //~ digitalWrite(Scope_Trigger_Pin, LOW); // diagnostic Scope_Trigger_Pin 00335 // 00336 unsigned int numBytesTransferred = m_spi.write(mosiData, byteCount, misoData, byteCount); 00337 //~ m_spi.transfer(mosiData8_FF0000); 00338 //~ m_spi.transfer(mosiData16_00FF00); 00339 //~ m_spi.transfer(mosiData16_0000FF); 00340 // 00341 //~ digitalWrite(Scope_Trigger_Pin, HIGH); // diagnostic Scope_Trigger_Pin 00342 // 00343 // Arduino: begin critical section: noInterrupts() masks all interrupt sources; end critical section with interrupts() 00344 //~ interrupts(); 00345 // Optional Diagnostic function to print SPI transactions 00346 if (onSPIprint) 00347 { 00348 onSPIprint(byteCount, (uint8_t*)mosiData, (uint8_t*)misoData); 00349 } 00350 // 00351 // VERIFY: SPIwrite24bits print diagnostic information 00352 //cmdLine.serial().printf(" MOSI->")); 00353 //cmdLine.serial().printf(" 0x")); 00354 //Serial.print( (mosiData8_FF0000 & 0xFF), HEX); 00355 //cmdLine.serial().printf(" 0x")); 00356 //Serial.print( (mosiData16_00FF00 & 0xFF), HEX); 00357 //cmdLine.serial().printf(" 0x")); 00358 //Serial.print( (mosiData16_0000FF & 0xFF), HEX); 00359 // hex dump mosiData[0..byteCount-1] 00360 #if 0 // HAS_MICROUSBSERIAL 00361 cmdLine_microUSBserial.serial().printf("\r\nSPI"); 00362 if (byteCount > 7) { 00363 cmdLine_microUSBserial.serial().printf(" byteCount:%d", byteCount); 00364 } 00365 cmdLine_microUSBserial.serial().printf(" MOSI->"); 00366 for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) 00367 { 00368 cmdLine_microUSBserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); 00369 } 00370 // hex dump misoData[0..byteCount-1] 00371 cmdLine_microUSBserial.serial().printf(" MISO<-"); 00372 for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) 00373 { 00374 cmdLine_microUSBserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); 00375 } 00376 cmdLine_microUSBserial.serial().printf(" "); 00377 #endif 00378 #if 0 // HAS_DAPLINK_SERIAL 00379 cmdLine_DAPLINKserial.serial().printf("\r\nSPI"); 00380 if (byteCount > 7) { 00381 cmdLine_DAPLINKserial.serial().printf(" byteCount:%d", byteCount); 00382 } 00383 cmdLine_DAPLINKserial.serial().printf(" MOSI->"); 00384 for (unsigned int byteIndex = 0; byteIndex < byteCount; byteIndex++) 00385 { 00386 cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", mosiData[byteIndex]); 00387 } 00388 // hex dump misoData[0..byteCount-1] 00389 cmdLine_DAPLINKserial.serial().printf(" MISO<-"); 00390 for (unsigned int byteIndex = 0; byteIndex < numBytesTransferred; byteIndex++) 00391 { 00392 cmdLine_DAPLINKserial.serial().printf(" 0x%2.2X", misoData[byteIndex]); 00393 } 00394 cmdLine_DAPLINKserial.serial().printf(" "); 00395 #endif 00396 // VERIFY: DIAGNOSTIC: print MAX5715 device register write 00397 // TODO: MAX5715_print_register_verbose(mosiData8_FF0000, mosiData16_00FFFF); 00398 // TODO: print_verbose_SPI_diagnostic(mosiData16_FF00, mosiData16_00FF, misoData16_FF00, misoData16_00FF); 00399 // 00400 //int misoData32 = (misoData32_FF000000 << 24) | (misoData32_FF0000 << 16) | (misoData32_0000FF00 << 8) | misoData32_000000FF; 00401 int misoData32 = (misoData[0] << 24) | (misoData[1] << 16) | (misoData[2] << 8) | misoData[3]; 00402 return misoData32; 00403 } 00404 00405 // CODE GENERATOR: class member function definitions 00406 //---------------------------------------- 00407 // Menu item '!' 00408 // Initialize device 00409 // 00410 // @test Init() expect 1 00411 // 00412 // @test group POR // verify initial register values 00413 // @test group PORverbose // verify initial register values 00414 // @test group PORverbose tinyTester.print("PART_ID value") 00415 // @test group POR RegRead(MAX11410::CMD_r001_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xddd_PART_ID, buffer) expect 1 expect-buffer 0x000F02 00416 // 00417 // @test group PORverbose tinyTester.print("POR value 0x04 CMD_r000_0100_dddd_xddd_GP0_CTRL") 00418 // @test group POR RegRead(MAX11410::CMD_r000_0100_dddd_xddd_GP0_CTRL, buffer) expect 1 expect-buffer 0x00 00419 // 00420 // @test group PORverbose tinyTester.print("POR value 0x05 CMD_r000_0101_dddd_xddd_GP1_CTRL") 00421 // @test group POR RegRead(MAX11410::CMD_r000_0101_dddd_xddd_GP1_CTRL, buffer) expect 1 expect-buffer 0x00 00422 // 00423 // @test group PORverbose tinyTester.print("POR value 0x07 CMD_r000_0111_xddd_dddd_GP_SEQ_ADDR") 00424 // @test group POR RegRead(MAX11410::CMD_r000_0111_xddd_dddd_GP_SEQ_ADDR, buffer) expect 1 expect-buffer 0x00003a 00425 // 00426 // @test group PORverbose tinyTester.print("POR value 0x08 CMD_r000_1000_x0dd_dddd_FILTER") 00427 // @test group POR RegRead(MAX11410::CMD_r000_1000_x0dd_dddd_FILTER, buffer) expect 1 expect-buffer 0x00 00428 // 00429 // @test group PORverbose tinyTester.print("POR value 0x09 CMD_r000_1001_dddd_dddd_CTRL") 00430 // @test group POR RegRead(MAX11410::CMD_r000_1001_dddd_dddd_CTRL, buffer) expect 1 expect-buffer 0x000001 00431 // 00432 // @test group PORverbose tinyTester.print("POR value 0x0a CMD_r000_1010_dddd_dddd_SOURCE") 00433 // @test group POR RegRead(MAX11410::CMD_r000_1010_dddd_dddd_SOURCE, buffer) expect 1 expect-buffer 0x00 00434 // 00435 // @test group PORverbose tinyTester.print("POR value 0x0b CMD_r000_1011_dddd_dddd_MUX_CTRL0") 00436 // @test group POR RegRead(MAX11410::CMD_r000_1011_dddd_dddd_MUX_CTRL0, buffer) expect 1 expect-buffer 0x0000ff 00437 // 00438 // @test group PORverbose tinyTester.print("POR value 0x0c CMD_r000_1100_dddd_dddd_MUX_CTRL1") 00439 // @test group POR RegRead(MAX11410::CMD_r000_1100_dddd_dddd_MUX_CTRL1, buffer) expect 1 expect-buffer 0x0000ff 00440 // 00441 // @test group PORverbose tinyTester.print("POR value 0x0d CMD_r000_1101_dddd_dddd_MUX_CTRL2") 00442 // @test group POR RegRead(MAX11410::CMD_r000_1101_dddd_dddd_MUX_CTRL2, buffer) expect 1 expect-buffer 0x00 00443 // 00444 // @test group PORverbose tinyTester.print("POR value 0x0e CMD_r000_1110_00ss_0ggg_PGA") 00445 // @test group POR RegRead(MAX11410::CMD_r000_1110_00ss_0ggg_PGA, buffer) expect 1 expect-buffer 0x00 00446 // 00447 // @future test CMD_r000_1111_dddd_dddd_WAIT_EXT = 0x0f, //!< 0b0001111 00448 // @future test CMD_r001_0000_xxxx_xxxx_WAIT_START = 0x10, //!< 0b0010000 00449 // 00450 // @test group RES1KA2A3TOGND // measure a 1kohm resistor between (AIN2,AIN3) and AGND to verify ref2_v (disabled by default) 00451 // @test group RES1KA2A3TOGNDMORE // measure a 1kohm resistor between (AIN2,AIN3) and AGND to verify ref2_v in more detail 00452 // @test group RES1KA2A3TOGNDMORE tinyTester.print("measure a 1kohm resistor between (AIN2,AIN3) and AGND to verify ref2_v") 00453 // @test group RES1KA2A3TOGND tinyTester.settle_time_msec = 1000 // default 250 00454 // @test group RES1KA2A3TOGND RegWrite(0x0C, 0xF3) expect 1 // *mux_ctrl1=0xf3 drives current source from AIN3 00455 // 00456 // @test group RES1KA2A3TOGNDMORE RegWrite(0x0A, 0x03) expect 1 // *source=0x03 idac_mode=100uA, 1k resistor 0.1V 00457 // @test group RES1KA2A3TOGNDMORE tinyTester.print("idac_mode=100uA, 1k resistor 0.1V") 00458 // @test group RES1KA2A3TOGNDMORE tinyTester.Wait_Output_Settling() 00459 // @test group RES1KA2A3TOGNDMORE Measure_Voltage(2,10) expect 0.1 00460 // @test group RES1KA2A3TOGNDMORE AINcode[2] expect (uint32_t)337731 within 33773 // idac_mode=100uA, 1k resistor 0.1V 00461 // 00462 // @test group RES1KA2A3TOGNDMORE RegWrite(0x0A, 0x0D) expect 1 // *source=0x0d idac_mode=800uA, 1k resistor 0.8V 00463 // @test group RES1KA2A3TOGNDMORE tinyTester.print("idac_mode=800uA, 1k resistor 0.8V") 00464 // @test group RES1KA2A3TOGNDMORE tinyTester.Wait_Output_Settling() 00465 // @test group RES1KA2A3TOGNDMORE Measure_Voltage(2,10) expect 0.8 00466 // @test group RES1KA2A3TOGNDMORE AINcode[2] expect (uint32_t)2724467 within 33773 // idac_mode=800uA, 1k resistor 0.8V 00467 // 00468 // @test group RES1KA2A3TOGND RegWrite(0x0A, 0x0B) expect 1 // *source=0x0b idac_mode=400uA, 1k resistor 0.4V 00469 // @test group RES1KA2A3TOGNDMORE tinyTester.print("idac_mode=400uA, 1k resistor 0.4V") 00470 // @test group RES1KA2A3TOGND tinyTester.Wait_Output_Settling() 00471 // @test group RES1KA2A3TOGND Measure_Voltage(2,10) expect 0.4 00472 // @test group RES1KA2A3TOGNDMORE AINcode[2] expect (uint32_t)1343163 within 33773 // idac_mode=400uA, 1k resistor 0.4V 00473 // 00474 // @test tinyTester.print("check filter register is writeable") 00475 // @future test tinyTester.print("this is a real mess dealing with the custom types") 00476 // @test RegWrite(0x08, 0x34) expect 1 00477 // @future test tinyTester.print("error: no matching function for call to 'MaximTinyTester::FunctionCall_Expect(const char [18], uint8_t (&)(MAX11410::CMD_enum_t, uint32_t), MAX11410::CMD_enum_t, uint32_t, int)'") 00478 // @future test RegWrite(CMD_r000_1000_x0dd_dddd_FILTER, 0x34) expect 1 00479 // @future test RegWrite(CMD_enum_t::CMD_r000_1000_x0dd_dddd_FILTER, 0x34) expect 1 00480 // @future test RegWrite(MAX11410::CMD_enum_t::CMD_r000_1000_x0dd_dddd_FILTER, 0x34) expect 1 00481 // 00482 // @test tinyTester.print("check filter register is readable") 00483 // @test RegRead(0x08, buffer) expect 1 expect-buffer 0x34 00484 // @future test RegRead(MAX11410::CMD_enum_t::CMD_r000_1000_x0dd_dddd_FILTER, &buffer) expect 1 expect-buffer 0x34 00485 // 00486 // @test tinyTester.settle_time_msec = 250 // default 250 00487 // @test tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 00488 // @test tinyTester.input_timeout_time_msec = 250 // default 250 00489 // @test tinyTester.settle_time_msec = 20 // default 250 00490 // @test tinyTester.blink_time_msec = 20 // quickly speed through the software verification 00491 // @test tinyTester.input_timeout_time_msec = 100 // default 250 00492 // 00493 // @test tinyTester.Wait_Output_Settling() 00494 // 00495 // @future test tinyTester.DigitalIn_Read_Expect_WarnOnly(DigitalIn& digitalInPin, const char* pinName, int expect_result, const char *expect_description) 00496 // 00497 // @return 1 on success; 0 on failure 00498 uint8_t MAX11410::Init(void) 00499 { 00500 00501 //---------------------------------------- 00502 // AIN0-AIN1 reference voltage, in Volts 00503 ref0_v = 2.500; 00504 00505 //---------------------------------------- 00506 // REF1P-REF1N reference resistance, in Ohms 00507 ref1_v = 4999; 00508 00509 //---------------------------------------- 00510 // REF2P-REF2N reference voltage, in Volts 00511 ref2_v = 2.500; 00512 00513 //---------------------------------------- 00514 // AVDD-AGND supply voltage, in Volts 00515 avdd_v = 3.300; 00516 00517 //---------------------------------------- 00518 // RTD Resistance measurement; Thermocouple Cold Junction, in Ohms 00519 rtd_ohm = 1000.0; 00520 00521 //---------------------------------------- 00522 // Temperature calculated from RTD Resistance; Thermocouple Cold Junction, in degrees C 00523 rtd_degc = 25.0; 00524 00525 //---------------------------------------- 00526 // shadow of register ctrl CMD_r000_1001_dddd_dddd_CTRL 00527 ctrl = 0x01; 00528 00529 //---------------------------------------- 00530 // set by Configure_PGA gain index register pga CMD_r000_1110_00ss_0ggg_PGA 00531 pgaGain = 1; 00532 00533 //---------------------------------------- 00534 // When driver polls status of a pin signal or a register status bit, 00535 // and there is no device physically connected, the driver must 00536 // be able to halt and report failure if too many tries. Each attempt 00537 // counts down until loop_limit is reached or exceeded. 00538 // 00539 // If driver seems to hang or takes too long to decide that device 00540 // is not connected, reduce the futility countdown limit value. 00541 // 00542 // If driver sometimes works but sometimes intermittently fails to 00543 // recognize device is attached, increase the futility countdown limit. 00544 loop_limit = 30; 00545 00546 //---------------------------------------- 00547 // timing delay after enable RTD bias current in Measure_RTD() 00548 rtd_ms = 100; 00549 00550 //---------------------------------------- 00551 // filter register configuration in Measure_RTD() -- 0x34 LINEF_11_SINC4 RATE_0100 output data rate 60SPS 00552 rtd_filter = 0x34; 00553 00554 //---------------------------------------- 00555 // ctrl register configuration in Measure_RTD() -- 0x40 unipolar, 0x01 REF_SEL_001_REF1P_REF1N 00556 rtd_ctrl = 0x41; 00557 00558 //---------------------------------------- 00559 // source register configuration in Measure_RTD() -- 0x0B IDAC_MODE_1011_400uA 00560 rtd_source = 0x0B; 00561 00562 //---------------------------------------- 00563 // pga register configuration in Measure_RTD() -- 0x21 SIG_PATH_10_PGA GAIN_001_2 00564 rtd_pga = 0x21; 00565 00566 //---------------------------------------- 00567 // filter register configuration in Measure_Voltage() -- 0x34 LINEF_11_SINC4 RATE_0100 output data rate 60SPS 00568 v_filter = 0x34; 00569 00570 //---------------------------------------- 00571 // ctrl register configuration in Measure_Voltage() -- 0x02 bipolar REF_SEL_010_REF2P_REF2N 00572 v_ctrl = 0x02; 00573 00574 //---------------------------------------- 00575 // pga register configuration in Measure_Voltage() -- 0x00 SIG_PATH_00_BUFFERED GAIN_000_1 00576 v_pga = 0x00; 00577 00578 //---------------------------------------- 00579 // list of registers to be read by menu item * with no arguments 00580 static MAX11410::MAX11410_CMD_enum_t readAllStatusListValues[] = { 00581 MAX11410::CMD_r000_0000_xxxx_xxdd_PD, 00582 MAX11410::CMD_r000_0001_xddd_xxdd_CONV_START, 00583 MAX11410::CMD_r000_0010_xddd_dddd_SEQ_START, 00584 MAX11410::CMD_r000_0011_xxxx_xddd_CAL_START, 00585 MAX11410::CMD_r000_0100_dddd_xddd_GP0_CTRL, 00586 MAX11410::CMD_r000_0101_dddd_xddd_GP1_CTRL, 00587 MAX11410::CMD_r000_0110_xddd_xxdd_GP_CONV, 00588 MAX11410::CMD_r000_0111_xddd_dddd_GP_SEQ_ADDR, 00589 MAX11410::CMD_r000_1000_x0dd_dddd_FILTER, 00590 MAX11410::CMD_r000_1001_dddd_dddd_CTRL, 00591 MAX11410::CMD_r000_1010_dddd_dddd_SOURCE, 00592 MAX11410::CMD_r000_1011_dddd_dddd_MUX_CTRL0, 00593 MAX11410::CMD_r000_1100_dddd_dddd_MUX_CTRL1, 00594 MAX11410::CMD_r000_1101_dddd_dddd_MUX_CTRL2, 00595 MAX11410::CMD_r000_1110_00ss_0ggg_PGA, 00596 MAX11410::CMD_r000_1111_dddd_dddd_WAIT_EXT, 00597 MAX11410::CMD_r001_0000_xxxx_xxxx_WAIT_START, 00598 }; 00599 readAllStatusList = readAllStatusListValues; 00600 00601 //---------------------------------------- 00602 // number of registers to be read by menu item * with no arguments 00603 readAllStatusListLen = 17; 00604 00605 //---------------------------------------- 00606 // Device ID Validation 00607 const uint32_t part_id_expect = 0x000F02; 00608 uint32_t part_id_readback; 00609 RegRead(CMD_r001_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xddd_PART_ID, &part_id_readback); 00610 if (part_id_readback != part_id_expect) return 0; 00611 00612 //---------------------------------------- 00613 // write8 0x00 PD = 0x03 (Reset Registers; enter Standby mode) 00614 RegWrite(CMD_r000_0000_xxxx_xxdd_PD, PD_11_Reset); 00615 00616 //---------------------------------------- 00617 // write8 0x00 PD = 0x00 (NOP) 00618 RegWrite(CMD_r000_0000_xxxx_xxdd_PD, PD_00_Normal); 00619 00620 //---------------------------------------- 00621 // success 00622 return 1; 00623 } 00624 00625 //---------------------------------------- 00626 // Return the physical voltage corresponding to conversion result, 00627 // for unipolar mode. 00628 // Does not perform any offset or gain correction. 00629 // 00630 // @pre CTRL::U_BN = 1 -- Unipolar mode 00631 // @pre CTRL::FORMAT = x 00632 // @pre VRef = Voltage of REF input, in Volts 00633 // @param[in] value_u24: raw 24-bit MAX11410 code (right justified). 00634 // @return physical voltage corresponding to MAX11410 code. 00635 // 00636 // @test group UNIPOLAR // Verify function VoltageOfCode_Unipolar 00637 // @test group UNIPOLAR tinyTester.blink_time_msec = 20 // quickly speed through the software verification 00638 // @test group UNIPOLAR Configure_CTRL_REF(2) expect 1 // These tests require REF2 = 2.500V 00639 // @test group UNIPOLAR Configure_PGA(0,0) expect 1 // These tests require PGA gain=1 00640 // @test group UNIPOLAR VoltageOfCode_Unipolar(0xFFFFFF) expect 2.500 within 0.030 // Full Scale 00641 // @test group UNIPOLAR VoltageOfCode_Unipolar(0xFFFFFE) expect 2.500 // Full Scale 00642 // @test group UNIPOLAR VoltageOfCode_Unipolar(0xCCCCCC) expect 2.000 // Two Volts 00643 // @test group UNIPOLAR VoltageOfCode_Unipolar(0xC00000) expect 1.875 // 75% Scale 00644 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x800000) expect 1.250 // Mid Scale 00645 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x666666) expect 1.000 // One Volt 00646 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x400000) expect 0.625 // 25% Scale 00647 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x0A3D70) expect 0.100 // 100mV 00648 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x000064) expect 0.000014901162 // 100 LSB 00649 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x00000A) expect 0.0000014901162 // Ten LSB 00650 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x000003) expect 0.00000044703483 // Three LSB 00651 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x000002) expect 0.00000029802326 // Two LSB 00652 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x000001) expect 0.00000014901162 // One LSB 00653 // @test group UNIPOLAR VoltageOfCode_Unipolar(0x000000) expect 0.0 // Zero Scale 00654 // @test group UNIPOLAR tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 00655 // 00656 double MAX11410::VoltageOfCode_Unipolar(uint32_t value_u24) 00657 { 00658 00659 //---------------------------------------- 00660 // Linear map min and max endpoints 00661 double VRef = ref2_v; 00662 uint8_t ref_sel = (ctrl & 0x03); // MAX11410_REF_SEL_enum_t 00663 switch(ref_sel) 00664 { 00665 case REF_SEL_000_AIN0_AIN1: VRef = ref0_v; break; 00666 case REF_SEL_001_REF1P_REF1N: VRef = ref1_v; break; 00667 case REF_SEL_010_REF2P_REF2N: VRef = ref2_v; break; 00668 case REF_SEL_011_AVDD_AGND: VRef = avdd_v; break; 00669 case REF_SEL_100_AIN0_AGND: VRef = ref0_v; break; 00670 case REF_SEL_101_REF1P_AGND: VRef = ref1_v; break; 00671 case REF_SEL_110_REF2P_AGND: VRef = ref2_v; break; 00672 case REF_SEL_111_AVDD_AGND: VRef = avdd_v; break; 00673 } 00674 double MaxScaleVoltage = VRef; // voltage of maximum code 0xffffff 00675 double MinScaleVoltage = 0.0; // voltage of minimum code 0x000 00676 const uint32_t FULL_SCALE_CODE_24BIT = 0xffffff; 00677 const uint32_t MaxCode = FULL_SCALE_CODE_24BIT; 00678 const uint32_t MinCode = 0x000; 00679 double codeFraction = ((double)value_u24 - MinCode) / (MaxCode - MinCode + 1); 00680 return (MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction)) / pgaGain; 00681 } 00682 00683 //---------------------------------------- 00684 // Return the physical voltage corresponding to conversion result, 00685 // when conversion format is Bipolar mode, offset binary. 00686 // Does not perform any offset or gain correction. 00687 // 00688 // @pre CTRL::U_BN = 0 -- Bipolar mode 00689 // @pre CTRL::FORMAT = 1 -- offset binary 00690 // @pre VRef = Voltage of REF input, in Volts 00691 // @param[in] value_u24: raw 24-bit MAX11410 code (right justified). 00692 // @return physical voltage corresponding to MAX11410 code. 00693 // 00694 // @test group BIPOB // Verify function VoltageOfCode_Bipolar_OffsetBinary 00695 // @test group BIPOB tinyTester.blink_time_msec = 20 // quickly speed through the software verification 00696 // @test group BIPOB Configure_CTRL_REF(2) expect 1 // These tests require REF2 = 2.500V 00697 // @test group BIPOB Configure_PGA(0,0) expect 1 // These tests require PGA gain=1 00698 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0xFFFFFF) expect 2.5 within 0.030 // Full Scale 00699 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0xFFFFFE) expect 2.5 // Full Scale 00700 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0xC00000) expect 1.25 // Mid Scale 00701 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x800003) expect 0.00000894069671 // Three LSB 00702 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x800002) expect 0.00000596046447 // Two LSB 00703 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x800001) expect 0.0000029802326 // One LSB 00704 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x800000) expect 0.0 // Zero Scale 00705 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x7FFFFF) expect -0.0000029802326 // Negative One LSB 00706 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x7FFFFE) expect -0.0000059604644 // Negative Two LSB 00707 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x7FFFFD) expect -0.0000089406967 // Negative Three LSB 00708 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x400000) expect -1.25 // Negative Mid Scale 00709 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x000001) expect -2.5 // Negative Full Scale 00710 // @test group BIPOB VoltageOfCode_Bipolar_OffsetBinary(0x000000) expect -2.5 // Negative Full Scale 00711 // @test group BIPOB tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 00712 // 00713 double MAX11410::VoltageOfCode_Bipolar_OffsetBinary(uint32_t value_u24) 00714 { 00715 00716 //---------------------------------------- 00717 // Linear map min and max endpoints 00718 double VRef = ref2_v; 00719 uint8_t ref_sel = (ctrl & 0x03); // MAX11410_REF_SEL_enum_t 00720 switch(ref_sel) 00721 { 00722 case REF_SEL_000_AIN0_AIN1: VRef = ref0_v; break; 00723 case REF_SEL_001_REF1P_REF1N: VRef = ref1_v; break; 00724 case REF_SEL_010_REF2P_REF2N: VRef = ref2_v; break; 00725 case REF_SEL_011_AVDD_AGND: VRef = avdd_v; break; 00726 case REF_SEL_100_AIN0_AGND: VRef = ref0_v; break; 00727 case REF_SEL_101_REF1P_AGND: VRef = ref1_v; break; 00728 case REF_SEL_110_REF2P_AGND: VRef = ref2_v; break; 00729 case REF_SEL_111_AVDD_AGND: VRef = avdd_v; break; 00730 } 00731 double MaxScaleVoltage = 2 * VRef; // voltage of maximum code 0x7fffff 00732 double MinScaleVoltage = 0; // voltage of minimum code 0x800000; 00733 // const uint32_t FULL_SCALE_CODE_24BIT = 0x7fffff; 00734 // const uint32_t MaxCode = FULL_SCALE_CODE_24BIT; 00735 const int32_t CodeSpan = 0x1000000; 00736 const uint32_t MinCode = 0x800000; 00737 double codeFraction = ((double)value_u24 - MinCode) / CodeSpan; 00738 return (MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction)) / pgaGain; 00739 } 00740 00741 //---------------------------------------- 00742 // Return the physical voltage corresponding to conversion result, 00743 // when conversion format is Bipolar mode, 2's complement. 00744 // Does not perform any offset or gain correction. 00745 // 00746 // @pre CTRL::U_BN = 0 -- Bipolar mode 00747 // @pre CTRL::FORMAT = 0 -- 2's complement 00748 // @pre VRef = Voltage of REF input, in Volts 00749 // @param[in] value_u24: raw 24-bit MAX11410 code (right justified). 00750 // @return physical voltage corresponding to MAX11410 code. 00751 // 00752 // @test group BIP2C // Verify function VoltageOfCode_Bipolar_2sComplement 00753 // @test group BIP2C tinyTester.blink_time_msec = 20 // quickly speed through the software verification 00754 // @test group BIP2C Configure_CTRL_REF(2) expect 1 // These tests require REF2 = 2.500V 00755 // @test group BIP2C Configure_PGA(0,0) expect 1 // These tests require PGA gain=1 00756 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x7FFFFF) expect 2.500 within 0.030 // Full Scale 00757 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x7FFFFE) expect 2.500 // Full Scale 00758 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x666666) expect 2.000 // Two Volts 00759 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x600000) expect 1.875 // 75% Scale 00760 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x400000) expect 1.250 // Mid Scale 00761 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x333333) expect 1.000 // One Volt 00762 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x200000) expect 0.625 // 25% Scale 00763 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x051eb8) expect 0.100 // 100mV 00764 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x000003) expect 0.00000894069671 // Three LSB 00765 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x000002) expect 0.00000596046447 // Two LSB 00766 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x000001) expect 0.0000029802326 // One LSB 00767 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x000000) expect 0.0 // Zero Scale 00768 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xFFFFFF) expect -0.0000029802326 // Negative One LSB 00769 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xFFFFFE) expect -0.0000059604644 // Negative Two LSB 00770 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xFFFFFD) expect -0.0000089406967 // Negative Three LSB 00771 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xFAE148) expect -0.100 // Negative 100mV 00772 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xE00000) expect -0.625 // Negative 25% Scale 00773 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xCCCCCD) expect -1.000 // Negative One Volt 00774 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xC00000) expect -1.250 // Negative Mid Scale 00775 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0xA00000) expect -1.875 // Negative 75% Scale 00776 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x99999A) expect -2.000 // Negative Two Volts 00777 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x800001) expect -2.500 // Negative Full Scale 00778 // @test group BIP2C VoltageOfCode_Bipolar_2sComplement(0x800000) expect -2.500 // Negative Full Scale 00779 // @test group BIP2C tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 00780 // 00781 double MAX11410::VoltageOfCode_Bipolar_2sComplement(uint32_t value_u24) 00782 { 00783 00784 //---------------------------------------- 00785 // Linear map min and max endpoints 00786 double VRef = ref2_v; 00787 uint8_t ref_sel = (ctrl & 0x03); // MAX11410_REF_SEL_enum_t 00788 switch(ref_sel) 00789 { 00790 case REF_SEL_000_AIN0_AIN1: VRef = ref0_v; break; 00791 case REF_SEL_001_REF1P_REF1N: VRef = ref1_v; break; 00792 case REF_SEL_010_REF2P_REF2N: VRef = ref2_v; break; 00793 case REF_SEL_011_AVDD_AGND: VRef = avdd_v; break; 00794 case REF_SEL_100_AIN0_AGND: VRef = ref0_v; break; 00795 case REF_SEL_101_REF1P_AGND: VRef = ref1_v; break; 00796 case REF_SEL_110_REF2P_AGND: VRef = ref2_v; break; 00797 case REF_SEL_111_AVDD_AGND: VRef = avdd_v; break; 00798 } 00799 double MaxScaleVoltage = 2 * VRef; // voltage of maximum code 0x7fffff 00800 double MinScaleVoltage = 0; // voltage of minimum code 0x800000 00801 // const int32_t FULL_SCALE_CODE_24BIT_2S_COMPLEMENT = 0x7fffff; 00802 const int32_t SIGN_BIT_24BIT_2S_COMPLEMENT = 0x800000; 00803 if (value_u24 >= SIGN_BIT_24BIT_2S_COMPLEMENT) { value_u24 = value_u24 - (2 * SIGN_BIT_24BIT_2S_COMPLEMENT); } 00804 // const int32_t MaxCode = FULL_SCALE_CODE_24BIT_2S_COMPLEMENT; 00805 const int32_t CodeSpan = 0x1000000; 00806 const int32_t MinCode = 0; 00807 double codeFraction = ((double)((int32_t)value_u24) - MinCode) / CodeSpan; 00808 return (MinScaleVoltage + ((MaxScaleVoltage - MinScaleVoltage) * codeFraction)) / pgaGain; 00809 } 00810 00811 //---------------------------------------- 00812 // Return the physical voltage corresponding to conversion result, 00813 // when conversion format is determined by the CTRL register. 00814 // Does not perform any offset or gain correction. 00815 // 00816 // @pre CTRL::U_BN and CTRL::FORMAT = 0 select offset binary, 2's complement, or straight binary 00817 // @pre VRef = Voltage of REF input, in Volts 00818 // @param[in] value_u24: raw 24-bit MAX11410 code (right justified). 00819 // @return physical voltage corresponding to MAX11410 code. 00820 double MAX11410::VoltageOfCode(uint32_t value_u24) 00821 { 00822 00823 //---------------------------------------- 00824 // Determine format from CTRL register U_BN and FORMAT 00825 uint8_t u_bn_bitmask = (1 << 6); 00826 uint8_t format_bitmask = (1 << 5); 00827 if ((ctrl & u_bn_bitmask) != 0) 00828 { 00829 return VoltageOfCode_Unipolar(value_u24); 00830 } 00831 if ((ctrl & format_bitmask) != 0) 00832 { 00833 return VoltageOfCode_Bipolar_OffsetBinary(value_u24); 00834 } 00835 return VoltageOfCode_Bipolar_2sComplement(value_u24); 00836 } 00837 00838 //---------------------------------------- 00839 // Write a MAX11410 register. 00840 // 00841 // CMDOP_1aaa_aaaa_ReadRegister bit is cleared 0 indicating a write operation. 00842 // 00843 // MAX11410 register length can be determined by function RegSize. 00844 // 00845 // For 8-bit register size: 00846 // 00847 // SPI 16-bit transfer 00848 // 00849 // SPI MOSI = 0aaa_aaaa_dddd_dddd 00850 // 00851 // SPI MISO = xxxx_xxxx_xxxx_xxxx 00852 // 00853 // For 16-bit register size: 00854 // 00855 // SPI 24-bit or 32-bit transfer 00856 // 00857 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd 00858 // 00859 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx 00860 // 00861 // For 24-bit register size: 00862 // 00863 // SPI 32-bit transfer 00864 // 00865 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd_dddd_dddd 00866 // 00867 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx 00868 // 00869 // @return 1 on success; 0 on failure 00870 uint8_t MAX11410::RegWrite(MAX11410_CMD_enum_t commandByte, uint32_t regData) 00871 { 00872 00873 //---------------------------------------- 00874 // switch based on register address size RegSize(commandByte) 00875 commandByte = (MAX11410_CMD_enum_t)((commandByte &~ CMDOP_1aaa_aaaa_ReadRegister) & 0xFF); 00876 switch(RegSize(commandByte)) 00877 { 00878 case 8: // 8-bit register size 00879 { 00880 // SPI 16-bit transfer 00881 // SPI MOSI = 0aaa_aaaa_dddd_dddd 00882 // SPI MISO = xxxx_xxxx_xxxx_xxxx 00883 int16_t mosiData16 = ((int16_t)commandByte << 8) | ((int16_t)regData & 0xFF); 00884 SPIoutputCS(0); 00885 SPIwrite16bits(mosiData16); 00886 SPIoutputCS(1); 00887 // 00888 if (commandByte == CMD_r000_1110_00ss_0ggg_PGA) 00889 { 00890 // update pgaGain with 1, 2, 4, 8, 16, 32, 64, or 128 based on gain index 00891 static uint8_t pgaGainTable[8] = {1, 2, 4, 8, 16, 32, 64, 128}; 00892 pgaGain = (((regData >> 4) & 2) == SIG_PATH_10_PGA) 00893 ? pgaGainTable[(uint8_t)(regData & 7)] 00894 : 1; 00895 } 00896 if (commandByte == CMD_r000_0011_xxxx_xddd_CAL_START) 00897 { 00898 // after RegWrite CMD_r000_0011_xxxx_xddd_CAL_START, poll status until 0x000004 CAL_RDY 00899 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 00900 switch(regData & 0x07) 00901 { 00902 case 2: // CAL_TYPE_010_reserved = 0x02, //!< 0b010 00903 case 3: // CAL_TYPE_011_reserved = 0x03, //!< 0b011 00904 break; // do not wait for status 00905 case 1: // CAL_TYPE_001_PGA_GAIN = 0x01, //!< 0b001 00906 // 00907 // Note: this case may fall through, by design. 00908 #if __GNUC__ 00909 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" 00910 #endif 00911 if (pgaGain == 1) break; // do not wait for status 00912 // fall through to case 0,4,5,6,7 00913 #if __GNUC__ 00914 #pragma GCC diagnostic pop 00915 #endif 00916 // Note: this case may fall through, by design. 00917 case 0: // CAL_TYPE_000_SELF_CAL = 0x00, //!< 0b000 00918 case 4: // CAL_TYPE_100_SYS_OFF_A = 0x04, //!< 0b100 00919 case 5: // CAL_TYPE_101_SYS_GAIN_A = 0x05, //!< 0b101 00920 case 6: // CAL_TYPE_110_SYS_OFF_B = 0x06, //!< 0b110 00921 case 7: // CAL_TYPE_111_SYS_GAIN_B = 0x07, //!< 0b111 00922 { 00923 // wait for status CAL_RDY 00924 // Worst-case (longest) calibration time = 2 x 1 sample/second = 2 seconds 00925 for (int futility_countdown = loop_limit; 00926 ((futility_countdown > 0) && 00927 ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000004_CAL_RDY) == 0)); 00928 futility_countdown--) 00929 { 00930 for (int futility_countdown_inner = 32767; 00931 ((futility_countdown_inner > 0) && 00932 ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000004_CAL_RDY) == 0)); 00933 futility_countdown_inner--) 00934 { 00935 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 00936 } 00937 } 00938 } 00939 break; 00940 } 00941 } 00942 } 00943 break; 00944 case 16: // 16-bit register size 00945 { 00946 // SPI 24-bit or 32-bit transfer 00947 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd 00948 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx 00949 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd_0000_0000 00950 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx 00951 int32_t mosiData32 = ((int32_t)commandByte << 24) | (((int32_t)regData & 0xFFFF) << 8); 00952 SPIoutputCS(0); 00953 SPIreadWrite32bits(mosiData32); 00954 SPIoutputCS(1); 00955 } 00956 break; 00957 case 24: // 24-bit register size 00958 { 00959 // SPI 32-bit transfer 00960 // SPI MOSI = 0aaa_aaaa_dddd_dddd_dddd_dddd_dddd_dddd 00961 // SPI MISO = xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx 00962 int32_t mosiData32 = ((int32_t)commandByte << 24) | ((int32_t)regData & 0x00FFFFFF); 00963 SPIoutputCS(0); 00964 SPIreadWrite32bits(mosiData32); 00965 SPIoutputCS(1); 00966 } 00967 break; 00968 } 00969 00970 //---------------------------------------- 00971 // success 00972 return 1; 00973 } 00974 00975 //---------------------------------------- 00976 // Read an 8-bit MAX11410 register 00977 // 00978 // CMDOP_1aaa_aaaa_ReadRegister bit is set 1 indicating a read operation. 00979 // 00980 // MAX11410 register length can be determined by function RegSize. 00981 // 00982 // For 8-bit register size: 00983 // 00984 // SPI 16-bit transfer 00985 // 00986 // SPI MOSI = 1aaa_aaaa_0000_0000 00987 // 00988 // SPI MISO = xxxx_xxxx_dddd_dddd 00989 // 00990 // For 16-bit register size: 00991 // 00992 // SPI 24-bit or 32-bit transfer 00993 // 00994 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000 00995 // 00996 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd 00997 // 00998 // For 24-bit register size: 00999 // 01000 // SPI 32-bit transfer 01001 // 01002 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000 01003 // 01004 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd 01005 // 01006 // 01007 // @return 1 on success; 0 on failure 01008 uint8_t MAX11410::RegRead(MAX11410_CMD_enum_t commandByte, uint32_t* ptrRegData) 01009 { 01010 01011 //---------------------------------------- 01012 // switch based on register address size RegSize(regAddress) 01013 commandByte = (MAX11410_CMD_enum_t)((commandByte &~ CMDOP_1aaa_aaaa_ReadRegister) & 0xFF); 01014 switch(RegSize(commandByte)) 01015 { 01016 case 8: // 8-bit register size 01017 { 01018 // SPI 16-bit transfer 01019 // SPI MOSI = 1aaa_aaaa_0000_0000 01020 // SPI MISO = xxxx_xxxx_dddd_dddd 01021 int16_t mosiData16 = ((CMDOP_1aaa_aaaa_ReadRegister | (int16_t)commandByte) << 8) | ((int16_t)0); 01022 SPIoutputCS(0); 01023 int16_t misoData16 = SPIreadWrite16bits(mosiData16); 01024 SPIoutputCS(1); 01025 (*ptrRegData) = (misoData16 & 0x00FF); 01026 } 01027 break; 01028 case 16: // 16-bit register size 01029 { 01030 // SPI 24-bit or 32-bit transfer 01031 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000 01032 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd 01033 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000 01034 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_xxxx_xxxx 01035 int32_t mosiData32 = ((CMDOP_1aaa_aaaa_ReadRegister | (int32_t)commandByte) << 24); 01036 SPIoutputCS(0); 01037 int32_t misoData32 = SPIreadWrite32bits(mosiData32); 01038 SPIoutputCS(1); 01039 (*ptrRegData) = ((misoData32 >> 8) & 0x00FFFF); 01040 } 01041 break; 01042 case 24: // 24-bit register size 01043 { 01044 // SPI 32-bit transfer 01045 // SPI MOSI = 1aaa_aaaa_0000_0000_0000_0000_0000_0000 01046 // SPI MISO = xxxx_xxxx_dddd_dddd_dddd_dddd_dddd_dddd 01047 int32_t mosiData32 = ((CMDOP_1aaa_aaaa_ReadRegister | (int32_t)commandByte) << 24); 01048 SPIoutputCS(0); 01049 int32_t misoData32 = SPIreadWrite32bits(mosiData32); 01050 SPIoutputCS(1); 01051 (*ptrRegData) = (misoData32 & 0x00FFFFFF); 01052 } 01053 break; 01054 } 01055 01056 //---------------------------------------- 01057 // success 01058 return 1; 01059 } 01060 01061 //---------------------------------------- 01062 // Return the size of a MAX11410 register 01063 // 01064 // @return 8 for 8-bit, 16 for 16-bit, 24 for 24-bit, else 0 for undefined register size 01065 uint8_t MAX11410::RegSize(MAX11410_CMD_enum_t commandByte) 01066 { 01067 01068 //---------------------------------------- 01069 // switch based on register address value regAddress 01070 commandByte = (MAX11410_CMD_enum_t)((commandByte &~ CMDOP_1aaa_aaaa_ReadRegister) & 0xFF); 01071 switch(commandByte) 01072 { 01073 default: 01074 return 0; // undefined register size 01075 case CMD_r000_0000_xxxx_xxdd_PD: 01076 case CMD_r000_0001_xddd_xxdd_CONV_START: 01077 case CMD_r000_0010_xddd_dddd_SEQ_START: 01078 case CMD_r000_0011_xxxx_xddd_CAL_START: 01079 case CMD_r000_0100_dddd_xddd_GP0_CTRL: 01080 case CMD_r000_0101_dddd_xddd_GP1_CTRL: 01081 case CMD_r000_0110_xddd_xxdd_GP_CONV: 01082 case CMD_r000_0111_xddd_dddd_GP_SEQ_ADDR: 01083 case CMD_r000_1000_x0dd_dddd_FILTER: 01084 case CMD_r000_1001_dddd_dddd_CTRL: 01085 case CMD_r000_1010_dddd_dddd_SOURCE: 01086 case CMD_r000_1011_dddd_dddd_MUX_CTRL0: 01087 case CMD_r000_1100_dddd_dddd_MUX_CTRL1: 01088 case CMD_r000_1101_dddd_dddd_MUX_CTRL2: 01089 case CMD_r000_1110_00ss_0ggg_PGA: 01090 case CMD_r000_1111_dddd_dddd_WAIT_EXT: 01091 case CMD_r001_0000_xxxx_xxxx_WAIT_START: 01092 return 8; // 8-bit register size 01093 case CMD_r001_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xddd_PART_ID: 01094 case CMD_r001_0010_xxxx_xxxx_dddd_xxdd_dddd_dddd_SYSC_SEL: 01095 case CMD_r001_0011_dddd_dddd_dddd_dddd_dddd_dddd_SYS_OFF_A: 01096 case CMD_r001_0100_dddd_dddd_dddd_dddd_dddd_dddd_SYS_OFF_B: 01097 case CMD_r001_0101_dddd_dddd_dddd_dddd_dddd_dddd_SYS_GAIN_A: 01098 case CMD_r001_0110_dddd_dddd_dddd_dddd_dddd_dddd_SYS_GAIN_B: 01099 case CMD_r001_0111_dddd_dddd_dddd_dddd_dddd_dddd_SELF_OFF: 01100 case CMD_r001_1000_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_1: 01101 case CMD_r001_1001_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_2: 01102 case CMD_r001_1010_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_4: 01103 case CMD_r001_1011_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_8: 01104 case CMD_r001_1100_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_16: 01105 case CMD_r001_1101_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_32: 01106 case CMD_r001_1110_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_64: 01107 case CMD_r001_1111_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_128: 01108 case CMD_r010_0000_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH0: 01109 case CMD_r010_0001_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH1: 01110 case CMD_r010_0010_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH2: 01111 case CMD_r010_0011_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH3: 01112 case CMD_r010_0100_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH4: 01113 case CMD_r010_0101_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH5: 01114 case CMD_r010_0110_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH6: 01115 case CMD_r010_0111_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH7: 01116 case CMD_r010_1000_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH0: 01117 case CMD_r010_1001_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH1: 01118 case CMD_r010_1010_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH2: 01119 case CMD_r010_1011_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH3: 01120 case CMD_r010_1100_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH4: 01121 case CMD_r010_1101_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH5: 01122 case CMD_r010_1110_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH6: 01123 case CMD_r010_1111_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH7: 01124 case CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0: 01125 case CMD_r011_0001_dddd_dddd_dddd_dddd_dddd_dddd_DATA1: 01126 case CMD_r011_0010_dddd_dddd_dddd_dddd_dddd_dddd_DATA2: 01127 case CMD_r011_0011_dddd_dddd_dddd_dddd_dddd_dddd_DATA3: 01128 case CMD_r011_0100_dddd_dddd_dddd_dddd_dddd_dddd_DATA4: 01129 case CMD_r011_0101_dddd_dddd_dddd_dddd_dddd_dddd_DATA5: 01130 case CMD_r011_0110_dddd_dddd_dddd_dddd_dddd_dddd_DATA6: 01131 case CMD_r011_0111_dddd_dddd_dddd_dddd_dddd_dddd_DATA7: 01132 case CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS: 01133 case CMD_r011_1001_dddd_dddd_dddd_dddd_dxxd_dddd_STATUS_IE: 01134 return 24; // 24-bit register size 01135 case CMD_r011_1010_xaaa_aaaa_dddd_dddd_UC_0: 01136 case CMD_r011_1011_xaaa_aaaa_dddd_dddd_UC_1: 01137 case CMD_r011_1100_xaaa_aaaa_dddd_dddd_UC_2: 01138 case CMD_r011_1101_xaaa_aaaa_dddd_dddd_UC_3: 01139 case CMD_r011_1110_xaaa_aaaa_dddd_dddd_UC_4: 01140 case CMD_r011_1111_xaaa_aaaa_dddd_dddd_UC_5: 01141 case CMD_r100_0000_xaaa_aaaa_dddd_dddd_UC_6: 01142 case CMD_r100_0001_xaaa_aaaa_dddd_dddd_UC_7: 01143 case CMD_r100_0010_xaaa_aaaa_dddd_dddd_UC_8: 01144 case CMD_r100_0011_xaaa_aaaa_dddd_dddd_UC_9: 01145 case CMD_r100_0100_xaaa_aaaa_dddd_dddd_UC_10: 01146 case CMD_r100_0101_xaaa_aaaa_dddd_dddd_UC_11: 01147 case CMD_r100_0110_xaaa_aaaa_dddd_dddd_UC_12: 01148 case CMD_r100_0111_xaaa_aaaa_dddd_dddd_UC_13: 01149 case CMD_r100_1000_xaaa_aaaa_dddd_dddd_UC_14: 01150 case CMD_r100_1001_xaaa_aaaa_dddd_dddd_UC_15: 01151 case CMD_r100_1010_xaaa_aaaa_dddd_dddd_UC_16: 01152 case CMD_r100_1011_xaaa_aaaa_dddd_dddd_UC_17: 01153 case CMD_r100_1100_xaaa_aaaa_dddd_dddd_UC_18: 01154 case CMD_r100_1101_xaaa_aaaa_dddd_dddd_UC_19: 01155 case CMD_r100_1110_xaaa_aaaa_dddd_dddd_UC_20: 01156 case CMD_r100_1111_xaaa_aaaa_dddd_dddd_UC_21: 01157 case CMD_r101_0000_xaaa_aaaa_dddd_dddd_UC_22: 01158 case CMD_r101_0001_xaaa_aaaa_dddd_dddd_UC_23: 01159 case CMD_r101_0010_xaaa_aaaa_dddd_dddd_UC_24: 01160 case CMD_r101_0011_xaaa_aaaa_dddd_dddd_UC_25: 01161 case CMD_r101_0100_xaaa_aaaa_dddd_dddd_UC_26: 01162 case CMD_r101_0101_xaaa_aaaa_dddd_dddd_UC_27: 01163 case CMD_r101_0110_xaaa_aaaa_dddd_dddd_UC_28: 01164 case CMD_r101_0111_xaaa_aaaa_dddd_dddd_UC_29: 01165 case CMD_r101_1000_xaaa_aaaa_dddd_dddd_UC_30: 01166 case CMD_r101_1001_xaaa_aaaa_dddd_dddd_UC_31: 01167 case CMD_r101_1010_xaaa_aaaa_dddd_dddd_UC_32: 01168 case CMD_r101_1011_xaaa_aaaa_dddd_dddd_UC_33: 01169 case CMD_r101_1100_xaaa_aaaa_dddd_dddd_UC_34: 01170 case CMD_r101_1101_xaaa_aaaa_dddd_dddd_UC_35: 01171 case CMD_r101_1110_xaaa_aaaa_dddd_dddd_UC_36: 01172 case CMD_r101_1111_xaaa_aaaa_dddd_dddd_UC_37: 01173 case CMD_r110_0000_xaaa_aaaa_dddd_dddd_UC_38: 01174 case CMD_r110_0001_xaaa_aaaa_dddd_dddd_UC_39: 01175 case CMD_r110_0010_xaaa_aaaa_dddd_dddd_UC_40: 01176 case CMD_r110_0011_xaaa_aaaa_dddd_dddd_UC_41: 01177 case CMD_r110_0100_xaaa_aaaa_dddd_dddd_UC_42: 01178 case CMD_r110_0101_xaaa_aaaa_dddd_dddd_UC_43: 01179 case CMD_r110_0110_xaaa_aaaa_dddd_dddd_UC_44: 01180 case CMD_r110_0111_xaaa_aaaa_dddd_dddd_UC_45: 01181 case CMD_r110_1000_xaaa_aaaa_dddd_dddd_UC_46: 01182 case CMD_r110_1001_xaaa_aaaa_dddd_dddd_UC_47: 01183 case CMD_r110_1010_xaaa_aaaa_dddd_dddd_UC_48: 01184 case CMD_r110_1011_xaaa_aaaa_dddd_dddd_UC_49: 01185 case CMD_r110_1100_xaaa_aaaa_dddd_dddd_UC_50: 01186 case CMD_r110_1101_xaaa_aaaa_dddd_dddd_UC_51: 01187 case CMD_r110_1110_xaaa_aaaa_dddd_dddd_UC_52: 01188 case CMD_r110_1111_xxxx_xxxx_xaaa_aaaa_UCADDR: 01189 return 16; // 16-bit register size 01190 } 01191 } 01192 01193 //---------------------------------------- 01194 // Decode operation from commandByte 01195 // 01196 // @return operation such as idle, read register, write register, etc. 01197 MAX11410::MAX11410_CMDOP_enum_t MAX11410::DecodeCommand(MAX11410_CMD_enum_t commandByte) 01198 { 01199 01200 //---------------------------------------- 01201 // decode operation from command byte 01202 switch (commandByte & 0x80) 01203 { 01204 default: 01205 case CMDOP_0aaa_aaaa_WriteRegister: 01206 return CMDOP_0aaa_aaaa_WriteRegister; 01207 case CMDOP_1aaa_aaaa_ReadRegister: 01208 return CMDOP_1aaa_aaaa_ReadRegister; 01209 } 01210 } 01211 01212 //---------------------------------------- 01213 // Return the address field of a MAX11410 register 01214 // 01215 // @return register address field as given in datasheet 01216 uint8_t MAX11410::RegAddrOfCommand(MAX11410_CMD_enum_t commandByte) 01217 { 01218 01219 //---------------------------------------- 01220 // extract register address value from command byte 01221 return (uint8_t)((commandByte &~ CMDOP_1aaa_aaaa_ReadRegister) & 0xFF); 01222 } 01223 01224 //---------------------------------------- 01225 // Test whether a command byte is a register read command 01226 // 01227 // @return true if command byte is a register read command 01228 uint8_t MAX11410::IsRegReadCommand(MAX11410_CMD_enum_t commandByte) 01229 { 01230 01231 //---------------------------------------- 01232 // Test whether a command byte is a register read command 01233 return (commandByte & CMDOP_1aaa_aaaa_ReadRegister) ? 1 : 0; 01234 } 01235 01236 //---------------------------------------- 01237 // Test whether a command byte is a register write command 01238 // 01239 // @return true if command byte is a register write command 01240 uint8_t MAX11410::IsRegWriteCommand(MAX11410_CMD_enum_t commandByte) 01241 { 01242 01243 //---------------------------------------- 01244 // Test whether a command byte is a register write command 01245 return (commandByte & CMDOP_1aaa_aaaa_ReadRegister) ? 0 : 1; 01246 } 01247 01248 //---------------------------------------- 01249 // Return the name of a MAX11410 register 01250 // 01251 // @return null-terminated constant C string containing register name or empty string 01252 const char* MAX11410::RegName(MAX11410_CMD_enum_t commandByte) 01253 { 01254 01255 //---------------------------------------- 01256 // switch based on register address value regAddress 01257 commandByte = (MAX11410_CMD_enum_t)((commandByte &~ CMDOP_1aaa_aaaa_ReadRegister) & 0xFF); 01258 switch(commandByte) 01259 { 01260 default: 01261 return ""; // undefined register 01262 case CMD_r000_0000_xxxx_xxdd_PD: return "PD"; 01263 case CMD_r000_0001_xddd_xxdd_CONV_START: return "CONV_START"; 01264 case CMD_r000_0010_xddd_dddd_SEQ_START: return "SEQ_START"; 01265 case CMD_r000_0011_xxxx_xddd_CAL_START: return "CAL_START"; 01266 case CMD_r000_0100_dddd_xddd_GP0_CTRL: return "GP0_CTRL"; 01267 case CMD_r000_0101_dddd_xddd_GP1_CTRL: return "GP1_CTRL"; 01268 case CMD_r000_0110_xddd_xxdd_GP_CONV: return "GP_CONV"; 01269 case CMD_r000_0111_xddd_dddd_GP_SEQ_ADDR: return "GP_SEQ_ADDR"; 01270 case CMD_r000_1000_x0dd_dddd_FILTER: return "FILTER"; 01271 case CMD_r000_1001_dddd_dddd_CTRL: return "CTRL"; 01272 case CMD_r000_1010_dddd_dddd_SOURCE: return "SOURCE"; 01273 case CMD_r000_1011_dddd_dddd_MUX_CTRL0: return "MUX_CTRL0"; 01274 case CMD_r000_1100_dddd_dddd_MUX_CTRL1: return "MUX_CTRL1"; 01275 case CMD_r000_1101_dddd_dddd_MUX_CTRL2: return "MUX_CTRL2"; 01276 case CMD_r000_1110_00ss_0ggg_PGA: return "PGA"; 01277 case CMD_r000_1111_dddd_dddd_WAIT_EXT: return "WAIT_EXT"; 01278 case CMD_r001_0000_xxxx_xxxx_WAIT_START: return "WAIT_START"; 01279 case CMD_r001_0001_xxxx_xxxx_xxxx_xxxx_xxxx_xddd_PART_ID: return "PART_ID"; 01280 case CMD_r001_0010_xxxx_xxxx_dddd_xxdd_dddd_dddd_SYSC_SEL: return "SYSC_SEL"; 01281 case CMD_r001_0011_dddd_dddd_dddd_dddd_dddd_dddd_SYS_OFF_A: return "SYS_OFF_A"; 01282 case CMD_r001_0100_dddd_dddd_dddd_dddd_dddd_dddd_SYS_OFF_B: return "SYS_OFF_B"; 01283 case CMD_r001_0101_dddd_dddd_dddd_dddd_dddd_dddd_SYS_GAIN_A: return "SYS_GAIN_A"; 01284 case CMD_r001_0110_dddd_dddd_dddd_dddd_dddd_dddd_SYS_GAIN_B: return "SYS_GAIN_B"; 01285 case CMD_r001_0111_dddd_dddd_dddd_dddd_dddd_dddd_SELF_OFF: return "SELF_OFF"; 01286 case CMD_r001_1000_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_1: return "SELF_GAIN_1"; 01287 case CMD_r001_1001_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_2: return "SELF_GAIN_2"; 01288 case CMD_r001_1010_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_4: return "SELF_GAIN_4"; 01289 case CMD_r001_1011_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_8: return "SELF_GAIN_8"; 01290 case CMD_r001_1100_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_16: return "SELF_GAIN_16"; 01291 case CMD_r001_1101_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_32: return "SELF_GAIN_32"; 01292 case CMD_r001_1110_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_64: return "SELF_GAIN_64"; 01293 case CMD_r001_1111_dddd_dddd_dddd_dddd_dddd_dddd_SELF_GAIN_128: return "SELF_GAIN_128"; 01294 // Condense register names LTHRESH0..LTHRESH7 from CMD_r010_0000_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH0 01295 case CMD_r010_0000_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH0: 01296 case CMD_r010_0001_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH1: 01297 case CMD_r010_0010_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH2: 01298 case CMD_r010_0011_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH3: 01299 case CMD_r010_0100_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH4: 01300 case CMD_r010_0101_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH5: 01301 case CMD_r010_0110_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH6: 01302 case CMD_r010_0111_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH7: 01303 { 01304 // Condense register names "LTHRESH#" from CMD_r010_0000_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH0 01305 int index = commandByte - CMD_r010_0000_dddd_dddd_dddd_dddd_dddd_dddd_LTHRESH0; 01306 static char retValueString[] = "LTHRESH#"; 01307 retValueString[7] = (index % 10) + '0'; 01308 return retValueString; 01309 }; 01310 // Condense register names UTHRESH0..UTHRESH7 from CMD_r010_1000_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH0 01311 case CMD_r010_1000_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH0: 01312 case CMD_r010_1001_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH1: 01313 case CMD_r010_1010_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH2: 01314 case CMD_r010_1011_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH3: 01315 case CMD_r010_1100_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH4: 01316 case CMD_r010_1101_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH5: 01317 case CMD_r010_1110_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH6: 01318 case CMD_r010_1111_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH7: 01319 { 01320 // Condense register names "UTHRESH#" from CMD_r010_1000_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH0 01321 int index = commandByte - CMD_r010_1000_dddd_dddd_dddd_dddd_dddd_dddd_UTHRESH0; 01322 static char retValueString[] = "UTHRESH#"; 01323 retValueString[7] = (index % 10) + '0'; 01324 return retValueString; 01325 }; 01326 // Condense register names DATA0..DATA7 from CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0 01327 case CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0: 01328 case CMD_r011_0001_dddd_dddd_dddd_dddd_dddd_dddd_DATA1: 01329 case CMD_r011_0010_dddd_dddd_dddd_dddd_dddd_dddd_DATA2: 01330 case CMD_r011_0011_dddd_dddd_dddd_dddd_dddd_dddd_DATA3: 01331 case CMD_r011_0100_dddd_dddd_dddd_dddd_dddd_dddd_DATA4: 01332 case CMD_r011_0101_dddd_dddd_dddd_dddd_dddd_dddd_DATA5: 01333 case CMD_r011_0110_dddd_dddd_dddd_dddd_dddd_dddd_DATA6: 01334 case CMD_r011_0111_dddd_dddd_dddd_dddd_dddd_dddd_DATA7: 01335 { 01336 // Condense register names "DATA#" from CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0 01337 int index = commandByte - CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0; 01338 static char retValueString[] = "DATA#"; 01339 retValueString[4] = (index % 10) + '0'; 01340 return retValueString; 01341 }; 01342 case CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS: return "STATUS"; 01343 case CMD_r011_1001_dddd_dddd_dddd_dddd_dxxd_dddd_STATUS_IE: return "STATUS_IE"; 01344 // Condense register names UC_00..UC_52 from CMD_r011_1010_xaaa_aaaa_dddd_dddd_UC_0 01345 case CMD_r011_1010_xaaa_aaaa_dddd_dddd_UC_0: 01346 case CMD_r011_1011_xaaa_aaaa_dddd_dddd_UC_1: 01347 case CMD_r011_1100_xaaa_aaaa_dddd_dddd_UC_2: 01348 case CMD_r011_1101_xaaa_aaaa_dddd_dddd_UC_3: 01349 case CMD_r011_1110_xaaa_aaaa_dddd_dddd_UC_4: 01350 case CMD_r011_1111_xaaa_aaaa_dddd_dddd_UC_5: 01351 case CMD_r100_0000_xaaa_aaaa_dddd_dddd_UC_6: 01352 case CMD_r100_0001_xaaa_aaaa_dddd_dddd_UC_7: 01353 case CMD_r100_0010_xaaa_aaaa_dddd_dddd_UC_8: 01354 case CMD_r100_0011_xaaa_aaaa_dddd_dddd_UC_9: 01355 case CMD_r100_0100_xaaa_aaaa_dddd_dddd_UC_10: 01356 case CMD_r100_0101_xaaa_aaaa_dddd_dddd_UC_11: 01357 case CMD_r100_0110_xaaa_aaaa_dddd_dddd_UC_12: 01358 case CMD_r100_0111_xaaa_aaaa_dddd_dddd_UC_13: 01359 case CMD_r100_1000_xaaa_aaaa_dddd_dddd_UC_14: 01360 case CMD_r100_1001_xaaa_aaaa_dddd_dddd_UC_15: 01361 case CMD_r100_1010_xaaa_aaaa_dddd_dddd_UC_16: 01362 case CMD_r100_1011_xaaa_aaaa_dddd_dddd_UC_17: 01363 case CMD_r100_1100_xaaa_aaaa_dddd_dddd_UC_18: 01364 case CMD_r100_1101_xaaa_aaaa_dddd_dddd_UC_19: 01365 case CMD_r100_1110_xaaa_aaaa_dddd_dddd_UC_20: 01366 case CMD_r100_1111_xaaa_aaaa_dddd_dddd_UC_21: 01367 case CMD_r101_0000_xaaa_aaaa_dddd_dddd_UC_22: 01368 case CMD_r101_0001_xaaa_aaaa_dddd_dddd_UC_23: 01369 case CMD_r101_0010_xaaa_aaaa_dddd_dddd_UC_24: 01370 case CMD_r101_0011_xaaa_aaaa_dddd_dddd_UC_25: 01371 case CMD_r101_0100_xaaa_aaaa_dddd_dddd_UC_26: 01372 case CMD_r101_0101_xaaa_aaaa_dddd_dddd_UC_27: 01373 case CMD_r101_0110_xaaa_aaaa_dddd_dddd_UC_28: 01374 case CMD_r101_0111_xaaa_aaaa_dddd_dddd_UC_29: 01375 case CMD_r101_1000_xaaa_aaaa_dddd_dddd_UC_30: 01376 case CMD_r101_1001_xaaa_aaaa_dddd_dddd_UC_31: 01377 case CMD_r101_1010_xaaa_aaaa_dddd_dddd_UC_32: 01378 case CMD_r101_1011_xaaa_aaaa_dddd_dddd_UC_33: 01379 case CMD_r101_1100_xaaa_aaaa_dddd_dddd_UC_34: 01380 case CMD_r101_1101_xaaa_aaaa_dddd_dddd_UC_35: 01381 case CMD_r101_1110_xaaa_aaaa_dddd_dddd_UC_36: 01382 case CMD_r101_1111_xaaa_aaaa_dddd_dddd_UC_37: 01383 case CMD_r110_0000_xaaa_aaaa_dddd_dddd_UC_38: 01384 case CMD_r110_0001_xaaa_aaaa_dddd_dddd_UC_39: 01385 case CMD_r110_0010_xaaa_aaaa_dddd_dddd_UC_40: 01386 case CMD_r110_0011_xaaa_aaaa_dddd_dddd_UC_41: 01387 case CMD_r110_0100_xaaa_aaaa_dddd_dddd_UC_42: 01388 case CMD_r110_0101_xaaa_aaaa_dddd_dddd_UC_43: 01389 case CMD_r110_0110_xaaa_aaaa_dddd_dddd_UC_44: 01390 case CMD_r110_0111_xaaa_aaaa_dddd_dddd_UC_45: 01391 case CMD_r110_1000_xaaa_aaaa_dddd_dddd_UC_46: 01392 case CMD_r110_1001_xaaa_aaaa_dddd_dddd_UC_47: 01393 case CMD_r110_1010_xaaa_aaaa_dddd_dddd_UC_48: 01394 case CMD_r110_1011_xaaa_aaaa_dddd_dddd_UC_49: 01395 case CMD_r110_1100_xaaa_aaaa_dddd_dddd_UC_50: 01396 case CMD_r110_1101_xaaa_aaaa_dddd_dddd_UC_51: 01397 case CMD_r110_1110_xaaa_aaaa_dddd_dddd_UC_52: 01398 { 01399 // Condense register names "UC_##" from CMD_r011_1010_xaaa_aaaa_dddd_dddd_UC_0 01400 int index = commandByte - CMD_r011_1010_xaaa_aaaa_dddd_dddd_UC_0; 01401 static char retValueString[] = "UC_00"; 01402 retValueString[3] = (index / 10) + '0'; 01403 retValueString[4] = (index % 10) + '0'; 01404 return retValueString; 01405 }; 01406 case CMD_r110_1111_xxxx_xxxx_xaaa_aaaa_UCADDR: return "UCADDR"; 01407 } 01408 } 01409 01410 //---------------------------------------- 01411 // Menu item 'XF' 01412 // 01413 // FILTER Select Filter and Rate. 01414 // Sets conversion rate based on RATE, LINEF, and CONV_TYPE value. See Table 9a through Table 9d for details. 01415 // For CONV_TYPE_01_Continuous, linef=LINEF_11_SINC4, rate=RATE_0100 selects output data rate 60SPS. 01416 // 01417 // @param[in] linef = filter type, default=MAX11410::LINEF_enum_t::LINEF_11_SINC4 01418 // @param[in] rate = output data rate selection, default=MAX11410::RATE_enum_t::RATE_0100 01419 // 01420 // @return 1 on success; 0 on failure 01421 uint8_t MAX11410::Configure_FILTER(uint8_t linef, uint8_t rate) 01422 { 01423 01424 //---------------------------------------- 01425 // write8 0x08 FILTER 01426 RegWrite(CMD_r000_1000_x0dd_dddd_FILTER, (uint8_t)(0 01427 | (((uint8_t)linef & 3) << 4) 01428 | (((uint8_t)rate & 15) << 0) 01429 )); 01430 01431 //---------------------------------------- 01432 // success 01433 return 1; 01434 } 01435 01436 //---------------------------------------- 01437 // Menu item 'XP' 01438 // 01439 // PGA Select Gain and Signal Path. 01440 // 01441 // @param[in] sigpath = signal path, default=MAX11410::SIG_PATH_enum_t::SIG_PATH_00_BUFFERED 01442 // @param[in] gain = gain selection, default=MAX11410::GAIN_enum_t::GAIN_000_1 01443 // 01444 // @return 1 on success; 0 on failure 01445 uint8_t MAX11410::Configure_PGA(uint8_t sigpath, uint8_t gain) 01446 { 01447 01448 //---------------------------------------- 01449 // write8 0x0E PGA 01450 RegWrite(CMD_r000_1110_00ss_0ggg_PGA, (uint8_t)(0 01451 | (((uint8_t)sigpath & 2) << 4) 01452 | (((uint8_t)gain & 7) << 0) 01453 )); 01454 01455 //---------------------------------------- 01456 // success 01457 return 1; 01458 } 01459 01460 //---------------------------------------- 01461 // Menu item 'XC' 01462 // 01463 // CTRL Select clock, format, and reference. 01464 // 01465 // @param[in] extclk = external clock enable, default=0 01466 // @param[in] u_bn = unipolar input range enable, default=0 01467 // @param[in] format = offset binary format enable, default=0 01468 // @param[in] refbufp_en = REFP reference buffer enable, default=0 01469 // @param[in] refbufn_en = REFN reference buffer enable, default=0 01470 // @param[in] ref_sel = reference selection, default=MAX11410::REF_SEL_enum_t::REF_SEL_001_REF1P_REF1N 01471 // 01472 // @return 1 on success; 0 on failure 01473 uint8_t MAX11410::Configure_CTRL(uint8_t extclk, uint8_t u_bn, uint8_t format, uint8_t refbufp_en, uint8_t refbufn_en, uint8_t ref_sel) 01474 { 01475 01476 //---------------------------------------- 01477 // shadow of register CMD_r000_1001_dddd_dddd_CTRL 01478 ctrl = (uint8_t)(0 01479 | (((uint8_t)extclk & 1) << 7) 01480 | (((uint8_t)u_bn & 1) << 6) 01481 | (((uint8_t)format & 1) << 5) 01482 | (((uint8_t)refbufp_en & 1) << 4) 01483 | (((uint8_t)refbufn_en & 1) << 3) 01484 | (((uint8_t)ref_sel & 7) << 0) 01485 ); 01486 01487 //---------------------------------------- 01488 // write8 0x09 CTRL 01489 RegWrite(CMD_r000_1001_dddd_dddd_CTRL, ctrl); 01490 01491 //---------------------------------------- 01492 // success 01493 return 1; 01494 } 01495 01496 //---------------------------------------- 01497 // Menu item 'XR' 01498 // 01499 // CTRL select reference, without changing the other fields. 01500 // 01501 // @pre ctrl = shadow of CTRL register 01502 // @param[in] ref_sel = reference selection, default=MAX11410::REF_SEL_enum_t::REF_SEL_001_REF1P_REF1N 01503 // 01504 // @return 1 on success; 0 on failure 01505 uint8_t MAX11410::Configure_CTRL_REF(uint8_t ref_sel) 01506 { 01507 01508 //---------------------------------------- 01509 // shadow of register CMD_r000_1001_dddd_dddd_CTRL 01510 ctrl = (ctrl & ((uint8_t)(~ 7) << 0)) 01511 | (((uint8_t)ref_sel & 7) << 0); 01512 01513 //---------------------------------------- 01514 // write8 0x09 CTRL 01515 RegWrite(CMD_r000_1001_dddd_dddd_CTRL, ctrl); 01516 01517 //---------------------------------------- 01518 // success 01519 return 1; 01520 } 01521 01522 //---------------------------------------- 01523 // Menu item 'XS' 01524 // 01525 // SOURCE Configure voltage bias source, current source, burnout mode 01526 // 01527 // @param[in] vbias_mode = bias voltage mode, default=MAX11410::VBIAS_MODE_enum_t::VBIAS_MODE_00_Active 01528 // @param[in] brn_mode = burnout source mode, default=MAX11410::BRN_MODE_enum_t::BRN_MODE_00_disabled 01529 // @param[in] idac_mode = current source value, default=MAX11410::IDAC_MODE_enum_t::IDAC_MODE_0000_10uA 01530 // 01531 // @return 1 on success; 0 on failure 01532 uint8_t MAX11410::Configure_SOURCE(uint8_t vbias_mode, uint8_t brn_mode, uint8_t idac_mode) 01533 { 01534 01535 //---------------------------------------- 01536 // write8 0x0A SOURCE 01537 RegWrite(CMD_r000_1010_dddd_dddd_SOURCE, (uint8_t)(0 01538 | (((uint8_t)vbias_mode & 3) << 6) 01539 | (((uint8_t)brn_mode & 3) << 4) 01540 | (((uint8_t)idac_mode & 15) << 0) 01541 )); 01542 01543 //---------------------------------------- 01544 // success 01545 return 1; 01546 } 01547 01548 //---------------------------------------- 01549 // Menu item 'XM' 01550 // 01551 // MUX_CTRL0 Select pins for analog input AINP and AINN 01552 // 01553 // @param[in] ainp = channel high side, default=MAX11410::AINP_SEL_enum_t::AINP_SEL_0000_AIN0 01554 // @param[in] ainn = channel low side, default=MAX11410::AINN_SEL_enum_t::AINN_SEL_1010_GND 01555 // 01556 // @return 1 on success; 0 on failure 01557 uint8_t MAX11410::Configure_MUX_CTRL0(uint8_t ainp, uint8_t ainn) 01558 { 01559 01560 //---------------------------------------- 01561 // write8 0x0B MUX_CTRL0 01562 RegWrite(CMD_r000_1011_dddd_dddd_MUX_CTRL0, (uint8_t)(0 01563 | (((uint8_t)ainp & 15) << 4) 01564 | (((uint8_t)ainn & 15) << 0) 01565 )); 01566 01567 //---------------------------------------- 01568 // success 01569 return 1; 01570 } 01571 01572 //---------------------------------------- 01573 // Menu item 'XI' 01574 // 01575 // MUX_CTRL1 Select pins for current source 01576 // 01577 // @param[in] idac1_sel = channel high side, default=MAX11410::IDAC1_SEL_enum_t::IDAC1_SEL_1111_unconnected 01578 // @param[in] idac0_sel = channel low side, default=MAX11410::IDAC0_SEL_enum_t::IDAC0_SEL_1111_unconnected 01579 // 01580 // @return 1 on success; 0 on failure 01581 uint8_t MAX11410::Configure_MUX_CTRL1(uint8_t idac1_sel, uint8_t idac0_sel) 01582 { 01583 01584 //---------------------------------------- 01585 // write8 0x0C MUX_CTRL1 01586 RegWrite(CMD_r000_1100_dddd_dddd_MUX_CTRL1, (uint8_t)(0 01587 | (((uint8_t)idac1_sel & 15) << 4) 01588 | (((uint8_t)idac0_sel & 15) << 0) 01589 )); 01590 01591 //---------------------------------------- 01592 // success 01593 return 1; 01594 } 01595 01596 //---------------------------------------- 01597 // Menu item 'XV' 01598 // 01599 // MUX_CTRL2 Select pins for voltage bias source 01600 // 01601 // @param[in] vbias_ain7_ain0_bitmap = bit map of AIN7..AIN0 enables for voltage bias, default=0 01602 // 01603 // @return 1 on success; 0 on failure 01604 uint8_t MAX11410::Configure_MUX_CTRL2(uint8_t vbias_ain7_ain0_bitmap) 01605 { 01606 01607 //---------------------------------------- 01608 // write8 0x0D MUX_CTRL2 01609 RegWrite(CMD_r000_1101_dddd_dddd_MUX_CTRL2, vbias_ain7_ain0_bitmap); 01610 01611 //---------------------------------------- 01612 // success 01613 return 1; 01614 } 01615 01616 //---------------------------------------- 01617 // Menu item 'X0' 01618 // 01619 // CAL_START Calibrate Self Offset and Gain. 01620 // 01621 // @return 1 on success; 0 on failure 01622 uint8_t MAX11410::Calibrate_Self_Offset_Gain(void) 01623 { 01624 01625 //---------------------------------------- 01626 // write8 0x03 CAL_START -- RegWrite will poll status until CAL_RDY 01627 RegWrite(CMD_r000_0011_xxxx_xddd_CAL_START, (uint8_t)CAL_TYPE_000_SELF_CAL); 01628 01629 //---------------------------------------- 01630 // success 01631 return 1; 01632 } 01633 01634 //---------------------------------------- 01635 // Menu item 'X1' 01636 // 01637 // CAL_START Calibrate Selected PGA. 01638 // 01639 // @return 1 on success; 0 on failure 01640 uint8_t MAX11410::Calibrate_PGA_Gain(void) 01641 { 01642 01643 //---------------------------------------- 01644 // write8 0x03 CAL_START -- RegWrite will poll status until CAL_RDY 01645 RegWrite(CMD_r000_0011_xxxx_xddd_CAL_START, (uint8_t)CAL_TYPE_001_PGA_GAIN); 01646 01647 //---------------------------------------- 01648 // success 01649 return 1; 01650 } 01651 01652 //---------------------------------------- 01653 // CAL_START Calibrate System Offset A. 01654 // 01655 // @return 1 on success; 0 on failure 01656 uint8_t MAX11410::Calibrate_System_Offset_A(void) 01657 { 01658 01659 //---------------------------------------- 01660 // write8 0x03 CAL_START -- RegWrite will poll status until CAL_RDY 01661 RegWrite(CMD_r000_0011_xxxx_xddd_CAL_START, (uint8_t)CAL_TYPE_100_SYS_OFF_A); 01662 01663 //---------------------------------------- 01664 // success 01665 return 1; 01666 } 01667 01668 //---------------------------------------- 01669 // CAL_START Calibrate System Gain A. 01670 // 01671 // @return 1 on success; 0 on failure 01672 uint8_t MAX11410::Calibrate_System_Gain_A(void) 01673 { 01674 01675 //---------------------------------------- 01676 // write8 0x03 CAL_START -- RegWrite will poll status until CAL_RDY 01677 RegWrite(CMD_r000_0011_xxxx_xddd_CAL_START, (uint8_t)CAL_TYPE_101_SYS_GAIN_A); 01678 01679 //---------------------------------------- 01680 // success 01681 return 1; 01682 } 01683 01684 //---------------------------------------- 01685 // CAL_START Calibrate System Offset B. 01686 // 01687 // @return 1 on success; 0 on failure 01688 uint8_t MAX11410::Calibrate_System_Offset_B(void) 01689 { 01690 01691 //---------------------------------------- 01692 // write8 0x03 CAL_START -- RegWrite will poll status until CAL_RDY 01693 RegWrite(CMD_r000_0011_xxxx_xddd_CAL_START, (uint8_t)CAL_TYPE_110_SYS_OFF_B); 01694 01695 //---------------------------------------- 01696 // success 01697 return 1; 01698 } 01699 01700 //---------------------------------------- 01701 // CAL_START Calibrate System Gain B. 01702 // 01703 // @return 1 on success; 0 on failure 01704 uint8_t MAX11410::Calibrate_System_Gain_B(void) 01705 { 01706 01707 //---------------------------------------- 01708 // write8 0x03 CAL_START -- RegWrite will poll status until CAL_RDY 01709 RegWrite(CMD_r000_0011_xxxx_xddd_CAL_START, (uint8_t)CAL_TYPE_111_SYS_GAIN_B); 01710 01711 //---------------------------------------- 01712 // success 01713 return 1; 01714 } 01715 01716 //---------------------------------------- 01717 // Menu item '$' -> AINcode[0], AINcode[1], AINcode[2], AINcode[3], AINcode[4], AINcode[5], AINcode[6], AINcode[7], AINcode[8], AINcode[9], AINcode[10] 01718 // 01719 // Measure all ADC channels in sequence. 01720 // Diagnostic output pulse on GP0 for each channel's measurement. 01721 // Diagnostic output pulse on GP1 for entire loop. 01722 // 01723 // @post AINcode[0..10]: measurement result LSB code 01724 // 01725 // @return 1 on success; 0 on failure 01726 uint8_t MAX11410::Read_All_Voltages(void) 01727 { 01728 01729 //---------------------------------------- 01730 // scan AIN0..AIN9 01731 // 01732 // diagnostic GPIO pulse on MAX11410 GP1 pin (0xc3 = logic 0, 0xc4 = logic 1) 01733 RegWrite(CMD_r000_0101_dddd_xddd_GP1_CTRL, 0xc3); // GP1 = 0 01734 // 01735 const MAX11410_AINN_SEL_enum_t ainn = AINN_SEL_1010_GND; 01736 for(uint8_t ainp = /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_0000_AIN0; ainp <= /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD; ainp++) 01737 { 01738 // diagnostic GPIO pulse on MAX11410 GP0 pin (0xc3 = logic 0, 0xc4 = logic 1) 01739 RegWrite(CMD_r000_0100_dddd_xddd_GP0_CTRL, 0xc3); // GP0 = 0 01740 // 01741 Measure_Voltage((MAX11410_AINP_SEL_enum_t)ainp, ainn); 01742 // @post AINcode[ainp]: measurement result LSB code 01743 // 01744 // diagnostic GPIO pulse on MAX11410 GP0 pin (0xc3 = logic 0, 0xc4 = logic 1) 01745 RegWrite(CMD_r000_0100_dddd_xddd_GP0_CTRL, 0xc4); // GP0 = 1 01746 // 01747 } 01748 // diagnostic GPIO pulse on MAX11410 GP1 pin (0xc3 = logic 0, 0xc4 = logic 1) 01749 RegWrite(CMD_r000_0101_dddd_xddd_GP1_CTRL, 0xc4); // GP1 = 1 01750 // 01751 01752 //---------------------------------------- 01753 // success 01754 return 1; 01755 } 01756 01757 //---------------------------------------- 01758 // Menu item 'V' 01759 // Trigger Measurement for voltage input. 01760 // 01761 // Example code for typical voltage measurement. 01762 // 01763 // @pre external connection REF2P-REF2N is a reference voltage 01764 // @pre VRef = Voltage of REF input, in Volts 01765 // @pre v_filter = filter register configuration, 0x34 for LINEF_11_SINC4 RATE_0100 output data rate 60SPS 01766 // @pre v_ctrl = ctrl register configuration, 0x02 for bipolar REF_SEL_010_REF2P_REF2N 01767 // @pre v_pga = pga register configuration, 0x00 for SIG_PATH_00_BUFFERED GAIN_000_1 01768 // @param[in] ainp = channel high side, default=AINP_SEL_0000_AIN0 01769 // @param[in] ainn = channel low side, default=AINN_SEL_1010_GND 01770 // @post AINcode[ainp]: measurement result LSB code 01771 // 01772 // Output data rate (sample rate) is determined by filter register. 01773 // filter register configuration in Measure_Voltage CONV_TYPE_01_Continuous 01774 // v_filter=0x00 -- LINEF_00_50Hz_60Hz_FIR RATE_0000 | 1.1SPS 01775 // v_filter=0x01 -- LINEF_00_50Hz_60Hz_FIR RATE_0001 | 2.1SPS 01776 // v_filter=0x02 -- LINEF_00_50Hz_60Hz_FIR RATE_0010 | 4.2SPS 01777 // v_filter=0x03 -- LINEF_00_50Hz_60Hz_FIR RATE_0011 | 8.4SPS 01778 // v_filter=0x04 -- LINEF_00_50Hz_60Hz_FIR RATE_0100 | 16.8SPS 01779 // v_filter=0x10 -- LINEF_01_50Hz_FIR RATE_0000 | 1.3SPS 01780 // v_filter=0x11 -- LINEF_01_50Hz_FIR RATE_0001 | 2.7SPS 01781 // v_filter=0x12 -- LINEF_01_50Hz_FIR RATE_0010 | 5.3SPS 01782 // v_filter=0x13 -- LINEF_01_50Hz_FIR RATE_0011 | 10.7SPS 01783 // v_filter=0x14 -- LINEF_01_50Hz_FIR RATE_0100 | 21.3SPS 01784 // v_filter=0x15 -- LINEF_01_50Hz_FIR RATE_0101 | 40.0SPS 01785 // v_filter=0x20 -- LINEF_10_60Hz_FIR RATE_0000 | 1.3SPS 01786 // v_filter=0x21 -- LINEF_10_60Hz_FIR RATE_0001 | 2.7SPS 01787 // v_filter=0x22 -- LINEF_10_60Hz_FIR RATE_0010 | 5.3SPS 01788 // v_filter=0x23 -- LINEF_10_60Hz_FIR RATE_0011 | 10.7SPS 01789 // v_filter=0x24 -- LINEF_10_60Hz_FIR RATE_0100 | 21.3SPS 01790 // v_filter=0x25 -- LINEF_10_60Hz_FIR RATE_0101 | 40.0SPS 01791 // v_filter=0x30 -- LINEF_11_SINC4 RATE_0000 | 4SPS 01792 // v_filter=0x31 -- LINEF_11_SINC4 RATE_0001 | 10SPS 01793 // v_filter=0x32 -- LINEF_11_SINC4 RATE_0010 | 20SPS 01794 // v_filter=0x33 -- LINEF_11_SINC4 RATE_0011 | 40SPS 01795 // v_filter=0x34 --*LINEF_11_SINC4 RATE_0100 | 60SPS 01796 // v_filter=0x35 -- LINEF_11_SINC4 RATE_0101 | 120SPS 01797 // v_filter=0x36 -- LINEF_11_SINC4 RATE_0110 | 240SPS 01798 // v_filter=0x37 -- LINEF_11_SINC4 RATE_0111 | 480SPS 01799 // v_filter=0x38 -- LINEF_11_SINC4 RATE_1000 | 960SPS 01800 // v_filter=0x39 -- LINEF_11_SINC4 RATE_1001 | 1920SPS 01801 // 01802 // @return ideal voltage calculated from raw LSB code and reference voltage 01803 double MAX11410::Measure_Voltage(MAX11410_AINP_SEL_enum_t ainp, MAX11410_AINN_SEL_enum_t ainn) 01804 { 01805 01806 //---------------------------------------- 01807 // restrict channel selection to valid index range 01808 if ((uint8_t)ainp > /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD) 01809 { 01810 ainp = /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD; 01811 } 01812 01813 //---------------------------------------- 01814 // restrict channel selection to valid index range 01815 if ((uint8_t)ainn > /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND) 01816 { 01817 ainn = /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND; 01818 } 01819 01820 //---------------------------------------- 01821 // write8 0x0B MUX_CTRL0 = 0x0A to select AINP=AIN0 and AINN=GND 01822 Configure_MUX_CTRL0((uint8_t)ainp, (uint8_t)ainn); 01823 01824 //---------------------------------------- 01825 // write8 0x09 CTRL to select reference and Data Format (Unipolar or Bipolar) 01826 RegWrite(CMD_r000_1001_dddd_dddd_CTRL, v_ctrl); 01827 ctrl = v_ctrl; 01828 01829 //---------------------------------------- 01830 // write8 0x0E PGA and update pgaGain 01831 Configure_PGA( 01832 ((v_pga >> 4) & 2), // sigpath 01833 ( v_pga & 7)); // gain 01834 01835 //---------------------------------------- 01836 // write8 0x08 FILTER to select output data rate 01837 RegWrite(CMD_r000_1000_x0dd_dddd_FILTER, v_filter); 01838 01839 //---------------------------------------- 01840 // write8 0x01 CONV_START = 0x01 to set Conversion Mode = Continuous 01841 RegWrite(CMD_r000_0001_xddd_xxdd_CONV_START, 0x01); 01842 01843 //---------------------------------------- 01844 // purge old data from data0 register 01845 RegRead(CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0, &AINcode[((int)ainp & 0x0F)]); 01846 data0 = AINcode[((int)ainp & 0x0F)]; 01847 01848 //---------------------------------------- 01849 // read24 0x80|0x38 STATUS (%SW 0xB8 0 0 0) 01850 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 01851 01852 //---------------------------------------- 01853 // wait until STATUS_enum_t::STATUS_000010_DATA_RDY indicates data is available 01854 // A bad SPI interface can cause bit slippage, which makes this loop get stuck. Expect *PART_ID? = 0x000F02 01855 // while ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000010_DATA_RDY) == 0) { 01856 // possible infinite loop; need a timeout or futility countdown to escape 01857 for (int futility_countdown = loop_limit; 01858 ((futility_countdown > 0) && 01859 ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000010_DATA_RDY) == 0)); 01860 futility_countdown--) 01861 { 01862 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 01863 #if 1 01864 // improve response time at the cost of more program size 01865 if (futility_countdown < (loop_limit - 5)) { 01866 wait_ms(1); // timing delay function, platform-specific 01867 } 01868 if (futility_countdown < (loop_limit - 10)) { 01869 wait_ms(2); // timing delay function, platform-specific 01870 } 01871 if (futility_countdown < (loop_limit - 15)) { 01872 wait_ms(5); // timing delay function, platform-specific 01873 } 01874 if (futility_countdown < (loop_limit - 20)) { 01875 wait_ms(10); // timing delay function, platform-specific 01876 } 01877 if (futility_countdown < (loop_limit - 25)) { 01878 wait_ms(20); // timing delay function, platform-specific 01879 } 01880 if (futility_countdown < (loop_limit - 30)) { 01881 wait_ms(50); // timing delay function, platform-specific 01882 } 01883 if (futility_countdown < (loop_limit - 35)) { 01884 wait_ms(100); // timing delay function, platform-specific 01885 } 01886 #else 01887 if (loop_limit > 5) { 01888 wait_ms(20); // timing delay function, platform-specific 01889 } 01890 if (loop_limit > 10) { 01891 wait_ms(50); // timing delay function, platform-specific 01892 } 01893 if (loop_limit > 30) { 01894 wait_ms(100); // timing delay function, platform-specific 01895 } 01896 #endif 01897 } 01898 01899 //---------------------------------------- 01900 // read24 0x80|0x30 DATA0 (%SW 0xB0 0 0 0): AINcode[ainp] = measurement 01901 RegRead(CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0, &AINcode[((int)ainp & 0x0F)]); 01902 data0 = AINcode[((int)ainp & 0x0F)]; 01903 01904 //---------------------------------------- 01905 // ideal voltage calculated from raw LSB code and reference voltage 01906 return VoltageOfCode(AINcode[((int)ainp & 0x0F)]); 01907 } 01908 01909 //---------------------------------------- 01910 // Menu item 'R' -> rtd_ohm, rtd_degc 01911 // Trigger Measurement for Resistive Temperature Device (RTD). 01912 // 01913 // Example code for typical RTD measurement. 01914 // 01915 // @pre external connection REF1P-REF1N is a reference resistor 01916 // @pre ref1_v = reference resistance in ohms, default=4999 01917 // @pre rtd_filter = filter register configuration, 0x34 for LINEF_11_SINC4 RATE_0100 output data rate 60SPS 01918 // @pre rtd_ctrl = ctrl register configuration, 0x40 for ref0_v, 0x41 for ref1_v, 0x42 for ref2_v 01919 // @pre rtd_souce = souce register configuration, 0x0B for IDAC_MODE_1011_400uA 01920 // @pre rtd_pga = pga register configuration, 0x21 for SIG_PATH_10_PGA GAIN_001_2 01921 // @param[in] rtd_iout = channel RTD high side force, default=AINP_SEL_0111_AIN7 01922 // @param[in] rtd_ainp = channel RTD high side sense, default=AINP_SEL_1000_AIN8 01923 // @param[in] rtd_ainn = channel RTD low side, default=AINN_SEL_1001_AIN9 01924 // @post AINcode[rtd_ainp]: measurement result LSB code 01925 // @post rtd_ohm: measurement result resistance in Ohms 01926 // @post rtd_degc: Temperature calculated from RTD Resistance; Thermocouple Cold Junction, in degrees C 01927 // 01928 // Output data rate (sample rate) is determined by filter register. 01929 // filter register configuration in Measure_RTD CONV_TYPE_01_Continuous 01930 // rtd_filter=0x00 -- LINEF_00_50Hz_60Hz_FIR RATE_0000 | 1.1SPS 01931 // rtd_filter=0x01 -- LINEF_00_50Hz_60Hz_FIR RATE_0001 | 2.1SPS 01932 // rtd_filter=0x02 -- LINEF_00_50Hz_60Hz_FIR RATE_0010 | 4.2SPS 01933 // rtd_filter=0x03 -- LINEF_00_50Hz_60Hz_FIR RATE_0011 | 8.4SPS 01934 // rtd_filter=0x04 -- LINEF_00_50Hz_60Hz_FIR RATE_0100 | 16.8SPS 01935 // rtd_filter=0x10 -- LINEF_01_50Hz_FIR RATE_0000 | 1.3SPS 01936 // rtd_filter=0x11 -- LINEF_01_50Hz_FIR RATE_0001 | 2.7SPS 01937 // rtd_filter=0x12 -- LINEF_01_50Hz_FIR RATE_0010 | 5.3SPS 01938 // rtd_filter=0x13 -- LINEF_01_50Hz_FIR RATE_0011 | 10.7SPS 01939 // rtd_filter=0x14 -- LINEF_01_50Hz_FIR RATE_0100 | 21.3SPS 01940 // rtd_filter=0x15 -- LINEF_01_50Hz_FIR RATE_0101 | 40.0SPS 01941 // rtd_filter=0x20 -- LINEF_10_60Hz_FIR RATE_0000 | 1.3SPS 01942 // rtd_filter=0x21 -- LINEF_10_60Hz_FIR RATE_0001 | 2.7SPS 01943 // rtd_filter=0x22 -- LINEF_10_60Hz_FIR RATE_0010 | 5.3SPS 01944 // rtd_filter=0x23 -- LINEF_10_60Hz_FIR RATE_0011 | 10.7SPS 01945 // rtd_filter=0x24 -- LINEF_10_60Hz_FIR RATE_0100 | 21.3SPS 01946 // rtd_filter=0x25 -- LINEF_10_60Hz_FIR RATE_0101 | 40.0SPS 01947 // rtd_filter=0x30 -- LINEF_11_SINC4 RATE_0000 | 4SPS 01948 // rtd_filter=0x31 -- LINEF_11_SINC4 RATE_0001 | 10SPS 01949 // rtd_filter=0x32 -- LINEF_11_SINC4 RATE_0010 | 20SPS 01950 // rtd_filter=0x33 -- LINEF_11_SINC4 RATE_0011 | 40SPS 01951 // rtd_filter=0x34 --*LINEF_11_SINC4 RATE_0100 | 60SPS 01952 // rtd_filter=0x35 -- LINEF_11_SINC4 RATE_0101 | 120SPS 01953 // rtd_filter=0x36 -- LINEF_11_SINC4 RATE_0110 | 240SPS 01954 // rtd_filter=0x37 -- LINEF_11_SINC4 RATE_0111 | 480SPS 01955 // rtd_filter=0x38 -- LINEF_11_SINC4 RATE_1000 | 960SPS 01956 // rtd_filter=0x39 -- LINEF_11_SINC4 RATE_1001 | 1920SPS 01957 // 01958 // @return resistance calculated from raw LSB code and reference resistance 01959 double MAX11410::Measure_RTD(MAX11410_AINP_SEL_enum_t rtd_iout, MAX11410_AINP_SEL_enum_t rtd_ainp, MAX11410_AINN_SEL_enum_t rtd_ainn) 01960 { 01961 01962 //---------------------------------------- 01963 // restrict channel selection to valid index range 01964 if ((uint8_t)rtd_iout > /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD) 01965 { 01966 rtd_iout = /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD; 01967 } 01968 01969 //---------------------------------------- 01970 // restrict channel selection to valid index range 01971 if ((uint8_t)rtd_ainp > /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD) 01972 { 01973 rtd_ainp = /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD; 01974 } 01975 01976 //---------------------------------------- 01977 // restrict channel selection to valid index range 01978 if ((uint8_t)rtd_ainn > /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND) 01979 { 01980 rtd_ainn = /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND; 01981 } 01982 01983 //---------------------------------------- 01984 // write8 0x08 FILTER to select output data rate 01985 RegWrite(CMD_r000_1000_x0dd_dddd_FILTER, rtd_filter); 01986 01987 //---------------------------------------- 01988 // write8 0x09 CTRL to select reference resistor REF1P/REF1N; Data Format = Unipolar 01989 RegWrite(CMD_r000_1001_dddd_dddd_CTRL, rtd_ctrl); 01990 ctrl = rtd_ctrl; 01991 01992 //---------------------------------------- 01993 // write8 0x0A SOURCE to select IDAC_MODE 400uA; AIN9=2.000V, AIN8(PT100)=2.040V, AIN8(PT1000)=2.400V 01994 RegWrite(CMD_r000_1010_dddd_dddd_SOURCE, rtd_source); 01995 01996 //---------------------------------------- 01997 // write8 0x0B MUX_CTRL0 = 0x89 to select AINP=AIN8 and AINN=AIN9 01998 Configure_MUX_CTRL0((uint8_t)rtd_ainp, (uint8_t)rtd_ainn); 01999 02000 //---------------------------------------- 02001 // write8 0x0C MUX_CTRL1 = 0xF7 to select IDAC1_SEL=NC, IDAC0_SEL=AIN7 02002 Configure_MUX_CTRL1((uint8_t)IDAC1_SEL_1111_unconnected, (uint8_t)rtd_iout); 02003 02004 //---------------------------------------- 02005 // write8 0x0E PGA and update pgaGain 02006 Configure_PGA( 02007 ((rtd_pga >> 4) & 2), // sigpath 02008 ( rtd_pga & 7)); // gain 02009 02010 //---------------------------------------- 02011 // diagnostic GPIO pulse on GP1 during RTD power-up interval rtd_ms 02012 RegWrite(CMD_r000_0101_dddd_xddd_GP1_CTRL, 0xc3); // diagnostic GPIO pulse GP1 02013 // write8 0x05 GP1_CTRL (%SW 0x05 0xc3) 11000 output 011 logic 0 02014 02015 //---------------------------------------- 02016 // timing delay after enable RTD bias current 02017 wait_ms(rtd_ms); // timing delay function, platform-specific 02018 02019 //---------------------------------------- 02020 // diagnostic GPIO pulse on GP1 during RTD power-up interval rtd_ms 02021 RegWrite(CMD_r000_0101_dddd_xddd_GP1_CTRL, 0xc4); // diagnostic GPIO pulse GP1 02022 // write8 0x05 GP1_CTRL (%SW 0x05 0xc4) 11000 output 100 logic 1 02023 02024 //---------------------------------------- 02025 // write8 0x01 CONV_START = 0x01 to set Conversion Mode = Continuous 02026 RegWrite(CMD_r000_0001_xddd_xxdd_CONV_START, 0x01); 02027 02028 //---------------------------------------- 02029 // purge old data from data0 register 02030 RegRead(CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0, &AINcode[((int)rtd_ainp & 0x0F)]); 02031 data0 = AINcode[((int)rtd_ainp & 0x0F)]; 02032 02033 //---------------------------------------- 02034 // read24 0x80|0x38 STATUS (%SW 0xB8 0 0 0) 02035 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 02036 02037 //---------------------------------------- 02038 // wait until STATUS_enum_t::STATUS_000010_DATA_RDY indicates data is available 02039 // A bad SPI interface can cause bit slippage, which makes this loop get stuck. Expect *PART_ID? = 0x000F02 02040 // while ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000010_DATA_RDY) == 0) { 02041 // possible infinite loop; need a timeout or futility countdown to escape 02042 for (int futility_countdown = loop_limit; 02043 ((futility_countdown > 0) && 02044 ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000010_DATA_RDY) == 0)); 02045 futility_countdown--) 02046 { 02047 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 02048 } 02049 02050 //---------------------------------------- 02051 // read24 0x80|0x30 DATA0 (%SW 0xB0 0 0 0): AINcode[ainp] = measurement 02052 RegRead(CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0, &AINcode[((int)rtd_ainp & 0x0F)]); 02053 data0 = AINcode[((int)rtd_ainp & 0x0F)]; 02054 02055 //---------------------------------------- 02056 // turn off RTD bias current to avoid self-heating (unless rtd_ms is 0) 02057 if (rtd_ms != 0) 02058 { 02059 // write8 0x0C MUX_CTRL1 = 0xFF to select IDAC1_SEL=NC, IDAC0_SEL=NC 02060 Configure_MUX_CTRL1((uint8_t)IDAC1_SEL_1111_unconnected, (uint8_t)IDAC0_SEL_1111_unconnected); 02061 } 02062 02063 //---------------------------------------- 02064 // resistance calculated from raw LSB code and ref1_v reference resistance in ohms 02065 rtd_ohm = VoltageOfCode(AINcode[((int)rtd_ainp & 0x0F)]); 02066 TemperatureOfRTD(rtd_ohm); // calculate rtd_degc 02067 return rtd_ohm; 02068 } 02069 02070 //---------------------------------------- 02071 // Return the physical temperature corresponding to measured resistance 02072 // of a PT1000 type Resistive Temperature Device (RTD). 02073 // 02074 // @param[in] rtd_ohm = RTD resistance in ohms, default=1000 02075 // @post rtd_degc: Temperature calculated from RTD Resistance; Thermocouple Cold Junction, in degrees C 02076 // 02077 // @return ideal temperature in degrees C, calculated from RTD resistance in ohms 02078 // @test group RTD_PT1000 // PT1000 type Resistive Temperature Device (RTD) 02079 // @test group RTD_PT1000 tinyTester.blink_time_msec = 20 // quickly speed through the software verification 02080 // @test group RTD_PT1000 TemperatureOfRTD_PT1000(842.94) expect -40.0 within 0.1 // PT-1000 RTD at -40C 02081 // @test group RTD_PT1000 TemperatureOfRTD_PT1000(1000.0) expect 0.0 within 0.1 // PT-1000 RTD at 0C 02082 // @test group RTD_PT1000 TemperatureOfRTD_PT1000(1097.3) expect 25.0 within 0.1 // PT-1000 RTD at 25C 02083 // @test group RTD_PT1000 TemperatureOfRTD_PT1000(1328.1) expect 85.0 within 0.1 // PT-1000 RTD at 85C 02084 // @test group RTD_PT1000 TemperatureOfRTD_PT1000(1479.5) expect 125.0 within 0.1 // PT-1000 RTD at 125C 02085 // @test group RTD_PT1000 tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 02086 // 02087 double MAX11410::TemperatureOfRTD_PT1000(double rtd_ohm) 02088 { 02089 02090 //---------------------------------------- 02091 // Temperature from RTD Resistance maths 02092 // ITS-90 PT-1000 RTD 02093 double R0 = 1000.0; 02094 double a = 3.9083e-3; 02095 double b = -5.7750e-7; 02096 // calculate T from R and R0 02097 double sqrtTerm = sqrt(R0*R0 * a*a - 4*R0*b*(R0 - rtd_ohm)); 02098 double denominator = 2 * R0 * b; 02099 rtd_degc = ((-R0 * a) + (sqrtTerm)) / denominator; 02100 return rtd_degc; 02101 } 02102 02103 //---------------------------------------- 02104 // Return the physical temperature corresponding to measured resistance 02105 // of a PT100 type Resistive Temperature Device (RTD). 02106 // 02107 // @param[in] rtd_ohm = RTD resistance in ohms, default=100 02108 // @post rtd_degc: Temperature calculated from RTD Resistance; Thermocouple Cold Junction, in degrees C 02109 // 02110 // @return ideal temperature in degrees C, calculated from RTD resistance in ohms 02111 // @test group RTD_PT100 // PT100 type Resistive Temperature Device (RTD) 02112 // @test group RTD_PT100 tinyTester.blink_time_msec = 20 // quickly speed through the software verification 02113 // @test group RTD_PT100 TemperatureOfRTD_PT100(84.294) expect -40.0 within 0.1 // PT-100 RTD at -40C 02114 // @test group RTD_PT100 TemperatureOfRTD_PT100(100.00) expect 0.0 within 0.1 // PT-100 RTD at 0C 02115 // @test group RTD_PT100 TemperatureOfRTD_PT100(109.73) expect 25.0 within 0.1 // PT-100 RTD at 25C 02116 // @test group RTD_PT100 TemperatureOfRTD_PT100(132.81) expect 85.0 within 0.1 // PT-100 RTD at 85C 02117 // @test group RTD_PT100 TemperatureOfRTD_PT100(147.95) expect 125.0 within 0.1 // PT-100 RTD at 125C 02118 // @test group RTD_PT100 tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 02119 // 02120 double MAX11410::TemperatureOfRTD_PT100(double rtd_ohm) 02121 { 02122 02123 //---------------------------------------- 02124 // Temperature from RTD Resistance maths 02125 // ITS-90 PT-100 RTD 02126 double R0 = 100.0; 02127 double a = 3.9083e-3; 02128 double b = -5.7750e-7; 02129 // calculate T from R and R0 02130 double sqrtTerm = sqrt(R0*R0 * a*a - 4*R0*b*(R0 - rtd_ohm)); 02131 double denominator = 2 * R0 * b; 02132 rtd_degc = ((-R0 * a) + (sqrtTerm)) / denominator; 02133 return rtd_degc; 02134 } 02135 02136 //---------------------------------------- 02137 // Return the physical temperature corresponding to measured resistance 02138 // of a PT100 or PT1000 type Resistive Temperature Device (RTD). 02139 // 02140 // @param[in] rtd_ohm = RTD resistance in ohms, default=100 02141 // @post rtd_degc: Temperature calculated from RTD Resistance; Thermocouple Cold Junction, in degrees C 02142 // 02143 // @return ideal temperature in degrees C, calculated from RTD resistance in ohms 02144 // @test group RTD // Verify function TemperatureOfRTD 02145 // @test group RTD tinyTester.blink_time_msec = 20 // quickly speed through the software verification 02146 // @test group RTD TemperatureOfRTD(84.294) expect -40.0 within 0.1 // PT-100 RTD at -40C 02147 // @test group RTD TemperatureOfRTD(100.00) expect 0.0 within 0.1 // PT-100 RTD at 0C 02148 // @test group RTD TemperatureOfRTD(109.73) expect 25.0 within 0.1 // PT-100 RTD at 25C 02149 // @test group RTD TemperatureOfRTD(132.81) expect 85.0 within 0.1 // PT-100 RTD at 85C 02150 // @test group RTD TemperatureOfRTD(147.95) expect 125.0 within 0.1 // PT-100 RTD at 125C 02151 // @test group RTD TemperatureOfRTD(842.94) expect -40.0 within 0.1 // PT-1000 RTD at -40C 02152 // @test group RTD TemperatureOfRTD(1000.0) expect 0.0 within 0.1 // PT-1000 RTD at 0C 02153 // @test group RTD TemperatureOfRTD(1097.3) expect 25.0 within 0.1 // PT-1000 RTD at 25C 02154 // @test group RTD TemperatureOfRTD(1328.1) expect 85.0 within 0.1 // PT-1000 RTD at 85C 02155 // @test group RTD TemperatureOfRTD(1479.5) expect 125.0 within 0.1 // PT-1000 RTD at 125C 02156 // @test group RTD tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 02157 // 02158 double MAX11410::TemperatureOfRTD(double rtd_ohm) 02159 { 02160 02161 //---------------------------------------- 02162 // return TemperatureOfRTD_PT100 or TemperatureOfRTD_PT1000 02163 if (rtd_ohm > 500.0) 02164 { 02165 return TemperatureOfRTD_PT1000(rtd_ohm); 02166 } 02167 else 02168 { 02169 return TemperatureOfRTD_PT100(rtd_ohm); 02170 } 02171 } 02172 02173 //---------------------------------------- 02174 // Menu item 'TM' -> tc_v, tc_delta_degc, tc_degc 02175 // Trigger Measurement for Thermocouple 02176 // 02177 // Example code for typical Thermocouple measurement. 02178 // An RTD measures the "cold junction" where TC connects to the board, 02179 // and the TC measures the temperature difference above the cold junction. 02180 // 02181 // @param[in] tc_ainp = channel of Thermocouple high side, default=AINP_SEL_0101_AIN5 02182 // @param[in] tc_ainn = channel of Thermocouple low side, default=AINN_SEL_0110_AIN6 02183 // @param[in] rtd_iout = channel RTD high side force, default=AINP_SEL_0111_AIN7 02184 // @param[in] rtd_ainp = channel RTD high side sense, default=AINP_SEL_1000_AIN8 02185 // @param[in] rtd_ainn = channel RTD low side, default=AINN_SEL_1001_AIN9 02186 // @post AINcode[tc_ainp]: measurement result LSB code 02187 // @post tc_v: raw thermocouple voltage in Volts 02188 // @post tc_delta_degc: temperature in degC above cold junction 02189 // @post tc_degc: temperature in degC 02190 // 02191 // @return 1 on success; 0 on failure 02192 double MAX11410::Measure_Thermocouple(MAX11410_AINP_SEL_enum_t tc_ainp, MAX11410_AINN_SEL_enum_t tc_ainn, MAX11410_AINP_SEL_enum_t rtd_iout, MAX11410_AINP_SEL_enum_t rtd_ainp, MAX11410_AINN_SEL_enum_t rtd_ainn) 02193 { 02194 02195 //---------------------------------------- 02196 // restrict channel selection to valid index range 02197 if ((uint8_t)tc_ainp > /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD) 02198 { 02199 tc_ainp = /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD; 02200 } 02201 02202 //---------------------------------------- 02203 // restrict channel selection to valid index range 02204 if ((uint8_t)tc_ainn > /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND) 02205 { 02206 tc_ainn = /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND; 02207 } 02208 02209 //---------------------------------------- 02210 // restrict channel selection to valid index range 02211 if ((uint8_t)rtd_iout > /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD) 02212 { 02213 rtd_iout = /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD; 02214 } 02215 02216 //---------------------------------------- 02217 // restrict channel selection to valid index range 02218 if ((uint8_t)rtd_ainp > /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD) 02219 { 02220 rtd_ainp = /* MAX11410_AINP_SEL_enum_t:: */ AINP_SEL_1010_AVDD; 02221 } 02222 02223 //---------------------------------------- 02224 // restrict channel selection to valid index range 02225 if ((uint8_t)rtd_ainn > /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND) 02226 { 02227 rtd_ainn = /* MAX11410_AINN_SEL_enum_t:: */ AINN_SEL_1010_GND; 02228 } 02229 02230 //---------------------------------------- 02231 // write8 0x0B MUX_CTRL0 = 0x0A to select AINP=AIN0 and AINN=GND 02232 Configure_MUX_CTRL0((uint8_t)tc_ainp, (uint8_t)tc_ainn); 02233 02234 //---------------------------------------- 02235 // write8 0x09 CTRL to select reference REF2P/REF2N; Data Format = Bipolar 2's Complement 02236 Configure_CTRL(/*extclk*/ 0, /*u_bn*/ 0, /*format*/ 0, 02237 /*refbufp_en*/ 0, /*refbufn_en*/ 0, 02238 /*ref_sel*/ (uint8_t)REF_SEL_010_REF2P_REF2N); 02239 02240 //---------------------------------------- 02241 // write8 0x0E PGA 02242 Configure_PGA((uint8_t) /* MAX11410_SIG_PATH_enum_t:: */ SIG_PATH_00_BUFFERED, 02243 (uint8_t) /* MAX11410_GAIN_enum_t:: */ GAIN_000_1); 02244 02245 //---------------------------------------- 02246 // write8 0x08 FILTER = 0x34 to select RATE_0100, LINEF_11_SINC4 60SPS (given CONV_TYPE_01_Continuous) 02247 Configure_FILTER((uint8_t) /* MAX11410::MAX11410_LINEF_enum_t:: */ LINEF_11_SINC4, 02248 (uint8_t) /* MAX11410::MAX11410_RATE_enum_t:: */ RATE_0100); 02249 02250 //---------------------------------------- 02251 // write8 0x01 CONV_START = 0x01 to set Conversion Mode = Continuous 02252 RegWrite(CMD_r000_0001_xddd_xxdd_CONV_START, 0x01); 02253 02254 //---------------------------------------- 02255 // purge old data from data0 register 02256 RegRead(CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0, &AINcode[((int)tc_ainp & 0x0F)]); 02257 data0 = AINcode[((int)tc_ainp & 0x0F)]; 02258 02259 //---------------------------------------- 02260 // read24 0x80|0x38 STATUS (%SW 0xB8 0 0 0) 02261 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 02262 02263 //---------------------------------------- 02264 // wait until STATUS_enum_t::STATUS_000010_DATA_RDY indicates data is available 02265 // A bad SPI interface can cause bit slippage, which makes this loop get stuck. Expect *PART_ID? = 0x000F02 02266 // while ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000010_DATA_RDY) == 0) { 02267 // possible infinite loop; need a timeout or futility countdown to escape 02268 for (int futility_countdown = loop_limit; 02269 ((futility_countdown > 0) && 02270 ((status & /* MAX11410_STATUS_enum_t:: */ STATUS_000010_DATA_RDY) == 0)); 02271 futility_countdown--) 02272 { 02273 RegRead(CMD_r011_1000_dddd_dddd_dddd_dddd_dxxx_dddd_STATUS, &status); 02274 } 02275 02276 //---------------------------------------- 02277 // read24 0x80|0x30 DATA0 (%SW 0xB0 0 0 0): AINcode[tc_ainp] = measurement 02278 RegRead(CMD_r011_0000_dddd_dddd_dddd_dddd_dddd_dddd_DATA0, &AINcode[((int)tc_ainp & 0x0F)]); 02279 data0 = AINcode[((int)tc_ainp & 0x0F)]; 02280 02281 //---------------------------------------- 02282 // ideal voltage calculated from raw LSB code and reference voltage 02283 tc_v = VoltageOfCode(AINcode[((int)tc_ainp & 0x0F)]); 02284 02285 //---------------------------------------- 02286 // ideal voltage calculated from raw LSB code and reference voltage 02287 tc_delta_degc = TemperatureOfTC_TypeK(tc_v); 02288 02289 //---------------------------------------- 02290 // ideal voltage calculated from raw LSB code and reference voltage 02291 tc_degc = rtd_degc + tc_delta_degc; 02292 02293 //---------------------------------------- 02294 // ideal voltage calculated from raw LSB code and reference voltage 02295 return tc_v; 02296 } 02297 02298 //---------------------------------------- 02299 // Return the physical temperature corresponding to measured voltage 02300 // of a type K Thermocouple (TC). 02301 // 02302 // @pre {0}.rtd_degc = cold junction temperature, in degrees C 02303 // @param[in] tc_v = Thermocouple voltage in volts, default=0.0254 02304 // 02305 // @return ideal temperature in degrees C, calculated from RTD resistance in ohms 02306 // @test group TC_1 // Verify Thermocouple function TemperatureOfTC_TypeK 02307 // @test group TC_2 // Verify Thermocouple function TemperatureOfTC_TypeK in more detail 02308 // @test group TC_1 tinyTester.blink_time_msec = 20 // quickly speed through the software verification 02309 // @test group TC_1 TemperatureOfTC_TypeK(0.000e-3) expect 0.0 within 0.1 // TC_TypeK at 0C = 0.000mV 02310 // @test group TC_1 TemperatureOfTC_TypeK(0.039e-3) expect 1.0 within 0.1 // TC_TypeK at 1C = 0.039mV 02311 // @test group TC_1 TemperatureOfTC_TypeK(0.079e-3) expect 2.0 within 0.1 // TC_TypeK at 2C = 0.079mV 02312 // @test group TC_1 TemperatureOfTC_TypeK(0.119e-3) expect 3.0 within 0.1 // TC_TypeK at 3C = 0.119mV 02313 // @test group TC_2 TemperatureOfTC_TypeK(0.158e-3) expect 4.0 within 0.1 // TC_TypeK at 4C = 0.158mV 02314 // @test group TC_2 TemperatureOfTC_TypeK(0.198e-3) expect 5.0 within 0.1 // TC_TypeK at 5C = 0.198mV 02315 // @test group TC_2 TemperatureOfTC_TypeK(0.238e-3) expect 6.0 within 0.1 // TC_TypeK at 6C = 0.238mV 02316 // @test group TC_2 TemperatureOfTC_TypeK(0.2775e-3) expect 7.0 within 0.1 // TC_TypeK at 7C = 0.2775mV 02317 // @test group TC_2 TemperatureOfTC_TypeK(0.317e-3) expect 8.0 within 0.1 // TC_TypeK at 8C = 0.317mV 02318 // @test group TC_2 TemperatureOfTC_TypeK(0.357e-3) expect 9.0 within 0.1 // TC_TypeK at 9C = 0.357mV 02319 // @test group TC_1 TemperatureOfTC_TypeK(0.397e-3) expect 10.0 within 0.1 // TC_TypeK at 10C = 0.397mV 02320 // @test group TC_1 TemperatureOfTC_TypeK(0.798e-3) expect 20.0 within 0.1 // TC_TypeK at 20C = 0.798mV 02321 // @test group TC_1 TemperatureOfTC_TypeK(1.081e-3) expect 27.0 within 0.1 // TC_TypeK at 27C = 1.081mV 02322 // @test group TC_1 TemperatureOfTC_TypeK(1.203e-3) expect 30.0 within 0.1 // TC_TypeK at 30C = 1.203mV 02323 // @test group TC_1 TemperatureOfTC_TypeK(1.612e-3) expect 40.0 within 0.1 // TC_TypeK at 40C = 1.612mV 02324 // @test group TC_1 TemperatureOfTC_TypeK(2.023e-3) expect 50.0 within 0.1 // TC_TypeK at 50C = 2.023mV 02325 // @test group TC_1 TemperatureOfTC_TypeK(2.436e-3) expect 60.0 within 0.1 // TC_TypeK at 60C = 2.436mV 02326 // @test group TC_1 TemperatureOfTC_TypeK(2.851e-3) expect 70.0 within 0.1 // TC_TypeK at 70C = 2.851mV 02327 // @test group TC_1 TemperatureOfTC_TypeK(3.267e-3) expect 80.0 within 0.1 // TC_TypeK at 80C = 3.267mV 02328 // @test group TC_1 TemperatureOfTC_TypeK(3.682e-3) expect 90.0 within 0.1 // TC_TypeK at 90C = 3.682mV 02329 // @test group TC_1 TemperatureOfTC_TypeK(4.096e-3) expect 100.0 within 0.1 // TC_TypeK at 100C = 4.096mV 02330 // @test group TC_2 TemperatureOfTC_TypeK(4.509e-3) expect 110.0 within 0.1 // TC_TypeK at 110C = 4.509mV 02331 // @test group TC_2 TemperatureOfTC_TypeK(4.920e-3) expect 120.0 within 0.1 // TC_TypeK at 120C = 4.920mV 02332 // @test group TC_2 TemperatureOfTC_TypeK(5.328e-3) expect 130.0 within 0.1 // TC_TypeK at 130C = 5.328mV 02333 // @test group TC_2 TemperatureOfTC_TypeK(5.735e-3) expect 140.0 within 0.1 // TC_TypeK at 140C = 5.735mV 02334 // @test group TC_2 TemperatureOfTC_TypeK(6.138e-3) expect 150.0 within 0.1 // TC_TypeK at 150C = 6.138mV 02335 // @test group TC_2 TemperatureOfTC_TypeK(6.540e-3) expect 160.0 within 0.1 // TC_TypeK at 160C = 6.540mV 02336 // @test group TC_2 TemperatureOfTC_TypeK(6.941e-3) expect 170.0 within 0.1 // TC_TypeK at 170C = 6.941mV 02337 // @test group TC_2 TemperatureOfTC_TypeK(7.340e-3) expect 180.0 within 0.1 // TC_TypeK at 180C = 7.340mV 02338 // @test group TC_1 TemperatureOfTC_TypeK(7.739e-3) expect 190.0 within 0.1 // TC_TypeK at 190C = 7.739mV 02339 // @test group TC_1 TemperatureOfTC_TypeK(8.138e-3) expect 200.0 within 0.1 // TC_TypeK at 200C = 8.138mV 02340 // @test group TC_1 TemperatureOfTC_TypeK(8.539e-3) expect 210.0 within 0.1 // TC_TypeK at 210C = 8.539mV 02341 // @test group TC_1 TemperatureOfTC_TypeK(8.940e-3) expect 220.0 within 0.1 // TC_TypeK at 220C = 8.940mV 02342 // @test group TC_2 TemperatureOfTC_TypeK(9.343e-3) expect 230.0 within 0.1 // TC_TypeK at 230C = 9.343mV 02343 // @test group TC_2 TemperatureOfTC_TypeK(9.747e-3) expect 240.0 within 0.1 // TC_TypeK at 240C = 9.747mV 02344 // @test group TC_2 TemperatureOfTC_TypeK(10.153e-3) expect 250.0 within 0.1 // TC_TypeK at 250C = 10.153mV 02345 // @test group TC_2 TemperatureOfTC_TypeK(10.561e-3) expect 260.0 within 0.1 // TC_TypeK at 260C = 10.561mV 02346 // @test group TC_2 TemperatureOfTC_TypeK(10.971e-3) expect 270.0 within 0.1 // TC_TypeK at 270C = 10.971mV 02347 // @test group TC_2 TemperatureOfTC_TypeK(11.382e-3) expect 280.0 within 0.1 // TC_TypeK at 280C = 11.382mV 02348 // @test group TC_2 TemperatureOfTC_TypeK(11.795e-3) expect 290.0 within 0.1 // TC_TypeK at 290C = 11.795mV 02349 // @test group TC_1 TemperatureOfTC_TypeK(12.209e-3) expect 300.0 within 0.1 // TC_TypeK at 300C = 12.209mV 02350 // @test group TC_2 TemperatureOfTC_TypeK(14.293e-3) expect 350.0 within 0.1 // TC_TypeK at 350C = 14.293mV 02351 // @test group TC_1 TemperatureOfTC_TypeK(16.397e-3) expect 400.0 within 0.1 // TC_TypeK at 400C = 16.397mV 02352 // @test group TC_1 TemperatureOfTC_TypeK(18.516e-3) expect 450.0 within 0.1 // TC_TypeK at 450C = 18.516mV 02353 // @test group TC_1 TemperatureOfTC_TypeK(20.218e-3) expect 490.0 // TC_TypeK at 490C = 20.218mV 02354 // @test group TC_1 tinyTester.blink_time_msec = 75 // default 75 resume hardware self test 02355 // 02356 double MAX11410::TemperatureOfTC_TypeK(double tc_v) 02357 { 02358 02359 //---------------------------------------- 02360 // Temperature from TC_TypeK voltage maths 02361 // define standard TC_TypeK coefficients 02362 // ITS-90 Thermocouple Inverse Polynomial for a Type K thermocouple 02363 // calculate deltaT from tc_v 02364 // 02365 // Voltage range -5891uV < tc_v < 0uV, 02366 // Temperature Range -200 deg C to 0 deg C 02367 static double coefficients_TCtypeK_V_lt_0[] = { 02368 0.00000, 02369 2.5173462e-2, 02370 -1.1662878e-6, 02371 -1.0833638e-9, 02372 -8.9773540e-13, 02373 -3.7342377e-16, 02374 -8.6632643e-20, 02375 -1.0450598e-23, 02376 -5.1920577e-28, 02377 }; 02378 // 02379 // Voltage range 0uV < tc_v < 20.644uV, 02380 // Temperature Range 0 deg C to 500 deg C 02381 static double coefficients_TCtypeK_0_lt_V_lt_20u644V[] = { 02382 0.00000, 02383 2.508355e-2, 02384 7.860106e-8, 02385 -2.503131e-10, 02386 8.315270e-14, 02387 -1.228034e-17, 02388 9.804036e-22, 02389 -4.413030e-26, 02390 1.057734e-30, 02391 -1.052755e-35, 02392 }; 02393 // 02394 // Voltage range 20.6440uV < tc_v < 54.886uV, 02395 // Temperature Range 500 deg C to 1372 deg C 02396 static double coefficients_TCtypeK_20u644V_lt_V_lt_54u886V[] = { 02397 -1.318058e2, 02398 4.830222e-2, 02399 -1.646031e-6, 02400 5.464731e-11, 02401 -9.650715e-16, 02402 8.802193e-21, 02403 -3.110810e-26, 02404 }; 02405 // 02406 double deltaT = 0; 02407 double thermocouple_voltage_uV = tc_v * 1e6; 02408 if (thermocouple_voltage_uV < 0) 02409 { 02410 // Voltage range -5891uV < DMMavg < 0uV, Temperature Range -200 deg C to 0 deg C 02411 deltaT = temperatureDegC_polynomial(thermocouple_voltage_uV, 9, coefficients_TCtypeK_V_lt_0); 02412 } 02413 else if (thermocouple_voltage_uV > 20644) 02414 { 02415 // Voltage range 206440uV < DMMavg < 54886uV, Temperature Range 500 deg C to 1372 deg C 02416 deltaT = temperatureDegC_polynomial(thermocouple_voltage_uV, 7, coefficients_TCtypeK_20u644V_lt_V_lt_54u886V); 02417 } 02418 else 02419 { 02420 // Voltage range 0uV < DMMavg < 20.644uV, Temperature Range 0 deg C to 500 deg C 02421 deltaT = temperatureDegC_polynomial(thermocouple_voltage_uV, 10, coefficients_TCtypeK_0_lt_V_lt_20u644V); 02422 } 02423 return deltaT; // + rtd_degc; // cold junction 02424 } 02425 02426 //---------------------------------------- 02427 // Calculate temperature in degrees C from input voltage, 02428 // using a given set of polynomial coefficients. 02429 // For example: 02430 // 02431 // t = coefficients[0] + coefficients[1] * DMMavg + coefficients[2] * DmMMavg**2 02432 // 02433 // @param[in] thermocouple_voltage_uV = Thermocouple voltage in microvolts 02434 // 02435 // @return ideal temperature in degrees C, calculated from polynomial coefficients 02436 // 02437 double MAX11410::temperatureDegC_polynomial(double thermocouple_voltage_uV, int num_coefficients, double coefficients[]) 02438 { 02439 02440 //---------------------------------------- 02441 // Temperature from polynomial coefficients maths 02442 double temperatureDegC = 0; 02443 int index; 02444 for (index = num_coefficients-1; index >= 0; index--) 02445 { 02446 temperatureDegC = (temperatureDegC * thermocouple_voltage_uV) + coefficients[index]; 02447 } 02448 return temperatureDegC; 02449 } 02450 02451 02452 // End of file
Generated on Thu Jul 14 2022 04:24:15 by
1.7.2
MAX11410BOB