First commit
authorKevin Townsend <kevin@ktownsend.com>
Sat, 23 Jun 2012 11:14:10 +0000 (13:14 +0200)
committerKevin Townsend <kevin@ktownsend.com>
Sat, 23 Jun 2012 11:14:10 +0000 (13:14 +0200)
drivers/adc/ads1015/ads1015.c [new file with mode: 0644]
drivers/adc/ads1015/ads1015.h [new file with mode: 0644]

diff --git a/drivers/adc/ads1015/ads1015.c b/drivers/adc/ads1015/ads1015.c
new file mode 100644 (file)
index 0000000..7f37cc2
--- /dev/null
@@ -0,0 +1,301 @@
+/**************************************************************************/
+/*! 
+    @file     ads1015.c
+    @author   K. Townsend (microBuilder.eu)
+       
+    @brief    Drivers for the TI ADS1015 12-Bit I2C ADC
+
+    @section DESCRIPTION
+
+    The ADS1015 is a 4-channel, 12-bit I2C ADC with a programmable
+    comparator and an internal PGA (from 2/3 to 16x gain).  It can be
+    configured for four single-ended channels or two differential inputs.
+    The comparator can be used in both traditional and windowed mode.
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. 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.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, 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 "ads1015.h"
+#include "core/systick/systick.h"
+
+extern volatile uint8_t   I2CMasterBuffer[I2C_BUFSIZE];
+extern volatile uint8_t   I2CSlaveBuffer[I2C_BUFSIZE];
+extern volatile uint32_t  I2CReadLength, I2CWriteLength;
+
+static bool _ads1015Initialised = false;
+
+/**************************************************************************/
+/*! 
+    @brief  Sends a single command byte over I2C
+*/
+/**************************************************************************/
+static ads1015Error_t ads1015WriteRegister (uint8_t reg, uint16_t value)
+{
+  ads1015Error_t error = ADS1015_ERROR_OK;
+
+  // Clear write buffers
+  uint32_t i;
+  for ( i = 0; i < I2C_BUFSIZE; i++ )
+  {
+    I2CMasterBuffer[i] = 0x00;
+  }
+
+  I2CWriteLength = 4;
+  I2CReadLength = 0;
+  I2CMasterBuffer[0] = ADS1015_ADDRESS;       // I2C device address
+  I2CMasterBuffer[1] = reg;                   // Register
+  I2CMasterBuffer[2] = value >> 8;            // Upper 8-bits
+  I2CMasterBuffer[3] = value & 0xFF;          // Lower 8-bits
+  i2cEngine();
+
+  // ToDo: Add in proper I2C error-checking
+  return error;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads a 16 bit values over I2C
+*/
+/**************************************************************************/
+static ads1015Error_t ina219Read16(uint8_t reg, uint16_t *value)
+{
+  ads1015Error_t error = ADS1015_ERROR_OK;
+
+  // Clear write buffers
+  uint32_t i;
+  for ( i = 0; i < I2C_BUFSIZE; i++ )
+  {
+    I2CMasterBuffer[i] = 0x00;
+  }
+
+  I2CWriteLength = 2;
+  I2CReadLength = 2;
+  I2CMasterBuffer[0] = ADS1015_ADDRESS;           // I2C device address
+  I2CMasterBuffer[1] = reg;                       // Command register
+  // Append address w/read bit
+  I2CMasterBuffer[2] = ADS1015_ADDRESS | ADS1015_READBIT;  
+  i2cEngine();
+
+  // Shift values to create properly formed integer
+  *value = ((I2CSlaveBuffer[0] << 8) | I2CSlaveBuffer[1]);
+
+  // ToDo: Add in proper I2C error-checking
+  return error;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Initialises the I2C block
+*/
+/**************************************************************************/
+ads1015Error_t ads1015Init(void)
+{
+  ads1015Error_t error = ADS1015_ERROR_OK;
+
+  // Initialise I2C
+  if (i2cInit(I2CMASTER) == false)
+  {
+    return ADS1015_ERROR_I2CINIT;    /* Fatal error */
+  }
+
+  _ads1015Initialised = true;
+  return error;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads the 12-bit conversion results from the specified channel
+*/
+/**************************************************************************/
+ads1015Error_t ads1015ReadADC_SingleEnded(uint8_t channel, uint16_t *value)
+{
+  ads1015Error_t error = ADS1015_ERROR_OK;
+
+  if (!(_ads1015Initialised))
+  {
+    ads1015Init();
+  }
+
+  if (channel > 3)
+  {
+    *value = 0;
+    return ADS1015_ERROR_INVALIDCHANNEL;
+  }
+
+  // Start with default values
+  uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE    | // Disable the comparator (default val)
+                    ADS1015_REG_CONFIG_CLAT_NONLAT  | // Non-latching (default val)
+                    ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low   (default val)
+                    ADS1015_REG_CONFIG_CMODE_TRAD   | // Traditional comparator (default val)
+                    ADS1015_REG_CONFIG_DR_1600SPS   | // 1600 samples per second (default)
+                    ADS1015_REG_CONFIG_MODE_SINGLE;   // Single-shot mode (default)
+
+  // Set PGA/voltage range
+  config |= ADS1015_REG_CONFIG_PGA_6_144V;            // +/- 6.144V range (limited to VDD +0.3V max!)
+
+  // Set single-ended input channel
+  switch (channel)
+  {
+    case (0):
+      config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
+      break;
+    case (1):
+      config |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
+      break;
+    case (2):
+      config |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
+      break;
+    case (3):
+      config |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
+      break;
+  }
+
+  // Set 'start single-conversion' bit
+  config |= ADS1015_REG_CONFIG_OS_SINGLE;
+
+  // Write config register to the ADC
+  error = ads1015WriteRegister(ADS1015_REG_POINTER_CONFIG, config);
+  if (error) return error;
+
+  // Wait for the conversion to complete
+  systickDelay(1);
+
+  // Read the conversion results
+  error = ina219Read16(ADS1015_REG_POINTER_CONVERT, value);
+  if (error) return error;
+
+  // Shift results 4-bits to the right
+  *value = *value >> 4;
+
+  return error;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads the 12-bit conversion results, measuring the voltage
+            difference between the P (AIN0) and N (AIN1) input.  Generates
+            a signed 12-bit value since the difference can be either
+            positive or negative.
+*/
+/**************************************************************************/
+ads1015Error_t ads1015ReadADC_Differential_0_1(int16_t *value)
+{
+  ads1015Error_t error = ADS1015_ERROR_OK;
+
+  if (!(_ads1015Initialised))
+  {
+    ads1015Init();
+  }
+
+  // Start with default values
+  uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE    | // Disable the comparator (default val)
+                    ADS1015_REG_CONFIG_CLAT_NONLAT  | // Non-latching (default val)
+                    ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low   (default val)
+                    ADS1015_REG_CONFIG_CMODE_TRAD   | // Traditional comparator (default val)
+                    ADS1015_REG_CONFIG_DR_1600SPS   | // 1600 samples per second (default)
+                    ADS1015_REG_CONFIG_MODE_SINGLE;   // Single-shot mode (default)
+
+  // Set PGA/voltage range
+  config |= ADS1015_REG_CONFIG_PGA_6_144V;            // +/- 6.144V range (limited to VDD +0.3V max!)
+
+  // Set channels
+  config |= ADS1015_REG_CONFIG_MUX_DIFF_0_1;          // AIN0 = P, AIN1 = N
+
+  // Set 'start single-conversion' bit
+  config |= ADS1015_REG_CONFIG_OS_SINGLE;
+
+  // Write config register to the ADC
+  error = ads1015WriteRegister(ADS1015_REG_POINTER_CONFIG, config);
+  if (error) return error;
+
+  // Wait for the conversion to complete
+  systickDelay(1);
+
+  // Read the conversion results
+  error = ina219Read16(ADS1015_REG_POINTER_CONVERT, value);
+  if (error) return error;
+
+  // Shift results 4-bits to the right
+  *value = *value >> 4;
+
+  return error;
+}
+
+/**************************************************************************/
+/*! 
+    @brief  Reads the 12-bit conversion results, measuring the voltage
+            difference between the P (AIN2) and N (AIN3) input.  Generates
+            a signed 12-bit value since the difference can be either
+            positive or negative.
+*/
+/**************************************************************************/
+ads1015Error_t ads1015ReadADC_Differential_2_3(int16_t *value)
+{
+  ads1015Error_t error = ADS1015_ERROR_OK;
+
+  if (!(_ads1015Initialised))
+  {
+    ads1015Init();
+  }
+
+  // Start with default values
+  uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE    | // Disable the comparator (default val)
+                    ADS1015_REG_CONFIG_CLAT_NONLAT  | // Non-latching (default val)
+                    ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low   (default val)
+                    ADS1015_REG_CONFIG_CMODE_TRAD   | // Traditional comparator (default val)
+                    ADS1015_REG_CONFIG_DR_1600SPS   | // 1600 samples per second (default)
+                    ADS1015_REG_CONFIG_MODE_SINGLE;   // Single-shot mode (default)
+
+  // Set PGA/voltage range
+  config |= ADS1015_REG_CONFIG_PGA_6_144V;            // +/- 6.144V range (limited to VDD +0.3V max!)
+
+  // Set channels
+  config |= ADS1015_REG_CONFIG_MUX_DIFF_2_3;          // AIN2 = P, AIN3 = N
+
+  // Set 'start single-conversion' bit
+  config |= ADS1015_REG_CONFIG_OS_SINGLE;
+
+  // Write config register to the ADC
+  error = ads1015WriteRegister(ADS1015_REG_POINTER_CONFIG, config);
+  if (error) return error;
+
+  // Wait for the conversion to complete
+  systickDelay(1);
+
+  // Read the conversion results
+  error = ina219Read16(ADS1015_REG_POINTER_CONVERT, value);
+  if (error) return error;
+
+  // Shift results 4-bits to the right
+  *value = *value >> 4;
+
+  return error;
+}
+
diff --git a/drivers/adc/ads1015/ads1015.h b/drivers/adc/ads1015/ads1015.h
new file mode 100644 (file)
index 0000000..d083c64
--- /dev/null
@@ -0,0 +1,135 @@
+/**************************************************************************/
+/*! 
+    @file     ads1015.h
+    @author   K. Townsend (microBuilder.eu)
+
+    @section LICENSE
+
+    Software License Agreement (BSD License)
+
+    Copyright (c) 2012, K. Townsend
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    2. 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.
+    3. Neither the name of the copyright holders nor the
+    names of its contributors may be used to endorse or promote products
+    derived from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, 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 _ADS1015_H_
+#define _ADS1015_H_
+
+#include "projectconfig.h"
+#include "core/i2c/i2c.h"
+
+/*=========================================================================
+    I2C ADDRESS/BITS
+    -----------------------------------------------------------------------*/
+    #define ADS1015_ADDRESS                 (0x90)    // 1001 000 shifted left 1 bit = 0x90 (ADDR = GND)
+    #define ADS1015_READBIT                 (0x01)
+/*=========================================================================*/
+
+/*=========================================================================
+    POINTER REGISTER
+    -----------------------------------------------------------------------*/
+    #define ADS1015_REG_POINTER_MASK        (0x03)
+    #define ADS1015_REG_POINTER_CONVERT     (0x00)
+    #define ADS1015_REG_POINTER_CONFIG      (0x01)
+    #define ADS1015_REG_POINTER_LOWTHRESH   (0x02)
+    #define ADS1015_REG_POINTER_HITHRESH    (0x03)
+/*=========================================================================*/
+
+/*=========================================================================
+    CONFIG REGISTER
+    -----------------------------------------------------------------------*/
+    #define ADS1015_REG_CONFIG_OS_MASK      (0x8000)
+    #define ADS1015_REG_CONFIG_OS_SINGLE    (0x8000)  // Write: Set to start a single-conversion
+    #define ADS1015_REG_CONFIG_OS_BUSY      (0x0000)  // Read: Bit = 0 when conversion is in progress
+    #define ADS1015_REG_CONFIG_OS_NOTBUSY   (0x8000)  // Read: Bit = 1 when device is not performing a conversion
+
+    #define ADS1015_REG_CONFIG_MUX_MASK     (0x7000)
+    #define ADS1015_REG_CONFIG_MUX_DIFF_0_1 (0x0000)  // Differential P = AIN0, N = AIN1 (default)
+    #define ADS1015_REG_CONFIG_MUX_DIFF_0_3 (0x1000)  // Differential P = AIN0, N = AIN3
+    #define ADS1015_REG_CONFIG_MUX_DIFF_1_3 (0x2000)  // Differential P = AIN1, N = AIN3
+    #define ADS1015_REG_CONFIG_MUX_DIFF_2_3 (0x3000)  // Differential P = AIN2, N = AIN3
+    #define ADS1015_REG_CONFIG_MUX_SINGLE_0 (0x4000)  // Single-ended AIN0
+    #define ADS1015_REG_CONFIG_MUX_SINGLE_1 (0x5000)  // Single-ended AIN1
+    #define ADS1015_REG_CONFIG_MUX_SINGLE_2 (0x6000)  // Single-ended AIN2
+    #define ADS1015_REG_CONFIG_MUX_SINGLE_3 (0x7000)  // Single-ended AIN3
+
+    #define ADS1015_REG_CONFIG_PGA_MASK     (0x0E00)
+    #define ADS1015_REG_CONFIG_PGA_6_144V   (0x0000)  // +/-6.144V range
+    #define ADS1015_REG_CONFIG_PGA_4_096V   (0x0200)  // +/-4.096V range
+    #define ADS1015_REG_CONFIG_PGA_2_048V   (0x0400)  // +/-2.048V range (default)
+    #define ADS1015_REG_CONFIG_PGA_1_024V   (0x0600)  // +/-1.024V range
+    #define ADS1015_REG_CONFIG_PGA_0_512V   (0x0800)  // +/-0.512V range
+    #define ADS1015_REG_CONFIG_PGA_0_256V   (0x0A00)  // +/-0.256V range
+
+    #define ADS1015_REG_CONFIG_MODE_MASK    (0x0100)
+    #define ADS1015_REG_CONFIG_MODE_CONTIN  (0x0000)  // Continuous conversion mode
+    #define ADS1015_REG_CONFIG_MODE_SINGLE  (0x0100)  // Power-down single-shot mode (default)
+
+    #define ADS1015_REG_CONFIG_DR_MASK      (0x00E0)  
+    #define ADS1015_REG_CONFIG_DR_128SPS    (0x0000)  // 128 samples per second
+    #define ADS1015_REG_CONFIG_DR_250SPS    (0x0020)  // 250 samples per second
+    #define ADS1015_REG_CONFIG_DR_490SPS    (0x0040)  // 490 samples per second
+    #define ADS1015_REG_CONFIG_DR_920SPS    (0x0050)  // 920 samples per second
+    #define ADS1015_REG_CONFIG_DR_1600SPS   (0x0080)  // 1600 samples per second (default)
+    #define ADS1015_REG_CONFIG_DR_2400SPS   (0x00A0)  // 2400 samples per second
+    #define ADS1015_REG_CONFIG_DR_3300SPS   (0x00C0)  // 3300 samples per second
+
+    #define ADS1015_REG_CONFIG_CMODE_MASK   (0x0010)
+    #define ADS1015_REG_CONFIG_CMODE_TRAD   (0x0000)  // Traditional comparator with hysteresis (default)
+    #define ADS1015_REG_CONFIG_CMODE_WINDOW (0x0010)  // Window comparator
+
+    #define ADS1015_REG_CONFIG_CPOL_MASK    (0x0008)
+    #define ADS1015_REG_CONFIG_CPOL_ACTVLOW (0x0000)  // ALERT/RDY pin is low when active (default)
+    #define ADS1015_REG_CONFIG_CPOL_ACTVHI  (0x0008)  // ALERT/RDY pin is high when active
+
+    #define ADS1015_REG_CONFIG_CLAT_MASK    (0x0004)  // Determines if ALERT/RDY pin latches once asserted
+    #define ADS1015_REG_CONFIG_CLAT_NONLAT  (0x0000)  // Non-latching comparator (default)
+    #define ADS1015_REG_CONFIG_CLAT_LATCH   (0x0004)  // Latching comparator
+
+    #define ADS1015_REG_CONFIG_CQUE_MASK    (0x0003)
+    #define ADS1015_REG_CONFIG_CQUE_1CONV   (0x0000)  // Assert ALERT/RDY after one conversions
+    #define ADS1015_REG_CONFIG_CQUE_2CONV   (0x0001)  // Assert ALERT/RDY after two conversions
+    #define ADS1015_REG_CONFIG_CQUE_4CONV   (0x0002)  // Assert ALERT/RDY after four conversions
+    #define ADS1015_REG_CONFIG_CQUE_NONE    (0x0003)  // Disable the comparator and put ALERT/RDY in high state (default)
+/*=========================================================================*/
+
+typedef enum
+{
+  ADS1015_ERROR_OK = 0,                // Everything executed normally
+  ADS1015_ERROR_I2CINIT,               // Unable to initialise I2C
+  ADS1015_ERROR_I2CBUSY,               // I2C already in use
+  ADS1015_ERROR_INVALIDCHANNEL,        // Invalid channel specified
+  ADS1015_ERROR_LAST
+}
+ads1015Error_t;
+
+ads1015Error_t ads1015Init(void);
+ads1015Error_t ads1015ReadADC_SingleEnded(uint8_t channel, uint16_t *value);
+ads1015Error_t ads1015ReadADC_Differential_0_1(int16_t *value);
+ads1015Error_t ads1015ReadADC_Differential_2_3(int16_t *value);
+
+#endif
+
+
This page took 0.03938 seconds and 4 git commands to generate.