Driver for the AD7791 24bit ADC

Dependents:   ad7791-helloworld CN0216

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:57:07 2016 +0000
Revision:
0:075fe3d08488
Initial revision

Who changed what in which revision?

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