Microchip MCP342x ADC library

mcp342x.h

Committer:
antoniogonzalez
Date:
2016-06-15
Revision:
0:7dbf7356da6b
Child:
1:c4da9889ff85

File content as of revision 0:7dbf7356da6b:

/**
 * Author: Antonio Gonzalez <antgon@cantab.net>
 * Copyright (c) 2016 The Francis Crick Institute.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef MCP342x_h
#define MCP342x_h

#include "mbed.h"

/**
 * @brief Microchip analog-to-digital converter MCP3422/3/4
 *
 * Library for using Microchip's family of analog-to-digital converters
 * MCP3422/3/4. Some features of these include:
 * - 12-, 14-, 16-, or 18-bit ADC.
 * - Two-wire I2C interface.
 * - Sampling rate, 3.75 (18-bit), 15 (16-bit), 60 (14-bit), or 240
 *   (12-bit) SPS.
 * - Two (MCP3422/3) or four (MCP3424) channels, differential input.
 * - Internal voltage reference, 2.048 V.
 * - Selectable PGA, x1, x2, x4, or x8.
 * - Conversion modes: one-shot or continuous.
 *
 * TODO:
 * - Implement 'conversion mode one-shot'
 *
 * Example:
 * @code
 * #include "mbed.h"
 * #include "mcp342x.h"
 *
 * I2C i2c(p9, p10);
 * MCP342x mcp_adc(&i2c);
 *
 * int main(){
 *     mcp_adc.set_channel(MCP342x::CHANNEL_2);
 *     mcp_adc.set_pga(MCP342x::PGA_4);
 *     mcp_adc.set_resolution(MCP342x::RESOLUTION_12);
 *
 *     while(1){
 *         // Channel 2 was selected above. Read data from this channel.
 *         long chan2_val = mcp_adc.read();
 *
 *         // Select now channel 1 and read it.
 *         mcp_adc.set_channel(MCP342x::CHANNEL_1);
 *         long chan1_val = mcp_adc.read();
 *
 *         printf("CH1 %i  CH2 %i\r\n", chan1_val, chan2_val);
 *         wait(5);
 *     }
 * }
 * @endcode
 */
class MCP342x
{
public:
    // Registers.
    // The device has only one register, which is the configuration
    // byte. It consists of these bits:
    //   7    ~ready
    //   6-5  channel selection
    //   4    conversion mode (one-shot, continuous)
    //   3-2  sample rate selection (12, 14, 16, or 18)
    //   1-0  PGA gain selection (1x, 2x, 4x, or 8x)
    typedef enum {
        REG_PGA_Pos = 0,
        REG_RESOLUTION_Pos = 2,
        REG_MODE_Pos = 4,
        REG_CHANNEL_Pos = 5,
        REG_RDY_Pos = 7,

        REG_PGA_Clear = ~(0x3 << REG_PGA_Pos),
        REG_RESOLUTION_Clear = ~(0x3 << REG_RESOLUTION_Pos),
        REG_MODE_Clear = ~(0x1 << REG_MODE_Pos),
        REG_CHANNEL_Clear = ~(0x3 << REG_CHANNEL_Pos),
        REG_RDY_Clear = ~(0x1 << REG_RDY_Pos)
    } mcp342x_reg_t;

    // Programmable gain.
    typedef enum {
        PGA_1 = 0,
        PGA_2 = 1,
        PGA_4 = 2,
        PGA_8 = 3
    } mcp342x_pga_t;

    // Resolution.
    typedef enum {
        RESOLUTION_12 = 0,
        RESOLUTION_14 = 1,
        RESOLUTION_16 = 2,
        RESOLUTION_18 = 3
    } mcp342x_resolution_t;

    // Conversion mode.
    typedef enum {
        CONVERSION_MODE_ONESHOT = 0,
        CONVERSION_MODE_CONTINUOUS = 1
    } mcp342x_conversion_mode_t;

    // Channels.
    typedef enum {
        CHANNEL_1 = 0,
        CHANNEL_2 = 1,
        CHANNEL_3 = 2,
        CHANNEL_4 = 3
    } mcp342x_channel_t;

    /**
    * MCP342x constructor
    *
    * @param i2c Pointer to I2C
    * @param device_address Address for this sensor
    */
    MCP342x(I2C *i2c, uint8_t device_address = 0b000);

    /**
    * Set channel to read from.
    *
    * @param channel Channel number
    */
    void set_channel(mcp342x_channel_t channel);

    /**
    * Set conversion mode.
    *
    * @param mode Conversion mode. Options are
    * MCP342x::CONVERSION_MODE_ONESHOT or
    * MCP342x::CONVERSION_MODE_CONTINUOUS.
    */
    void set_conversion_mode(mcp342x_conversion_mode_t mode);

    /**
    * Set resolution.
    *
    * @param resolution Resolution, one of
    * MCP342x::RESOLUTION_12, MCP342x::RESOLUTION_14,
    * MCP342x::RESOLUTION_16 or MCP342x::RESOLUTION_18.
    */
    void set_resolution(mcp342x_resolution_t resolution);

    /**
    * Set programable gain amplifier. Options are
    * MCP342x::PGA_1, MCP342x::PGA_2, MCP342x::PGA_4, or MCP342x::PGA_8.
    */
    void set_pga(mcp342x_pga_t pga);

    /**
    * Read the ADC value. The value will be that read from the channel
    * set previously (`set_channel`)
    *
    * @return Analog measurement in raw data (integer)
    */
    long read();

    /**
    * Read the ADC value in volts. The value will be that read from the
    * channel set previously (`set_channel`).
    *
    * The data are coded in two's complements format, and the final
    * voltage is also a function of the resolution and gain settings.
    * This function follows the equations presented in the device's
    * datasheet (Microchip DS22088C), Section 4.9.
    *
    * @return Analog measurement in volts (float)
    */
    float read_volts();

private:
    uint8_t _address;
    I2C *_i2c;
    uint8_t _resolution;
    uint8_t _pga;
    char _configuration[1];
    static const uint8_t _device_code = 0b1101; // Hardcoded in factory
    void _write_configuration();
};

//void mcp342x_start_conversion(void); For one-shot mode.

#endif