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: 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
Revision 0:075fe3d08488, committed 2016-05-03
- Comitter:
- adisuciu
- Date:
- Tue May 03 12:57:07 2016 +0000
- Commit message:
- Initial revision
Changed in this revision
| AD7791.cpp | Show annotated file Show diff for this revision Revisions of this file |
| AD7791.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 075fe3d08488 AD7791.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AD7791.cpp Tue May 03 12:57:07 2016 +0000
@@ -0,0 +1,394 @@
+/**
+* @file AD7791.cpp
+* @brief Source file for AD7791 ADC
+* @author Analog Devices Inc.
+*
+* For support please go to:
+* Github: https://github.com/analogdevicesinc/mbed-adi
+* Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
+* Product: http://www.analog.com/ad7791
+* More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
+
+********************************************************************************
+* Copyright 2016(c) Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* - Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+* - Neither the name of Analog Devices, Inc. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+* - The use of this software may or may not infringe the patent rights
+* of one or more patent holders. This license does not release you
+* from the requirement that you obtain separate licenses from these
+* patent holders to use this software.
+* - Use of the software either in source or binary form, must be run
+* on or directly connected to an Analog Devices Inc. component.
+*
+* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+********************************************************************************/
+
+#include <stdint.h>
+#include "mbed.h"
+#include "AD7791.h"
+
+/**
+ * @brief AD7791 constructor, sets CS pin and SPI format
+ * @param CS - (optional)chip select of the AD7791
+ * @param MOSI - (optional)pin of the SPI interface
+ * @param MISO - (optional)pin of the SPI interface
+ * @param SCK - (optional)pin of the SPI interface
+ */
+AD7791::AD7791(float reference_voltage,
+ PinName CS,
+ PinName MOSI,
+ PinName MISO,
+ PinName SCK) :
+ miso(MISO), ad7791(MOSI, MISO, SCK), cs(CS), _vref(reference_voltage)
+{
+ cs = true; // cs is active low
+ ad7791.format(8, _SPI_MODE);
+ _continous_conversion = true;
+ _channel = DIFFERENTIAL;
+}
+
+/**
+ * @brief Set AD7791 SPI frequency
+ * @param hz - SPI bus frequency in hz
+ * @return none
+ */
+void AD7791::frequency(int hz)
+{
+ ad7791.frequency(hz);
+}
+
+/**
+ * @brief Resets the AD7791
+ * @return none
+ */
+void AD7791::reset()
+{
+ ad7791.format(8, _SPI_MODE);
+ cs = false;
+ wait_us(_DELAY_TIMING);
+ ad7791.write(_RESET);
+ ad7791.write(_RESET);
+ ad7791.write(_RESET);
+ ad7791.write(_RESET);
+ wait_us(_DELAY_TIMING);
+ cs = true;
+ _continous_conversion = true;
+}
+
+/**
+ * Sets the mode register. Also sets continous mode and range based on the value
+ * written in reg_val
+ * @param reg_val
+ */
+void AD7791::write_mode_reg(uint8_t reg_val)
+{
+ write_reg(MODE_REG, reg_val);
+ uint8_t continous_mode = (reg_val & 0xC0);
+ if(continous_mode == 0x00) {
+ _continous_conversion = true;
+ } else {
+ _continous_conversion = false;
+ }
+ /* uint8_t range = (reg_val & 0x30);
+ _PGA_gain = 1 << (range >> 4);*/
+
+}
+
+/**
+ * Reads the mode register and returns its value
+ * @return value of the mode register
+ */
+uint8_t AD7791::read_mode_reg()
+{
+ return read_reg(MODE_REG);
+}
+
+/**
+ * Writes the filter register
+ * @param regValue value to be written.
+ */
+void AD7791::write_filter_reg(uint8_t reg_val)
+{
+ write_reg(FILTER_REG, reg_val);
+}
+
+/**
+ * Reads the filter register and returns its value
+ * @return the value of the filter register
+ */
+uint8_t AD7791::read_filter_reg()
+{
+ return read_reg(FILTER_REG);
+}
+
+/**
+ * Reads the data register and returns its value
+ * @return value of the data register
+ */
+uint32_t AD7791::read_data_reg()
+{
+ uint32_t data_result;
+ ad7791.format(8, _SPI_MODE);
+ cs = false;
+ ad7791.write(_DATA_READ | (static_cast<uint8_t>(_channel)));
+ data_result = ((ad7791.write(_DUMMY_BYTE)) << 16);
+ data_result |= ((ad7791.write(_DUMMY_BYTE)) << 8 );
+ data_result |= (ad7791.write(_DUMMY_BYTE));
+ cs = true;
+ return data_result;
+}
+
+/**
+ * Reads the status register of the ADC and returns its value
+ * @return value of the status reg
+ */
+uint8_t AD7791::read_status_reg()
+{
+ return read_reg(STATUS_REG);
+}
+
+
+/**
+ * @brief Enables/disables continous_conversion mode
+ * In Single Conversion mode, read_u16 method will read the MODE register of the ADC,
+ * then write the Start single conversion bit and wait for the DOUT/RDY pin to go low,
+ * When the pin is driven low, data register is read back from the ADC.
+ *
+ * In Continous conversion mode, read_u16 method will poll the DOUT/RDY pin, if it is low,
+ * the data register is read back from the ADC.
+ *
+ * @param mode
+ * true - continous conversion mode enabled
+ * false - single conversion mode enabled
+ */
+void AD7791::set_conversion_mode(AD7791Mode_t mode)
+{
+ uint8_t mode_reg_val;
+ mode_reg_val = read_mode_reg() & 0x3F;
+ mode_reg_val = mode_reg_val | (static_cast<uint8_t>(mode));
+ write_mode_reg(mode);
+}
+
+/**
+ * - From mbed AnalogIn API -
+ * @brief Read the input voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
+ * Depending on the conversion mode, this method will have different behavior. Conversion mode is set using
+ * set_continous_conversion_mode(bool).
+ *
+ * In Single Conversion mode, read_u16 method will read the MODE register of the ADC,
+ * then write the Start single conversion bit and wait for the DOUT/RDY pin to go low,
+ * When the pin is driven low, data register is read back from the ADC.
+ *
+ * In Continous conversion mode, read_u16 method will poll the DOUT/RDY pin, if it is low,
+ * the data register is read back from the ADC.
+ *
+ * @return 16-bit unsigned short representing the current input voltage, normalised to a 16-bit value
+ * returns -1 (0xFFFF) along with a debug message if conversion failed.
+ */
+uint32_t AD7791::read_u32(void)
+{
+ uint32_t data_result = 0;
+ ad7791.format(8, _SPI_MODE);
+ cs = false;
+ uint16_t timeout_cnt = 0;
+ if(_continous_conversion == false) {
+
+ uint8_t mode_reg = read_mode_reg();
+ wait_us(_DELAY_TIMING);
+
+ cs = false;
+ mode_reg = (mode_reg & 0x3F) | MD1; // mask single conversion bits
+ ad7791.write((MODE_REG << 4) | (static_cast<uint8_t>(_channel))); // start single conversion
+ ad7791.write(mode_reg);
+ timeout_cnt = _SINGLE_CONVERSION_TIMEOUT; // starts timeout
+ } else {
+ timeout_cnt = _CONTINOUS_CONVERSION_TIMEOUT; // starts timeout
+ }
+ wait_us(1);
+
+ while(miso) { // wait for the MISO pin to go low.
+ if(timeout_cnt) {
+ timeout_cnt--;
+ } else {
+ cs = true;
+#ifdef AD7791_DEBUG_MODE
+ printf("timeout occurred reading the AD7791. "); // error, MISO line didn't toggle
+#endif
+ return -1; // ERROR
+ }
+ wait_us(10);
+ }
+
+ ad7791.write(_DATA_READ | (static_cast<uint8_t>(_channel)));
+ data_result = ((ad7791.write(_DUMMY_BYTE)) << 16);
+ data_result |= ((ad7791.write(_DUMMY_BYTE)) << 8 );
+ data_result |= (ad7791.write(_DUMMY_BYTE));
+ cs = true;
+ return data_result;
+}
+
+uint16_t AD7791::read_u16(void)
+{
+ uint32_t data = read_u32();
+ return static_cast<uint16_t>((data & 0xffff00) >> 8);
+}
+
+/**
+ * @brief Reads a register of the AD7791
+ * @param address - address of the register
+ * @return value of the register
+ */
+uint16_t AD7791::read_reg(AD7791Register_t address)
+{
+ uint16_t data = address << 12;
+ data |= _DUMMY_BYTE;
+ data |= _READ_FLAG;
+ data |= (static_cast<uint8_t>(_channel) << 8);
+ return write_spi(data);
+}
+
+/**
+ * @brief Writes a register of the AD7791
+ * @param address - address of the register
+ * @param reg_val - value to be written
+ * @return none
+ *
+ */
+void AD7791::write_reg(AD7791Register_t address, uint8_t reg_val)
+{
+ uint16_t spi_data = address << 12;
+ spi_data |= reg_val;
+ spi_data |= (static_cast<uint8_t>(_channel) << 8);
+ write_spi(spi_data);
+}
+
+/**
+ * @brief Writes 16bit data to the AD7791 SPI interface
+ * @param reg_val to be written
+ * @return data returned by the AD7791
+ */
+uint16_t AD7791::write_spi(uint16_t reg_val)
+{
+ uint16_t data_result;
+ uint8_t upper_byte = (reg_val >> 8) & 0xFF;
+ uint8_t lower_byte = reg_val & 0xFF;
+ ad7791.format(8, _SPI_MODE);
+ cs = false;
+ data_result = (ad7791.write(upper_byte) << 8);
+ data_result |= ad7791.write(lower_byte);
+ cs = true;
+ return data_result;
+}
+
+/**
+ * Sets the reference voltage of the AD7790
+ * @param ref reference voltage to be set
+ */
+void AD7791::set_reference_voltage(float ref)
+{
+ _vref = ref;
+}
+
+/**
+ * Gets the reference voltage of the AD7790
+ * @return reference voltage
+ */
+float AD7791::get_reference_voltage(void)
+{
+ return _vref;
+}
+
+/**
+ * Reads the data register of the ADC and converts the result to volts
+ * Gain needs to be correctly set using set_gain in order to get accurate results
+ * @return voltage of the ADC input
+ */
+float AD7791::read_voltage(void)
+{
+ return data_to_voltage(read_u32());
+}
+
+/**
+ * Converts an uint16_t to voltage.
+ * Gain needs to be correctly set using set_gain in order to get accurate results
+ * @param data in uint16_t format
+ * @return float value of voltage (in V)
+ */
+float AD7791::data_to_voltage(uint32_t data)
+{
+ return ((data / static_cast<float>(_RESOLUTION / 2)) - 1) * (_vref );
+}
+
+/**
+ * Converts voltage to an uint16_t.
+ * Gain needs to be correctly set using set_gain in order to get accurate results
+ * @param voltage to be converted
+ * @return data in uint16_t format
+ */
+uint32_t AD7791::voltage_to_data(float voltage)
+{
+ return (((voltage / _vref) + 1) * static_cast<float>(_RESOLUTION / 2));
+}
+
+/**
+ * Sets the conversion channel.
+ * @param channel
+ */
+void AD7791::set_channel(AD7791Channel_t channel)
+{
+ _channel = channel;
+}
+
+/**
+ * - From mbed AnalogIn API -
+ * Read the input voltage, represented as a float in the range [0.0, 1.0] - uses the read_u16 method
+ * @returns A floating-point value representing the current input voltage, measured as a percentage
+ * returns 1.0 along with a debug message if the conversion failed
+ */
+float AD7791::read(void)
+{
+ float percent;
+ uint32_t data;
+ data = read_u32();
+ percent = (data / static_cast<float>(_RESOLUTION) ); // translate bipolar conversion to [0.0, 1.0] domain
+ return percent;
+}
+
+#ifdef MBED_OPERATORS
+
+/**
+ * - From mbed AnalogIn API -
+ * An operator shorthand for read()
+ * The float() operator can be used as a shorthand for read() to simplify common code sequences
+ */
+AD7791::operator float()
+{
+ return read();
+}
+
+#endif
+
+
+
diff -r 000000000000 -r 075fe3d08488 AD7791.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/AD7791.h Tue May 03 12:57:07 2016 +0000
@@ -0,0 +1,176 @@
+/**
+* @file AD7791.h
+* @brief Header file for AD7791 ADC
+* @author Analog Devices Inc.
+*
+* For support please go to:
+* Github: https://github.com/analogdevicesinc/mbed-adi
+* Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
+* Product: http://www.analog.com/ad7791
+* More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
+
+********************************************************************************
+* Copyright 2016(c) Analog Devices, Inc.
+*
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* - Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* - Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in
+* the documentation and/or other materials provided with the
+* distribution.
+* - Neither the name of Analog Devices, Inc. nor the names of its
+* contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+* - The use of this software may or may not infringe the patent rights
+* of one or more patent holders. This license does not release you
+* from the requirement that you obtain separate licenses from these
+* patent holders to use this software.
+* - Use of the software either in source or binary form, must be run
+* on or directly connected to an Analog Devices Inc. component.
+*
+* THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
+* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
+* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
+* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+********************************************************************************/
+
+#ifndef AD7791_H
+#define AD7791_H
+
+#include "mbed.h"
+
+/**
+ * Comment this line if you want to turn off the debug mode.
+ * The debug mode will send a message if an exception occurs within AD7791 driver
+ */
+
+#define AD7791_DEBUG_MODE
+
+/**
+ * @brief Analog Devices AD7791 SPI 16-bit Buffered Sigma-Delta ADC
+ */
+class AD7791
+{
+public:
+ /// AD7791 registers
+ typedef enum {
+ COMMUNICATION_REG = 0, ///< Communication register
+ STATUS_REG = 0, ///< Status register
+ MODE_REG, ///< Mode register
+ FILTER_REG, ///< Filter Register
+ DATA_REG ///< Data register
+ } AD7791Register_t;
+
+ /// AD7791 channel configuration
+ typedef enum {
+ DIFFERENTIAL = 0, ///< AIN(+)-AIN(-)
+ RESERVED, ///< reserved
+ SHORT, ///< AIN(-)-AIN(-)
+ VDDMONITOR ///< Monitor VDD
+ } AD7791Channel_t;
+
+ typedef enum {
+ CONTINOUS_CONVERSION_MODE = 0,
+ SINGLE_CONVERSION_MODE = 0x80,
+ SHUTDOWN_MODE = 0xC0
+ } AD7791Mode_t;
+
+ typedef enum {
+ MD1 = 0x80, ///< Mode Select Bit 1
+ MD0 = 0x40, ///< Mode Select Bit 0
+// G1 = 0x20, ///< Range bit 1
+// G0 = 0x10, ///< Range bit 0
+ BO = 0x08, ///< Burnout Current Enable bit
+ UB = 0x04, ///< Unipolar/Bipolar bit
+ BUF = 0x02, ///< Buffered mode bit
+ } ModeRegisterBits_t;
+
+ typedef enum {
+ CLKDIV1 = 0x40, ///< Clock divider bit 1
+ CLKDIV0 = 0x20, ///< Clock divider bit 0
+ FS2 = 0x04, ///< Update rate bit 2
+ FS1 = 0x02, ///< Update rate bit 1
+ FS0 = 0x01, ///< Update rate bit 0
+ } FilterRegisterBits_t;
+
+ /* typedef enum {
+ RANGE_VREF = 0,
+ RANGE_VREF_DIV_2,
+ RANGE_VREF_DIV_4,
+ RANGE_VREF_DIV_8,
+ } AnalogInputRange_t;
+ */
+ /** SPI configuration & constructor */
+ AD7791( float reference_voltage, PinName CS = SPI_CS, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK);
+ void frequency(int hz);
+
+ /** Low level SPI bus comm methods */
+ void reset(void);
+
+ /** Register access methods*/
+ void set_channel(AD7791Channel_t channel);
+ void set_conversion_mode(AD7791Mode_t mode);
+ uint32_t read_data_reg();
+ uint8_t read_status_reg(void);
+ void write_filter_reg(uint8_t regVal);
+ uint8_t read_filter_reg(void);
+ void write_mode_reg(uint8_t regVal);
+ uint8_t read_mode_reg(void);
+// void set_range(AnalogInputRange_t range);
+// AnalogInputRange_t get_range(void);
+
+ /** Reference voltage methods */
+ void set_reference_voltage(float ref);
+ float get_reference_voltage(void);
+
+ /** Voltage read methods */
+ float read_voltage(void);
+ float data_to_voltage(uint32_t data);
+ uint32_t voltage_to_data(float voltage);
+
+ /** AnalogIn API */
+ float read(void);
+ uint32_t read_u32(void);
+ uint16_t read_u16(void);
+
+#ifdef MBED_OPERATORS
+ operator float();
+#endif
+
+private:
+ DigitalIn miso;
+ SPI ad7791; ///< SPI instance of the AD7791
+ DigitalOut cs; ///< DigitalOut instance for the chipselect of the AD7791
+
+ float _vref;
+// uint8_t _PGA_gain;
+ bool _continous_conversion;
+ AD7791Channel_t _channel;
+
+ void write_reg(AD7791Register_t regAddress, uint8_t regValue);
+ uint16_t write_spi(uint16_t data);
+ uint16_t read_reg (AD7791Register_t regAddress);
+
+ const static uint16_t _SINGLE_CONVERSION_TIMEOUT = 0xFFFF; // in 10us = 100ms
+ const static uint16_t _CONTINOUS_CONVERSION_TIMEOUT = 0xFFFF;
+ const static uint32_t _RESOLUTION = 0xFFFFFF;
+ const static uint8_t _RESET = 0xFF;
+ const static uint8_t _DUMMY_BYTE = 0xFF;
+ const static uint16_t _READ_FLAG = 0x0800;
+ const static uint8_t _DATA_READ = 0x38; // Read from the Data Register
+ const static uint8_t _DELAY_TIMING = 0x02;
+ const static uint8_t _SPI_MODE = 3;
+};
+
+#endif
Analog Devices AD7791