Driver for the AD7790 16 bit ADC

Dependents:   ad7790-helloworld CN0357

For additional information check out the mbed page of the Analog Devices wiki: https://wiki.analog.com/resources/tools-software/mbed-drivers-all

Committer:
adisuciu
Date:
Tue May 03 12:56:17 2016 +0000
Revision:
0:c7cfa6877e1d
Initial revision

Who changed what in which revision?

UserRevisionLine numberNew contents of line
adisuciu 0:c7cfa6877e1d 1 /**
adisuciu 0:c7cfa6877e1d 2 * @file AD7790.cpp
adisuciu 0:c7cfa6877e1d 3 * @brief Source file for AD7790 ADC
adisuciu 0:c7cfa6877e1d 4 * @author Analog Devices Inc.
adisuciu 0:c7cfa6877e1d 5 *
adisuciu 0:c7cfa6877e1d 6 * For support please go to:
adisuciu 0:c7cfa6877e1d 7 * Github: https://github.com/analogdevicesinc/mbed-adi
adisuciu 0:c7cfa6877e1d 8 * Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
adisuciu 0:c7cfa6877e1d 9 * Product: http://www.analog.com/ad7790
adisuciu 0:c7cfa6877e1d 10 * More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
adisuciu 0:c7cfa6877e1d 11
adisuciu 0:c7cfa6877e1d 12 ********************************************************************************
adisuciu 0:c7cfa6877e1d 13 * Copyright 2016(c) Analog Devices, Inc.
adisuciu 0:c7cfa6877e1d 14 *
adisuciu 0:c7cfa6877e1d 15 * All rights reserved.
adisuciu 0:c7cfa6877e1d 16 *
adisuciu 0:c7cfa6877e1d 17 * Redistribution and use in source and binary forms, with or without
adisuciu 0:c7cfa6877e1d 18 * modification, are permitted provided that the following conditions are met:
adisuciu 0:c7cfa6877e1d 19 * - Redistributions of source code must retain the above copyright
adisuciu 0:c7cfa6877e1d 20 * notice, this list of conditions and the following disclaimer.
adisuciu 0:c7cfa6877e1d 21 * - Redistributions in binary form must reproduce the above copyright
adisuciu 0:c7cfa6877e1d 22 * notice, this list of conditions and the following disclaimer in
adisuciu 0:c7cfa6877e1d 23 * the documentation and/or other materials provided with the
adisuciu 0:c7cfa6877e1d 24 * distribution.
adisuciu 0:c7cfa6877e1d 25 * - Neither the name of Analog Devices, Inc. nor the names of its
adisuciu 0:c7cfa6877e1d 26 * contributors may be used to endorse or promote products derived
adisuciu 0:c7cfa6877e1d 27 * from this software without specific prior written permission.
adisuciu 0:c7cfa6877e1d 28 * - The use of this software may or may not infringe the patent rights
adisuciu 0:c7cfa6877e1d 29 * of one or more patent holders. This license does not release you
adisuciu 0:c7cfa6877e1d 30 * from the requirement that you obtain separate licenses from these
adisuciu 0:c7cfa6877e1d 31 * patent holders to use this software.
adisuciu 0:c7cfa6877e1d 32 * - Use of the software either in source or binary form, must be run
adisuciu 0:c7cfa6877e1d 33 * on or directly connected to an Analog Devices Inc. component.
adisuciu 0:c7cfa6877e1d 34 *
adisuciu 0:c7cfa6877e1d 35 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
adisuciu 0:c7cfa6877e1d 36 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
adisuciu 0:c7cfa6877e1d 37 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
adisuciu 0:c7cfa6877e1d 38 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
adisuciu 0:c7cfa6877e1d 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
adisuciu 0:c7cfa6877e1d 40 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
adisuciu 0:c7cfa6877e1d 41 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
adisuciu 0:c7cfa6877e1d 42 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
adisuciu 0:c7cfa6877e1d 43 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
adisuciu 0:c7cfa6877e1d 44 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
adisuciu 0:c7cfa6877e1d 45 *
adisuciu 0:c7cfa6877e1d 46 ********************************************************************************/
adisuciu 0:c7cfa6877e1d 47
adisuciu 0:c7cfa6877e1d 48 #include <stdint.h>
adisuciu 0:c7cfa6877e1d 49 #include "mbed.h"
adisuciu 0:c7cfa6877e1d 50 #include "AD7790.h"
adisuciu 0:c7cfa6877e1d 51
adisuciu 0:c7cfa6877e1d 52 /**
adisuciu 0:c7cfa6877e1d 53 * @brief AD7790 constructor, sets CS pin and SPI format
adisuciu 0:c7cfa6877e1d 54 * @param CS - (optional)chip select of the AD7790
adisuciu 0:c7cfa6877e1d 55 * @param MOSI - (optional)pin of the SPI interface
adisuciu 0:c7cfa6877e1d 56 * @param MISO - (optional)pin of the SPI interface
adisuciu 0:c7cfa6877e1d 57 * @param SCK - (optional)pin of the SPI interface
adisuciu 0:c7cfa6877e1d 58 */
adisuciu 0:c7cfa6877e1d 59 AD7790::AD7790(float reference_voltage,
adisuciu 0:c7cfa6877e1d 60 PinName CS,
adisuciu 0:c7cfa6877e1d 61 PinName MOSI,
adisuciu 0:c7cfa6877e1d 62 PinName MISO,
adisuciu 0:c7cfa6877e1d 63 PinName SCK) :
adisuciu 0:c7cfa6877e1d 64 miso(MISO), ad7790(MOSI, MISO, SCK), cs(CS), _vref(reference_voltage), _PGA_gain(1)
adisuciu 0:c7cfa6877e1d 65 {
adisuciu 0:c7cfa6877e1d 66 cs = true; // cs is active low
adisuciu 0:c7cfa6877e1d 67 ad7790.format(8, _SPI_MODE);
adisuciu 0:c7cfa6877e1d 68 _continous_conversion = true;
adisuciu 0:c7cfa6877e1d 69 _channel = DIFFERENTIAL;
adisuciu 0:c7cfa6877e1d 70 }
adisuciu 0:c7cfa6877e1d 71
adisuciu 0:c7cfa6877e1d 72 /**
adisuciu 0:c7cfa6877e1d 73 * @brief Set AD7790 SPI frequency
adisuciu 0:c7cfa6877e1d 74 * @param hz - SPI bus frequency in hz
adisuciu 0:c7cfa6877e1d 75 * @return none
adisuciu 0:c7cfa6877e1d 76 */
adisuciu 0:c7cfa6877e1d 77 void AD7790::frequency(int hz)
adisuciu 0:c7cfa6877e1d 78 {
adisuciu 0:c7cfa6877e1d 79 ad7790.frequency(hz);
adisuciu 0:c7cfa6877e1d 80 }
adisuciu 0:c7cfa6877e1d 81
adisuciu 0:c7cfa6877e1d 82 /**
adisuciu 0:c7cfa6877e1d 83 * @brief Resets the AD7790
adisuciu 0:c7cfa6877e1d 84 * @return none
adisuciu 0:c7cfa6877e1d 85 */
adisuciu 0:c7cfa6877e1d 86 void AD7790::reset()
adisuciu 0:c7cfa6877e1d 87 {
adisuciu 0:c7cfa6877e1d 88 ad7790.format(8, _SPI_MODE);
adisuciu 0:c7cfa6877e1d 89 cs = false;
adisuciu 0:c7cfa6877e1d 90 wait_us(_DELAY_TIMING);
adisuciu 0:c7cfa6877e1d 91 ad7790.write(_RESET);
adisuciu 0:c7cfa6877e1d 92 ad7790.write(_RESET);
adisuciu 0:c7cfa6877e1d 93 ad7790.write(_RESET);
adisuciu 0:c7cfa6877e1d 94 ad7790.write(_RESET);
adisuciu 0:c7cfa6877e1d 95 wait_us(_DELAY_TIMING);
adisuciu 0:c7cfa6877e1d 96 cs = true;
adisuciu 0:c7cfa6877e1d 97 _continous_conversion = true;
adisuciu 0:c7cfa6877e1d 98 }
adisuciu 0:c7cfa6877e1d 99
adisuciu 0:c7cfa6877e1d 100 /**
adisuciu 0:c7cfa6877e1d 101 * Sets the mode register. Also sets continous mode and range based on the value
adisuciu 0:c7cfa6877e1d 102 * written in reg_val
adisuciu 0:c7cfa6877e1d 103 * @param reg_val
adisuciu 0:c7cfa6877e1d 104 */
adisuciu 0:c7cfa6877e1d 105 void AD7790::write_mode_reg(uint8_t reg_val)
adisuciu 0:c7cfa6877e1d 106 {
adisuciu 0:c7cfa6877e1d 107 write_reg(MODE_REG, reg_val);
adisuciu 0:c7cfa6877e1d 108 uint8_t continous_mode = (reg_val & 0xC0);
adisuciu 0:c7cfa6877e1d 109 if(continous_mode == 0x00) {
adisuciu 0:c7cfa6877e1d 110 _continous_conversion = true;
adisuciu 0:c7cfa6877e1d 111 } else {
adisuciu 0:c7cfa6877e1d 112 _continous_conversion = false;
adisuciu 0:c7cfa6877e1d 113 }
adisuciu 0:c7cfa6877e1d 114 uint8_t range = (reg_val & 0x30);
adisuciu 0:c7cfa6877e1d 115 _PGA_gain = 1 << (range >> 4);
adisuciu 0:c7cfa6877e1d 116 }
adisuciu 0:c7cfa6877e1d 117
adisuciu 0:c7cfa6877e1d 118 /**
adisuciu 0:c7cfa6877e1d 119 * Reads the mode register and returns its value
adisuciu 0:c7cfa6877e1d 120 * @return value of the mode register
adisuciu 0:c7cfa6877e1d 121 */
adisuciu 0:c7cfa6877e1d 122 uint8_t AD7790::read_mode_reg()
adisuciu 0:c7cfa6877e1d 123 {
adisuciu 0:c7cfa6877e1d 124 return read_reg(MODE_REG);
adisuciu 0:c7cfa6877e1d 125 }
adisuciu 0:c7cfa6877e1d 126
adisuciu 0:c7cfa6877e1d 127 /**
adisuciu 0:c7cfa6877e1d 128 * Writes the filter register
adisuciu 0:c7cfa6877e1d 129 * @param regValue value to be written.
adisuciu 0:c7cfa6877e1d 130 */
adisuciu 0:c7cfa6877e1d 131 void AD7790::write_filter_reg(uint8_t reg_val)
adisuciu 0:c7cfa6877e1d 132 {
adisuciu 0:c7cfa6877e1d 133 write_reg(FILTER_REG, reg_val);
adisuciu 0:c7cfa6877e1d 134 }
adisuciu 0:c7cfa6877e1d 135
adisuciu 0:c7cfa6877e1d 136 /**
adisuciu 0:c7cfa6877e1d 137 * Reads the filter register and returns its value
adisuciu 0:c7cfa6877e1d 138 * @return the value of the filter register
adisuciu 0:c7cfa6877e1d 139 */
adisuciu 0:c7cfa6877e1d 140 uint8_t AD7790::read_filter_reg()
adisuciu 0:c7cfa6877e1d 141 {
adisuciu 0:c7cfa6877e1d 142 return read_reg(FILTER_REG);
adisuciu 0:c7cfa6877e1d 143 }
adisuciu 0:c7cfa6877e1d 144
adisuciu 0:c7cfa6877e1d 145 /**
adisuciu 0:c7cfa6877e1d 146 * Reads the data register and returns its value
adisuciu 0:c7cfa6877e1d 147 * @return value of the data register
adisuciu 0:c7cfa6877e1d 148 */
adisuciu 0:c7cfa6877e1d 149 uint16_t AD7790::read_data_reg()
adisuciu 0:c7cfa6877e1d 150 {
adisuciu 0:c7cfa6877e1d 151 uint16_t data_result;
adisuciu 0:c7cfa6877e1d 152 ad7790.format(8, _SPI_MODE);
adisuciu 0:c7cfa6877e1d 153 cs = false;
adisuciu 0:c7cfa6877e1d 154 ad7790.write(_DATA_READ | (static_cast<uint8_t>(_channel)));
adisuciu 0:c7cfa6877e1d 155 data_result = ((ad7790.write(_DUMMY_BYTE)) << 8);
adisuciu 0:c7cfa6877e1d 156 data_result |= (ad7790.write(_DUMMY_BYTE));
adisuciu 0:c7cfa6877e1d 157 cs = true;
adisuciu 0:c7cfa6877e1d 158 return data_result;
adisuciu 0:c7cfa6877e1d 159 }
adisuciu 0:c7cfa6877e1d 160
adisuciu 0:c7cfa6877e1d 161 /**
adisuciu 0:c7cfa6877e1d 162 * Reads the status register of the ADC and returns its value
adisuciu 0:c7cfa6877e1d 163 * @return value of the status reg
adisuciu 0:c7cfa6877e1d 164 */
adisuciu 0:c7cfa6877e1d 165 uint8_t AD7790::read_status_reg()
adisuciu 0:c7cfa6877e1d 166 {
adisuciu 0:c7cfa6877e1d 167 return read_reg(STATUS_REG);
adisuciu 0:c7cfa6877e1d 168 }
adisuciu 0:c7cfa6877e1d 169
adisuciu 0:c7cfa6877e1d 170
adisuciu 0:c7cfa6877e1d 171 /**
adisuciu 0:c7cfa6877e1d 172 * @brief Enables/disables continous_conversion mode
adisuciu 0:c7cfa6877e1d 173 * In Single Conversion mode, read_u16 method will read the MODE register of the ADC,
adisuciu 0:c7cfa6877e1d 174 * then write the Start single conversion bit and wait for the DOUT/RDY pin to go low,
adisuciu 0:c7cfa6877e1d 175 * When the pin is driven low, data register is read back from the ADC.
adisuciu 0:c7cfa6877e1d 176 *
adisuciu 0:c7cfa6877e1d 177 * In Continous conversion mode, read_u16 method will poll the DOUT/RDY pin, if it is low,
adisuciu 0:c7cfa6877e1d 178 * the data register is read back from the ADC.
adisuciu 0:c7cfa6877e1d 179 *
adisuciu 0:c7cfa6877e1d 180 * @param mode
adisuciu 0:c7cfa6877e1d 181 * true - continous conversion mode enabled
adisuciu 0:c7cfa6877e1d 182 * false - single conversion mode enabled
adisuciu 0:c7cfa6877e1d 183 */
adisuciu 0:c7cfa6877e1d 184 void AD7790::set_conversion_mode(AD7790Mode_t mode)
adisuciu 0:c7cfa6877e1d 185 {
adisuciu 0:c7cfa6877e1d 186 uint8_t mode_reg_val;
adisuciu 0:c7cfa6877e1d 187 mode_reg_val = read_mode_reg() & 0x3F;
adisuciu 0:c7cfa6877e1d 188 mode_reg_val = mode_reg_val | (static_cast<uint8_t>(mode));
adisuciu 0:c7cfa6877e1d 189 write_mode_reg(mode);
adisuciu 0:c7cfa6877e1d 190 }
adisuciu 0:c7cfa6877e1d 191
adisuciu 0:c7cfa6877e1d 192 /**
adisuciu 0:c7cfa6877e1d 193 * - From mbed AnalogIn API -
adisuciu 0:c7cfa6877e1d 194 * @brief Read the input voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
adisuciu 0:c7cfa6877e1d 195 * Depending on the conversion mode, this method will have different behavior. Conversion mode is set using
adisuciu 0:c7cfa6877e1d 196 * set_continous_conversion_mode(bool).
adisuciu 0:c7cfa6877e1d 197 *
adisuciu 0:c7cfa6877e1d 198 * In Single Conversion mode, read_u16 method will read the MODE register of the ADC,
adisuciu 0:c7cfa6877e1d 199 * then write the Start single conversion bit and wait for the DOUT/RDY pin to go low,
adisuciu 0:c7cfa6877e1d 200 * When the pin is driven low, data register is read back from the ADC.
adisuciu 0:c7cfa6877e1d 201 *
adisuciu 0:c7cfa6877e1d 202 * In Continous conversion mode, read_u16 method will poll the DOUT/RDY pin, if it is low,
adisuciu 0:c7cfa6877e1d 203 * the data register is read back from the ADC.
adisuciu 0:c7cfa6877e1d 204 *
adisuciu 0:c7cfa6877e1d 205 * @return 16-bit unsigned short representing the current input voltage, normalised to a 16-bit value
adisuciu 0:c7cfa6877e1d 206 * returns -1 (0xFFFF) along with a debug message if conversion failed.
adisuciu 0:c7cfa6877e1d 207 */
adisuciu 0:c7cfa6877e1d 208 uint16_t AD7790::read_u16(void)
adisuciu 0:c7cfa6877e1d 209 {
adisuciu 0:c7cfa6877e1d 210 uint16_t data_result = 0;
adisuciu 0:c7cfa6877e1d 211 ad7790.format(8, _SPI_MODE);
adisuciu 0:c7cfa6877e1d 212 cs = false;
adisuciu 0:c7cfa6877e1d 213 uint16_t timeout_cnt = 0;
adisuciu 0:c7cfa6877e1d 214 if(_continous_conversion == false) {
adisuciu 0:c7cfa6877e1d 215
adisuciu 0:c7cfa6877e1d 216 uint8_t mode_reg = read_mode_reg();
adisuciu 0:c7cfa6877e1d 217 wait_us(_DELAY_TIMING);
adisuciu 0:c7cfa6877e1d 218
adisuciu 0:c7cfa6877e1d 219 cs = false;
adisuciu 0:c7cfa6877e1d 220 mode_reg = (mode_reg & 0x3F) | MD1; // mask single conversion bits
adisuciu 0:c7cfa6877e1d 221 ad7790.write((MODE_REG << 4) | (static_cast<uint8_t>(_channel))); // start single conversion
adisuciu 0:c7cfa6877e1d 222 ad7790.write(mode_reg);
adisuciu 0:c7cfa6877e1d 223 timeout_cnt = _SINGLE_CONVERSION_TIMEOUT; // starts timeout
adisuciu 0:c7cfa6877e1d 224 } else {
adisuciu 0:c7cfa6877e1d 225 timeout_cnt = _CONTINOUS_CONVERSION_TIMEOUT; // starts timeout
adisuciu 0:c7cfa6877e1d 226 }
adisuciu 0:c7cfa6877e1d 227 wait_us(1);
adisuciu 0:c7cfa6877e1d 228
adisuciu 0:c7cfa6877e1d 229 while(miso) { // wait for the MISO pin to go low.
adisuciu 0:c7cfa6877e1d 230 if(timeout_cnt) {
adisuciu 0:c7cfa6877e1d 231 timeout_cnt--;
adisuciu 0:c7cfa6877e1d 232 } else {
adisuciu 0:c7cfa6877e1d 233 cs = true;
adisuciu 0:c7cfa6877e1d 234 #ifdef AD7790_DEBUG_MODE
adisuciu 0:c7cfa6877e1d 235 printf("timeout occurred reading the AD7790. "); // error, MISO line didn't toggle
adisuciu 0:c7cfa6877e1d 236 #endif
adisuciu 0:c7cfa6877e1d 237 return -1; // ERROR
adisuciu 0:c7cfa6877e1d 238 }
adisuciu 0:c7cfa6877e1d 239 wait_us(10);
adisuciu 0:c7cfa6877e1d 240 }
adisuciu 0:c7cfa6877e1d 241
adisuciu 0:c7cfa6877e1d 242 ad7790.write(_DATA_READ | (static_cast<uint8_t>(_channel)));
adisuciu 0:c7cfa6877e1d 243 data_result = ((ad7790.write(_DUMMY_BYTE)) << 8);
adisuciu 0:c7cfa6877e1d 244 data_result |= (ad7790.write(_DUMMY_BYTE));
adisuciu 0:c7cfa6877e1d 245 cs = true;
adisuciu 0:c7cfa6877e1d 246 return data_result;
adisuciu 0:c7cfa6877e1d 247 }
adisuciu 0:c7cfa6877e1d 248
adisuciu 0:c7cfa6877e1d 249 /**
adisuciu 0:c7cfa6877e1d 250 * @brief Reads a register of the AD7790
adisuciu 0:c7cfa6877e1d 251 * @param address - address of the register
adisuciu 0:c7cfa6877e1d 252 * @return value of the register
adisuciu 0:c7cfa6877e1d 253 */
adisuciu 0:c7cfa6877e1d 254 uint16_t AD7790::read_reg(AD7790Register_t address)
adisuciu 0:c7cfa6877e1d 255 {
adisuciu 0:c7cfa6877e1d 256 uint16_t data = address << 12;
adisuciu 0:c7cfa6877e1d 257 data |= _DUMMY_BYTE;
adisuciu 0:c7cfa6877e1d 258 data |= _READ_FLAG;
adisuciu 0:c7cfa6877e1d 259 data |= (static_cast<uint8_t>(_channel) << 8);
adisuciu 0:c7cfa6877e1d 260 return write_spi(data);
adisuciu 0:c7cfa6877e1d 261 }
adisuciu 0:c7cfa6877e1d 262
adisuciu 0:c7cfa6877e1d 263 /**
adisuciu 0:c7cfa6877e1d 264 * @brief Writes a register of the AD7790
adisuciu 0:c7cfa6877e1d 265 * @param address - address of the register
adisuciu 0:c7cfa6877e1d 266 * @param reg_val - value to be written
adisuciu 0:c7cfa6877e1d 267 * @return none
adisuciu 0:c7cfa6877e1d 268 *
adisuciu 0:c7cfa6877e1d 269 */
adisuciu 0:c7cfa6877e1d 270 void AD7790::write_reg(AD7790Register_t address, uint8_t reg_val)
adisuciu 0:c7cfa6877e1d 271 {
adisuciu 0:c7cfa6877e1d 272 uint16_t spi_data = address << 12;
adisuciu 0:c7cfa6877e1d 273 spi_data |= reg_val;
adisuciu 0:c7cfa6877e1d 274 spi_data |= (static_cast<uint8_t>(_channel) << 8);
adisuciu 0:c7cfa6877e1d 275 write_spi(spi_data);
adisuciu 0:c7cfa6877e1d 276 }
adisuciu 0:c7cfa6877e1d 277
adisuciu 0:c7cfa6877e1d 278 /**
adisuciu 0:c7cfa6877e1d 279 * @brief Writes 16bit data to the AD7790 SPI interface
adisuciu 0:c7cfa6877e1d 280 * @param reg_val to be written
adisuciu 0:c7cfa6877e1d 281 * @return data returned by the AD7790
adisuciu 0:c7cfa6877e1d 282 */
adisuciu 0:c7cfa6877e1d 283 uint16_t AD7790::write_spi(uint16_t reg_val)
adisuciu 0:c7cfa6877e1d 284 {
adisuciu 0:c7cfa6877e1d 285 uint16_t data_result;
adisuciu 0:c7cfa6877e1d 286 uint8_t upper_byte = (reg_val >> 8) & 0xFF;
adisuciu 0:c7cfa6877e1d 287 uint8_t lower_byte = reg_val & 0xFF;
adisuciu 0:c7cfa6877e1d 288 ad7790.format(8, _SPI_MODE);
adisuciu 0:c7cfa6877e1d 289 cs = false;
adisuciu 0:c7cfa6877e1d 290 data_result = (ad7790.write(upper_byte) << 8);
adisuciu 0:c7cfa6877e1d 291 data_result |= ad7790.write(lower_byte);
adisuciu 0:c7cfa6877e1d 292 cs = true;
adisuciu 0:c7cfa6877e1d 293 return data_result;
adisuciu 0:c7cfa6877e1d 294 }
adisuciu 0:c7cfa6877e1d 295
adisuciu 0:c7cfa6877e1d 296
adisuciu 0:c7cfa6877e1d 297 /**
adisuciu 0:c7cfa6877e1d 298 * Sets the AnalogInputRange to be used by the AD7790
adisuciu 0:c7cfa6877e1d 299 * @param range AnalogInputRange_t to be used in voltage computations
adisuciu 0:c7cfa6877e1d 300 */
adisuciu 0:c7cfa6877e1d 301 void AD7790::set_range(AnalogInputRange_t range)
adisuciu 0:c7cfa6877e1d 302 {
adisuciu 0:c7cfa6877e1d 303
adisuciu 0:c7cfa6877e1d 304 uint8_t mode_reg_val;
adisuciu 0:c7cfa6877e1d 305 mode_reg_val = read_mode_reg() & 0xCF;
adisuciu 0:c7cfa6877e1d 306 mode_reg_val = mode_reg_val | (range << 4);
adisuciu 0:c7cfa6877e1d 307 write_mode_reg(mode_reg_val);
adisuciu 0:c7cfa6877e1d 308 }
adisuciu 0:c7cfa6877e1d 309
adisuciu 0:c7cfa6877e1d 310 /**
adisuciu 0:c7cfa6877e1d 311 * Sets the reference voltage of the AD7790
adisuciu 0:c7cfa6877e1d 312 * @param ref reference voltage to be set
adisuciu 0:c7cfa6877e1d 313 */
adisuciu 0:c7cfa6877e1d 314 void AD7790::set_reference_voltage(float ref)
adisuciu 0:c7cfa6877e1d 315 {
adisuciu 0:c7cfa6877e1d 316 _vref = ref;
adisuciu 0:c7cfa6877e1d 317 }
adisuciu 0:c7cfa6877e1d 318
adisuciu 0:c7cfa6877e1d 319 /**
adisuciu 0:c7cfa6877e1d 320 * Gets the reference voltage of the AD7790
adisuciu 0:c7cfa6877e1d 321 * @return reference voltage
adisuciu 0:c7cfa6877e1d 322 */
adisuciu 0:c7cfa6877e1d 323 float AD7790::get_reference_voltage(void)
adisuciu 0:c7cfa6877e1d 324 {
adisuciu 0:c7cfa6877e1d 325 return _vref;
adisuciu 0:c7cfa6877e1d 326 }
adisuciu 0:c7cfa6877e1d 327
adisuciu 0:c7cfa6877e1d 328 /**
adisuciu 0:c7cfa6877e1d 329 * Reads the data register of the ADC and converts the result to volts
adisuciu 0:c7cfa6877e1d 330 * Gain needs to be correctly set using set_gain in order to get accurate results
adisuciu 0:c7cfa6877e1d 331 * @return voltage of the ADC input
adisuciu 0:c7cfa6877e1d 332 */
adisuciu 0:c7cfa6877e1d 333 float AD7790::read_voltage(void)
adisuciu 0:c7cfa6877e1d 334 {
adisuciu 0:c7cfa6877e1d 335 return data_to_voltage(read_u16());
adisuciu 0:c7cfa6877e1d 336 }
adisuciu 0:c7cfa6877e1d 337
adisuciu 0:c7cfa6877e1d 338 /**
adisuciu 0:c7cfa6877e1d 339 * Converts an uint16_t to voltage.
adisuciu 0:c7cfa6877e1d 340 * Gain needs to be correctly set using set_gain in order to get accurate results
adisuciu 0:c7cfa6877e1d 341 * @param data in uint16_t format
adisuciu 0:c7cfa6877e1d 342 * @return float value of voltage (in V)
adisuciu 0:c7cfa6877e1d 343 */
adisuciu 0:c7cfa6877e1d 344 float AD7790::data_to_voltage(uint16_t data)
adisuciu 0:c7cfa6877e1d 345 {
adisuciu 0:c7cfa6877e1d 346 return ((data / static_cast<float>(_RESOLUTION / 2)) - 1) * (_vref / _PGA_gain);
adisuciu 0:c7cfa6877e1d 347 }
adisuciu 0:c7cfa6877e1d 348
adisuciu 0:c7cfa6877e1d 349 /**
adisuciu 0:c7cfa6877e1d 350 * Converts voltage to an uint16_t.
adisuciu 0:c7cfa6877e1d 351 * Gain needs to be correctly set using set_gain in order to get accurate results
adisuciu 0:c7cfa6877e1d 352 * @param voltage to be converted
adisuciu 0:c7cfa6877e1d 353 * @return data in uint16_t format
adisuciu 0:c7cfa6877e1d 354 */
adisuciu 0:c7cfa6877e1d 355 uint16_t AD7790::voltage_to_data(float voltage)
adisuciu 0:c7cfa6877e1d 356 {
adisuciu 0:c7cfa6877e1d 357 return (((voltage * _PGA_gain / _vref) + 1) * static_cast<float>(_RESOLUTION / 2));
adisuciu 0:c7cfa6877e1d 358 }
adisuciu 0:c7cfa6877e1d 359
adisuciu 0:c7cfa6877e1d 360 /**
adisuciu 0:c7cfa6877e1d 361 * Sets the conversion channel.
adisuciu 0:c7cfa6877e1d 362 * @param channel
adisuciu 0:c7cfa6877e1d 363 */
adisuciu 0:c7cfa6877e1d 364 void AD7790::set_channel(AD7790Channel_t channel)
adisuciu 0:c7cfa6877e1d 365 {
adisuciu 0:c7cfa6877e1d 366 _channel = channel;
adisuciu 0:c7cfa6877e1d 367 }
adisuciu 0:c7cfa6877e1d 368
adisuciu 0:c7cfa6877e1d 369 /**
adisuciu 0:c7cfa6877e1d 370 * - From mbed AnalogIn API -
adisuciu 0:c7cfa6877e1d 371 * Read the input voltage, represented as a float in the range [0.0, 1.0] - uses the read_u16 method
adisuciu 0:c7cfa6877e1d 372 * @returns A floating-point value representing the current input voltage, measured as a percentage
adisuciu 0:c7cfa6877e1d 373 * returns 1.0 along with a debug message if the conversion failed
adisuciu 0:c7cfa6877e1d 374 */
adisuciu 0:c7cfa6877e1d 375 float AD7790::read(void)
adisuciu 0:c7cfa6877e1d 376 {
adisuciu 0:c7cfa6877e1d 377 float percent;
adisuciu 0:c7cfa6877e1d 378 uint16_t data;
adisuciu 0:c7cfa6877e1d 379 data = read_u16();
adisuciu 0:c7cfa6877e1d 380 percent = (data / static_cast<float>(_RESOLUTION) ); // translate bipolar conversion to [0.0, 1.0] domain
adisuciu 0:c7cfa6877e1d 381 return percent;
adisuciu 0:c7cfa6877e1d 382 }
adisuciu 0:c7cfa6877e1d 383
adisuciu 0:c7cfa6877e1d 384 #ifdef MBED_OPERATORS
adisuciu 0:c7cfa6877e1d 385
adisuciu 0:c7cfa6877e1d 386 /**
adisuciu 0:c7cfa6877e1d 387 * - From mbed AnalogIn API -
adisuciu 0:c7cfa6877e1d 388 * An operator shorthand for read()
adisuciu 0:c7cfa6877e1d 389 * The float() operator can be used as a shorthand for read() to simplify common code sequences
adisuciu 0:c7cfa6877e1d 390 */
adisuciu 0:c7cfa6877e1d 391 AD7790::operator float()
adisuciu 0:c7cfa6877e1d 392 {
adisuciu 0:c7cfa6877e1d 393 return read();
adisuciu 0:c7cfa6877e1d 394 }
adisuciu 0:c7cfa6877e1d 395
adisuciu 0:c7cfa6877e1d 396 #endif
adisuciu 0:c7cfa6877e1d 397
adisuciu 0:c7cfa6877e1d 398
adisuciu 0:c7cfa6877e1d 399