AD7798 ADC driver
Embed:
(wiki syntax)
Show/hide line numbers
AD7798.cpp
00001 /***************************************************************************//** 00002 * @file AD7798.c 00003 * @brief Implementation of AD7798 Driver. 00004 * @author 00005 ******************************************************************************** 00006 * Copyright 2012(c) Analog Devices, Inc. 00007 * 00008 * All rights reserved. 00009 * 00010 * Redistribution and use in source and binary forms, with or without 00011 * modification, are permitted provided that the following conditions are met: 00012 * - Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * - Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in 00016 * the documentation and/or other materials provided with the 00017 * distribution. 00018 * - Neither the name of Analog Devices, Inc. nor the names of its 00019 * contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * - The use of this software may or may not infringe the patent rights 00022 * of one or more patent holders. This license does not release you 00023 * from the requirement that you obtain separate licenses from these 00024 * patent holders to use this software. 00025 * - Use of the software either in source or binary form, must be run 00026 * on or directly connected to an Analog Devices Inc. component. 00027 * 00028 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR 00029 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 00030 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00031 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, 00032 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00033 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR 00034 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00035 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00036 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00037 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00038 * 00039 ******************************************************************************** 00040 * SVN Revision: 577 00041 *******************************************************************************/ 00042 00043 /******************************************************************************/ 00044 /* Include Files */ 00045 /******************************************************************************/ 00046 #include "AD7798.h" // AD7798 definitions. 00047 #include <stdio.h> 00048 00049 00050 /***************************************************************************//** 00051 * @brief Initializes the AD7798 and checks if the device is present. 00052 * 00053 * @param None. 00054 * 00055 * @return status - Result of the initialization procedure. 00056 * Example: 1 - if initialization was successful (ID is 0x0B). 00057 * 0 - if initialization was unsuccessful. 00058 *******************************************************************************/ 00059 AD7798::AD7798( PinName CS, PinName MOSI, PinName MISO, PinName SCK): 00060 /*miso(MISO),*/ ad7798(MOSI, MISO, SCK), cs(CS) 00061 { 00062 cs = true; // cs is active low 00063 ad7798.format(8, _SPI_MODE); 00064 } 00065 uint8_t AD7798::init(void) 00066 { 00067 unsigned char status = 0x1; 00068 00069 if ((get_register_value (AD7798_REG_ID, 1) & 0x0F) != AD7798_ID) { 00070 status = 0x0; 00071 } 00072 00073 return(status); 00074 } 00075 00076 /***************************************************************************//** 00077 * @brief Sends 32 consecutive 1's on SPI in order to reset the part. 00078 * 00079 * @param None. 00080 * 00081 * @return None. 00082 *******************************************************************************/ 00083 void AD7798::frequency(int hz) 00084 { 00085 ad7798.frequency(hz); 00086 } 00087 void AD7798::reset(void) 00088 { 00089 unsigned char dataToSend[4] = {0xFF, 0xFF, 0xFF, 0xFF}; 00090 00091 spi_write(dataToSend, 4); 00092 00093 wait_ms(500); 00094 00095 } 00096 /***************************************************************************//** 00097 * @brief Reads the value of the selected register 00098 * 00099 * @param regAddress - The address of the register to read. 00100 * @param size - The size of the register to read. 00101 * 00102 * @return data - The value of the selected register register. 00103 *******************************************************************************/ 00104 uint16_t AD7798::get_register_value(uint8_t regAddress, uint8_t size, bool toggle_cs) 00105 { 00106 unsigned char data[size]; 00107 uint16_t receivedData = 0x00; 00108 unsigned char byte; 00109 00110 data[0] = AD7798_COMM_READ | AD7798_COMM_ADDR(regAddress); 00111 00112 spi_read(data, size, toggle_cs); 00113 00114 receivedData = data[0]; 00115 00116 if(size > 1) { 00117 00118 for(byte = 1; byte < size; byte++) { 00119 receivedData = (receivedData << (byte * 8) | data[byte]); 00120 } 00121 } 00122 return receivedData; 00123 } 00124 /***************************************************************************//** 00125 * @brief Writes the value to the register 00126 * 00127 * @param - regAddress - The address of the register to write to. 00128 * @param - regValue - The value to write to the register. 00129 * @param - size - The size of the register to write. 00130 * 00131 * @return None. 00132 *******************************************************************************/ 00133 void AD7798::set_register_value(uint8_t regAddress, uint16_t regValue, 00134 uint8_t size, bool toggle_cs) 00135 { 00136 uint8_t data[size + 1]; 00137 uint8_t byte; 00138 uint16_t mask; 00139 00140 data[0] = AD7798_COMM_WRITE | AD7798_COMM_ADDR(regAddress); 00141 00142 if(size == 1) { 00143 00144 mask = 0x00FF; 00145 00146 } else { 00147 00148 mask = 0xFF00; 00149 } 00150 00151 for(byte = 1; byte <= size; byte++) { 00152 data[byte] = (uint8_t)((regValue & mask) >> ((size - byte) * 8)); 00153 mask = mask >> (byte * 8); 00154 } 00155 00156 spi_write(data, (1 + size), toggle_cs); 00157 00158 00159 } 00160 /***************************************************************************//** 00161 * @brief Reads /RDY bit of status reg. 00162 * 00163 * @param None. 00164 * 00165 * @return rdy - 0 if RDY is 1. 00166 * - 1 if RDY is 0. 00167 *******************************************************************************/ 00168 uint8_t AD7798::ready(void) 00169 { 00170 00171 while((get_register_value( AD7798_REG_STAT, 1) & 0x80) != 0x80); 00172 00173 return(1); 00174 } 00175 00176 /***************************************************************************//** 00177 * @brief Sets the operating mode of AD7798. 00178 * 00179 * @param mode - Mode of operation. 00180 * 00181 * @return None. 00182 *******************************************************************************/ 00183 void AD7798::set_mode(uint8_t mode) 00184 { 00185 unsigned long command; 00186 command = get_register_value(AD7798_REG_MODE, 2); 00187 command &= ~AD7798_MODE_SEL(0xFF); 00188 command |= AD7798_MODE_SEL(mode); 00189 set_register_value( 00190 AD7798_REG_MODE, 00191 command, 00192 2 00193 ); 00194 } 00195 /***************************************************************************//** 00196 * @brief Selects the channel of AD7798. 00197 * 00198 * @param channel - ADC channel selection. 00199 * 00200 * @return None. 00201 *******************************************************************************/ 00202 void AD7798::set_channel(uint8_t channel) 00203 { 00204 unsigned long command; 00205 command = get_register_value(AD7798_REG_CONF, 2); 00206 command &= ~AD7798_CONF_CHAN(0xFF); 00207 command |= AD7798_CONF_CHAN(channel); 00208 set_register_value( 00209 AD7798_REG_CONF, 00210 command, 00211 2 00212 ); 00213 } 00214 00215 /***************************************************************************//** 00216 * @brief Sets the gain of the In-Amp. 00217 * 00218 * @param gain - Gain. 00219 * 00220 * @return None. 00221 *******************************************************************************/ 00222 void AD7798::set_gain(uint16_t gain) 00223 { 00224 uint16_t command; 00225 command = get_register_value(AD7798_REG_CONF, 2); 00226 command &= ~AD7798_CONF_GAIN(0xFF); 00227 command |= AD7798_CONF_GAIN(gain); 00228 set_register_value( 00229 AD7798_REG_CONF, 00230 command, 00231 2 00232 ); 00233 } 00234 00235 void AD7798::set_filter(uint8_t filter) 00236 { 00237 unsigned long command; 00238 command = get_register_value(AD7798_REG_MODE, 2); 00239 command &= ~AD7798_MODE_RATE(0x0F); 00240 command |= AD7798_MODE_RATE(filter); 00241 set_register_value( 00242 AD7798_REG_MODE, 00243 command, 00244 2 00245 ); 00246 } 00247 /***************************************************************************//** 00248 * @brief Enables or disables the reference detect function. 00249 * 00250 * @param state - State of the reference detect function. 00251 * Example: 0 - Reference detect disabled. 00252 * 1 - Reference detect enabled. 00253 * 00254 * @return None. 00255 *******************************************************************************/ 00256 void AD7798::set_reference(uint8_t state) 00257 { 00258 unsigned long command = 0; 00259 command = get_register_value(AD7798_REG_CONF, 2); 00260 command &= ~AD7798_CONF_REFDET(1); 00261 command |= AD7798_CONF_REFDET(state); 00262 set_register_value(AD7798_REG_CONF, 00263 command, 00264 2); 00265 } 00266 00267 void AD7798::set_coding_mode(uint8_t mode) 00268 { 00269 uint16_t command; 00270 00271 command = get_register_value(AD7798_REG_CONF, 2); 00272 00273 if(mode == AD7798_BIPOLAR) { 00274 00275 command &= ~AD7798_CONF_UNIPOLAR; 00276 00277 } else if(mode == AD7798_UNIPOLAR) { 00278 00279 command |= AD7798_CONF_UNIPOLAR; 00280 } 00281 set_register_value( 00282 AD7798_REG_CONF, 00283 command, 00284 2 00285 ); 00286 } 00287 00288 void AD7798::set_burnout_current(uint8_t select) 00289 { 00290 uint16_t command; 00291 00292 command = get_register_value(AD7798_REG_CONF, 2); 00293 00294 if(select == AD7798_DISABLE) 00295 command &= ~AD7798_CONF_BO_EN; 00296 else if(select == AD7798_ENABLE) 00297 command |= AD7798_CONF_BO_EN; 00298 00299 set_register_value( 00300 AD7798_REG_CONF, 00301 command, 00302 2 00303 ); 00304 } 00305 00306 uint8_t AD7798::spi_read(uint8_t *data, uint8_t bytes_number, bool toggle_cs) 00307 { 00308 cs = false & toggle_cs; 00309 data[0] = ad7798.write(data[0]); 00310 for(uint8_t byte = 1; byte <= bytes_number; byte++) { 00311 data[byte - 1] = ad7798.write(data[byte]); 00312 } 00313 cs = true & toggle_cs; 00314 return bytes_number; 00315 } 00316 uint8_t AD7798::spi_write(uint8_t *data, uint8_t bytes_number, bool toggle_cs) 00317 { 00318 cs = false & toggle_cs; 00319 for(uint8_t byte = 0; byte < bytes_number; byte++) { 00320 ad7798.write(data[byte]); 00321 } 00322 cs = true & toggle_cs; 00323 return bytes_number; 00324 } 00325 00326 void AD7798::read_data(uint8_t adcChannel, uint16_t *adcData) 00327 { 00328 00329 uint8_t channel; 00330 00331 channel = 0x80 | adcChannel; 00332 00333 cs = 0; 00334 00335 set_register_value(AD7798_REG_MODE, 0x200A, 2);//, false); 00336 uint16_t regVal = 0; 00337 while( (regVal & channel) != channel) { 00338 regVal = get_register_value( AD7798_REG_STAT, 1);//, false); 00339 } 00340 00341 //timer_sleep(200); 00342 wait_ms(200); // ??? 00343 00344 *adcData = get_register_value(AD7798_REG_DATA, 2);//, false); 00345 00346 cs = 1; 00347 00348 00349 00350 }
Generated on Fri Jul 15 2022 02:11:10 by
