A collection of Analog Devices drivers for the mbed platform
Embed:
(wiki syntax)
Show/hide line numbers
AD7124_Diag.cpp
00001 /** 00002 * @file ad7124_diag.cpp 00003 * @brief Source file for the AD7124 wrapper used by the driver diag 00004 * @author Analog Devices Inc. 00005 * 00006 * For support please go to: 00007 * Github: https://github.com/analogdevicesinc/mbed-adi 00008 * Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers 00009 * More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all 00010 00011 ******************************************************************************** 00012 * Copyright 2016(c) Analog Devices, Inc. 00013 * 00014 * All rights reserved. 00015 * 00016 * Redistribution and use in source and binary forms, with or without 00017 * modification, are permitted provided that the following conditions are met: 00018 * - Redistributions of source code must retain the above copyright 00019 * notice, this list of conditions and the following disclaimer. 00020 * - Redistributions in binary form must reproduce the above copyright 00021 * notice, this list of conditions and the following disclaimer in 00022 * the documentation and/or other materials provided with the 00023 * distribution. 00024 * - Neither the name of Analog Devices, Inc. nor the names of its 00025 * contributors may be used to endorse or promote products derived 00026 * from this software without specific prior written permission. 00027 * - The use of this software may or may not infringe the patent rights 00028 * of one or more patent holders. This license does not release you 00029 * from the requirement that you obtain separate licenses from these 00030 * patent holders to use this software. 00031 * - Use of the software either in source or binary form, must be run 00032 * on or directly connected to an Analog Devices Inc. component. 00033 * 00034 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR 00035 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 00036 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00037 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, 00038 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00039 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR 00040 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00041 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00042 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00043 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00044 * 00045 ********************************************************************************/ 00046 00047 #include "mbed.h" 00048 #include <stdio.h> 00049 #include <vector> 00050 #include <string> 00051 #include "AD7124_Diag.h" 00052 00053 #include "../../../libraries/Thermocouple/Thermocouple.h" 00054 00055 00056 extern Serial pc; 00057 extern vector<string> cmdbuffer; 00058 00059 //#define CALIBRATION 00060 00061 AD7124_Diag::AD7124_Diag(AD7124& ad) : 00062 dut(ad) 00063 { 00064 00065 } 00066 00067 void AD7124_Diag::setup() 00068 { 00069 dut.frequency(500000); 00070 dut.Setup(); 00071 } 00072 00073 void AD7124_Diag::mvpInit() 00074 { 00075 uint32_t setValue; 00076 enum AD7124::ad7124_registers regNr; 00077 dut.frequency(500000); 00078 00079 /* Set Config_0 0x19*/ 00080 regNr = AD7124::AD7124_Config_0; //Select Config_0 register 00081 setValue = dut.ReadDeviceRegister(regNr); 00082 setValue |= AD7124_CFG_REG_BIPOLAR; //Select bipolar operation 00083 setValue |= AD7124_CFG_REG_BURNOUT(0); //Burnout current source off 00084 setValue |= AD7124_CFG_REG_REF_BUFP; 00085 setValue |= AD7124_CFG_REG_REF_BUFM; 00086 setValue |= AD7124_CFG_REG_AIN_BUFP; //Buffer AIN5 00087 setValue |= AD7124_CFG_REG_AINN_BUFM; //Buffer AIN4 00088 setValue |= AD7124_CFG_REG_REF_SEL(2); //Select REFIN1(+)/REFIN1(-) internal reference 00089 setValue |= AD7124_CFG_REG_PGA(0); 00090 setValue &= 0xFFFF; 00091 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00092 00093 /* Set Channel_0 register 0x09*/ 00094 regNr = AD7124::AD7124_Channel_0; 00095 setValue = dut.ReadDeviceRegister(regNr); 00096 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00097 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00098 setValue |= AD7124_CH_MAP_REG_AINP(0); // Set AIN4 as positive input 00099 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00100 setValue &= 0xFFFF; 00101 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00102 00103 regNr = AD7124::AD7124_Channel_1; 00104 setValue = dut.ReadDeviceRegister(regNr); 00105 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00106 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00107 setValue |= AD7124_CH_MAP_REG_AINP(1); // Set AIN4 as positive input 00108 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00109 setValue &= 0xFFFF; 00110 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00111 00112 regNr = AD7124::AD7124_Channel_2; 00113 setValue = dut.ReadDeviceRegister(regNr); 00114 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00115 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00116 setValue |= AD7124_CH_MAP_REG_AINP(2); // Set AIN4 as positive input 00117 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00118 setValue &= 0xFFFF; 00119 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00120 00121 regNr = AD7124::AD7124_Channel_3; 00122 setValue = dut.ReadDeviceRegister(regNr); 00123 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00124 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00125 setValue |= AD7124_CH_MAP_REG_AINP(3); // Set AIN4 as positive input 00126 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00127 setValue &= 0xFFFF; 00128 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00129 00130 regNr = AD7124::AD7124_Channel_4; 00131 setValue = dut.ReadDeviceRegister(regNr); 00132 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00133 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00134 setValue |= AD7124_CH_MAP_REG_AINP(4); // Set AIN4 as positive input 00135 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00136 setValue &= 0xFFFF; 00137 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00138 00139 00140 regNr = AD7124::AD7124_Channel_5; 00141 setValue = dut.ReadDeviceRegister(regNr); 00142 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00143 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00144 setValue |= AD7124_CH_MAP_REG_AINP(5); // Set AIN4 as positive input 00145 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00146 setValue &= 0xFFFF; 00147 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00148 00149 00150 regNr = AD7124::AD7124_Channel_6; 00151 setValue = dut.ReadDeviceRegister(regNr); 00152 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00153 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00154 setValue |= AD7124_CH_MAP_REG_AINP(6); // Set AIN4 as positive input 00155 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00156 setValue &= 0xFFFF; 00157 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00158 00159 regNr = AD7124::AD7124_Channel_7; 00160 setValue = dut.ReadDeviceRegister(regNr); 00161 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00162 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00163 setValue |= AD7124_CH_MAP_REG_AINP(7); // Set AIN4 as positive input 00164 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00165 setValue &= 0xFFFF; 00166 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00167 00168 regNr = AD7124::AD7124_Channel_8; 00169 setValue = dut.ReadDeviceRegister(regNr); 00170 //setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00171 setValue |= AD7124_CH_MAP_REG_SETUP(0); // Select setup0 00172 setValue |= AD7124_CH_MAP_REG_AINP(14); // Set AIN4 as positive input 00173 setValue |= AD7124_CH_MAP_REG_AINM(15); // Set AIN5 as negative input 00174 setValue &= 0xFFFF; 00175 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00176 00177 00178 /* Set Config_0 0x19*/ 00179 #if 0 00180 regNr = AD7124::AD7124_Config_1; //Select Config_0 register 00181 setValue = dut.ReadDeviceRegister(regNr); 00182 setValue |= AD7124_CFG_REG_BIPOLAR; //Select bipolar operation 00183 setValue |= AD7124_CFG_REG_BURNOUT(0); //Burnout current source off 00184 setValue |= AD7124_CFG_REG_REF_BUFP; 00185 setValue |= AD7124_CFG_REG_REF_BUFM; 00186 setValue |= AD7124_CFG_REG_AIN_BUFP; //Buffer AIN5 00187 setValue |= AD7124_CFG_REG_AINN_BUFM; //Buffer AIN4 00188 setValue |= AD7124_CFG_REG_REF_SEL(2); //Select REFIN1(+)/REFIN1(-) internal reference 00189 setValue &= 0xFFFF; 00190 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00191 #endif 00192 00193 #ifdef CALIBRATION 00194 // start calibration 00195 regNr = AD7124::AD7124_Offset_0; 00196 setValue = 0x800000; 00197 dut.WriteDeviceRegister(regNr, setValue);// Write data to ADC 00198 00199 // internal fullscale before zero scale 00200 pc.printf("\r\n Gain before cali :%x", dut.ReadDeviceRegister(AD7124::AD7124_Gain_0)); 00201 regNr = AD7124::AD7124_ADC_Control;//Select ADC_Control register 00202 setValue = AD7124_ADC_CTRL_REG_MODE(6); 00203 setValue |= AD7124_ADC_CTRL_REG_REF_EN; 00204 setValue &= 0xFFFF; 00205 dut.WriteDeviceRegister(regNr, setValue);// Write data to ADC 00206 //dut.WaitForConvReady(10000); 00207 wait_ms(2000); 00208 00209 pc.printf("\r\n Gain:%x", dut.ReadDeviceRegister(AD7124::AD7124_Gain_0)); 00210 00211 pc.printf("\r\n Offset before cali:%x", dut.ReadDeviceRegister(AD7124::AD7124_Offset_0)); 00212 // internal zeroscale 00213 regNr = AD7124::AD7124_ADC_Control;//Select ADC_Control register 00214 setValue = AD7124_ADC_CTRL_REG_MODE(5); 00215 setValue |= AD7124_ADC_CTRL_REG_REF_EN; 00216 setValue &= 0xFFFF; 00217 dut.WriteDeviceRegister(regNr, setValue);// Write data to ADC 00218 wait_ms(2000); 00219 pc.printf("\r\n Offset:%x\r\n", dut.ReadDeviceRegister(AD7124::AD7124_Offset_0)); 00220 00221 // end of calibration 00222 00223 #endif 00224 00225 /* Set IO_Control_1 0x03 */ 00226 regNr = AD7124::AD7124_IOCon1; //Select IO_Control_1 register 00227 setValue = dut.ReadDeviceRegister(regNr); 00228 setValue |= AD7124_IO_CTRL1_REG_IOUT0(0x4);// set IOUT0 current to 500uA 00229 setValue |= AD7124_IO_CTRL1_REG_IOUT_CH0(0x1); 00230 setValue &= 0xFFFFFF; 00231 dut.WriteDeviceRegister(regNr, setValue);// Write data to ADC 00232 #if 0 00233 setValue = 0; 00234 regNr = AD7124::AD7124_Channel_1; 00235 00236 /* Set Channel_1 register 0x0A*/ 00237 00238 setValue = dut.ReadDeviceRegister( regNr ); 00239 setValue |= (uint32_t)AD7124_CH_MAP_REG_CH_ENABLE;//Enable channel1 00240 setValue |= AD7124_CH_MAP_REG_SETUP(1);// Select setup1 00241 setValue |= AD7124_CH_MAP_REG_AINP(2);// Set AIN2 as positive input 00242 setValue |= AD7124_CH_MAP_REG_AINM(1);// Set AIN1 as negative input 00243 setValue &= 0xFFFF; 00244 dut.WriteDeviceRegister(regNr, setValue);// Write data to ADC 00245 00246 /* Set Config_1 0x1A*/ 00247 regNr = AD7124::AD7124_Config_1; //Select Config_1 register 00248 setValue = dut.ReadDeviceRegister(regNr); 00249 setValue |= AD7124_CFG_REG_BIPOLAR;//Select bipolar operation 00250 setValue |= AD7124_CFG_REG_BURNOUT(0);//Burnout current source off 00251 setValue |= AD7124_CFG_REG_REF_BUFP; 00252 setValue |= AD7124_CFG_REG_REF_BUFM; 00253 setValue |= AD7124_CFG_REG_AIN_BUFP;//Buffer AIN2 00254 setValue |= AD7124_CFG_REG_AINN_BUFM;//Buffer AIN1 00255 setValue |= AD7124_CFG_REG_REF_SEL(2);//Select internal reference 00256 setValue &= 0xFFFF; 00257 dut.WriteDeviceRegister(regNr, setValue);// Write data to ADC 00258 #endif 00259 00260 /* Set ADC_Control 0x01 */ 00261 regNr = AD7124::AD7124_ADC_Control; //Select ADC_Control register 00262 setValue = dut.ReadDeviceRegister(regNr); 00263 setValue |= AD7124_ADC_CTRL_REG_DATA_STATUS; // set data status bit in order to check on which channel the conversion is 00264 setValue |= AD7124_ADC_CTRL_REG_REF_EN; 00265 setValue &= 0xFFC3; 00266 setValue |= AD7124_ADC_CTRL_REG_MODE(1); 00267 setValue &= 0xFFFF; 00268 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00269 } 00270 00271 void AD7124_Diag::write_reg() 00272 { 00273 uint8_t reg = strtol(cmdbuffer[1].c_str(), NULL, 16); 00274 uint32_t regData = strtol(cmdbuffer[2].c_str(), NULL, 16); 00275 //dut.write_reg(reg, regData); 00276 dut.WriteDeviceRegister(static_cast<AD7124::ad7124_registers>(reg), 00277 regData); 00278 pc.printf("Wrote mode"); 00279 } 00280 void AD7124_Diag::read_reg() 00281 { 00282 uint8_t regVal = strtol(cmdbuffer[1].c_str(), NULL, 16); 00283 pc.printf("Mode reg: %x ", 00284 dut.ReadDeviceRegister( 00285 static_cast<AD7124::ad7124_registers>(regVal))); 00286 } 00287 void AD7124_Diag::reset() 00288 { 00289 dut.frequency(500000); 00290 dut.Reset(); 00291 pc.printf("Reseted AD7124"); 00292 } 00293 00294 float AD7124_Diag::data_to_voltage(uint32_t data) 00295 { 00296 data = data & 0xFFFFFF; 00297 return ((data / static_cast<float>(0xFFFFFF / 2)) - 1) * (2.5 / 1); 00298 } 00299 00300 void AD7124_Diag::enable_channel(int channel) 00301 { 00302 AD7124::ad7124_registers regNr = static_cast<AD7124::ad7124_registers> (AD7124::AD7124_Channel_0 + channel); //Select ADC_Control register 00303 uint32_t setValue = dut.ReadDeviceRegister(regNr); 00304 setValue |= (uint32_t) AD7124_CH_MAP_REG_CH_ENABLE; //Enable channel0 00305 setValue &= 0xFFFF; 00306 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00307 } 00308 00309 void AD7124_Diag::disable_channel(int channel) 00310 { 00311 AD7124::ad7124_registers regNr = static_cast<AD7124::ad7124_registers> (AD7124::AD7124_Channel_0 + channel); //Select ADC_Control register 00312 uint32_t setValue = dut.ReadDeviceRegister(regNr); 00313 setValue &= (~(uint32_t) AD7124_CH_MAP_REG_CH_ENABLE); //Enable channel0 00314 setValue &= 0xFFFF; 00315 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00316 } 00317 00318 void AD7124_Diag::enable_current_source(int current_source_channel) 00319 { 00320 AD7124::ad7124_registers regNr = AD7124::AD7124_IOCon1; //Select ADC_Control register 00321 uint32_t setValue = dut.ReadDeviceRegister(regNr); 00322 setValue &= ~(AD7124_IO_CTRL1_REG_IOUT_CH0(0xF)); 00323 setValue |= AD7124_IO_CTRL1_REG_IOUT_CH0(current_source_channel);// set IOUT0 current to 500uA 00324 setValue &= 0xFFFFFF; 00325 00326 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC 00327 pc.printf("Enabled 500uA current source on channel %d\r\n", current_source_channel); 00328 } 00329 00330 00331 #define R2 (1600.0) 00332 #define RTD_SLOPE (15/39.0) 00333 #define RTD_CONSTANT (1039.0) 00334 #define RTD_CONVERSION(R1) RTD_SLOPE * (R1-RTD_CONSTANT) 00335 float convert_rtd(float volt, float current) 00336 { 00337 float R1 = (volt / current) - R2; 00338 float temp = RTD_CONVERSION(R1); 00339 pc.printf("Resistance of RTD is: %f\r\n", R1); 00340 pc.printf("Temperature is: %f\r\n", temp); 00341 // pc.printf("mV equivalent(poly method) of thermocouple is %f \r\n",Thermocouple_Type_E::convert_inv(temp)); 00342 // pc.printf("mV equivalent(lut method) of thermocouple is %f \r\n",Thermocouple_Type_E::lookup_inv(temp)); 00343 00344 return 0; 00345 } 00346 00347 float cal_current(float volt, float current) 00348 { 00349 float cal_current = volt / R2; 00350 pc.printf("Calibrated current = %f mA \r\n", (cal_current * 1000.0)); 00351 return cal_current; 00352 } 00353 00354 float dummy(float volt, float current) 00355 { 00356 /* Nothing to do */ 00357 return volt; 00358 } 00359 00360 float convert_thermocouple_e(float volt, float current) 00361 { 00362 float mv = volt * 1000; 00363 pc.printf("Voltage in mv = %f\r\n", mv); 00364 // pc.printf("Temperature(lookup) in celsius = %f\r\n", Thermocouple_Type_E::lookup(mv)); 00365 // pc.printf("Temperature(poly) in celsius = %f\r\n\r\n", Thermocouple_Type_E::convert(mv)); 00366 return 0; 00367 } 00368 00369 float convert_thermocouple_k(float volt, float current) 00370 { 00371 float mv = volt * 1000; 00372 pc.printf("Voltage in mv = %f\r\n", mv); 00373 // pc.printf("Temperature(lookup) in celsius = %f\r\n", Thermocouple_Type_K::lookup(mv)); 00374 // pc.printf("Temperature(poly) in celsius = %f\r\n\r\n", Thermocouple_Type_K::convert(mv)); 00375 return 0; 00376 } 00377 00378 00379 float (*conversion_fkt[9])(float volt, float current) = {convert_thermocouple_e, convert_rtd, convert_thermocouple_k, convert_rtd, dummy, convert_rtd, dummy, convert_rtd, cal_current}; 00380 float conversion_results[9]; 00381 00382 void AD7124_Diag::start_single_conversion() 00383 { 00384 AD7124::ad7124_registers regNr = AD7124::AD7124_ADC_Control; //Select ADC_Control register 00385 uint32_t setValue = dut.ReadDeviceRegister(regNr); 00386 setValue &= 0xFFC3; 00387 setValue |= 0x04; //single conversion; 00388 setValue |= 0x1600; 00389 setValue &= 0xFFFF; 00390 dut.WriteDeviceRegister(regNr, setValue); // Write data to ADC*/ 00391 wait_ms(1); 00392 } 00393 00394 void AD7124_Diag::read_data() 00395 { 00396 int32_t data; 00397 float volt; 00398 float cal_current = 0; 00399 00400 for(int i = 0; i < 8; i++) { 00401 if(i % 2 == 0) { 00402 //enable_current_source(i+1); 00403 } else { 00404 enable_current_source(i); 00405 enable_channel(8); // calibration channel 00406 start_single_conversion(); 00407 if (dut.WaitForConvReady(10000) == -3) { 00408 pc.printf("TIMEOUT"); 00409 return; 00410 } 00411 00412 dut.ReadData(&data); 00413 disable_channel(8); 00414 00415 pc.printf("Channel: %d\r\n", data & 0xff); 00416 pc.printf("Data reg: %x \r\n", data); 00417 volt = data_to_voltage(data >> 8); 00418 pc.printf("Voltage = %f\r\n", volt); 00419 cal_current = conversion_fkt[8](volt, 0); 00420 conversion_results[8] = cal_current; 00421 00422 } 00423 00424 enable_channel(i); 00425 start_single_conversion(); 00426 00427 00428 if (dut.WaitForConvReady(10000) == -3) { 00429 pc.printf("TIMEOUT"); 00430 return; 00431 } 00432 00433 dut.ReadData(&data); 00434 00435 disable_channel(i); 00436 00437 00438 pc.printf("Channel: %d\r\n", data & 0xff); 00439 pc.printf("Data reg: %x \r\n", data); 00440 volt = data_to_voltage(data >> 8); 00441 pc.printf("Voltage = %f\r\n", volt); 00442 conversion_results[i] = conversion_fkt[i](volt, cal_current); 00443 pc.printf("\r\n"); 00444 00445 } 00446 } 00447 00448 void AD7124_Diag::read_volt() 00449 { 00450 uint8_t regVal = strtol(cmdbuffer[1].c_str(), NULL, 16); 00451 pc.printf("Data reg: %x ", 00452 dut.ReadDeviceRegister( 00453 static_cast<AD7124::ad7124_registers>(regVal))); 00454 }
Generated on Tue Jul 12 2022 17:59:52 by 1.7.2