Kenji Arai / MCP3425

Dependents:   check_ADC_MCP3425

Revision:
0:29be5dda6cf2
Child:
1:223248a79e87
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP3425.cpp	Sun Mar 18 01:02:54 2018 +0000
@@ -0,0 +1,181 @@
+/*
+ * mbed library program
+ *  16-Bit Analog-to-Digital Converter with I2C Interface
+ *  MCP3425 by Microchip Technology Inc.
+ *
+ * Copyright (c) 2018 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  http://mbed.org/users/kenjiArai/
+ *      Modify:     March     17th, 2018
+ *      Revised:    March     18th, 2018
+ */
+
+#include "MCP3425.h"
+
+extern Serial pc;
+
+// BIT DEFINITION
+#define RDY_BIT                     (1UL << 7)
+#define CONVERSION_MODE_BIT         (1UL << 4)
+#define SAMPLE_RATE_BIT             (3UL << 2)
+#define PGA_GAIN_BIT                (3UL << 0)
+
+#if (MBED_MAJOR_VERSION == 2)
+#define WAIT_MS(x)              wait_ms(x)
+#elif (MBED_MAJOR_VERSION == 5)
+#define WAIT_MS(x)              Thread::wait(x)
+#else
+#warning "I cannot control wait_ms()!!"
+#endif
+
+MCP3425::MCP3425 (PinName p_sda, PinName p_scl)
+    : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
+{
+    mcp3425_addr = MCP3425A0T_ADDR; // Chip MCP3425A0T-E/CH
+    init();
+}
+
+MCP3425::MCP3425 (PinName p_sda, PinName p_scl, uint8_t addr)
+    : _i2c_p(new I2C(p_sda, p_scl)), _i2c(*_i2c_p)
+{
+    mcp3425_addr = addr;    // you need get diffrent part nuber of chip
+    init();
+}
+
+MCP3425::MCP3425 (I2C& p_i2c)
+    : _i2c(p_i2c)
+{
+    mcp3425_addr = MCP3425A0T_ADDR; // Chip MCP3425A0T-E/CH
+    init();
+}
+
+MCP3425::MCP3425 (I2C& p_i2c, uint8_t addr)
+    : _i2c(p_i2c)
+{
+    mcp3425_addr = addr;    // you need get diffrent part nuber of chip
+    init();
+}
+
+void MCP3425::init()
+{
+    offset_volt = 0.0f;             // none offset
+    compensation_ref = 1.0f;        // no compensation
+    config.pga_gain = PGA_GAIN_1;   // Gain x1
+    config.sample_rate = SAMPLE_RATE_15SPS_16BIT;   // 16bit resolution
+    config.conversion_mode = CONV_MODE_CONTINUOUS;  // Continuous conversion
+    config_byte = convert_config2byte(&config); // make one byte
+    buf[0] = config_byte;
+    _i2c.write((int)mcp3425_addr, (char *)buf, 1);  // write into config reg.
+}
+
+int16_t MCP3425::read_16bit()
+{
+    uint32_t timeout = 1000U;   // timeout
+    if (config.conversion_mode == CONV_MODE_ONE_SHOT) {
+        // trigger for starting conversion
+        buf[0] = config_byte + RDY_BIT;
+        _i2c.write((int)mcp3425_addr, (char *)buf, 1);
+    }
+    do {
+        _i2c.read( (int)mcp3425_addr, (char *)buf, 3);
+        if ((buf[2] & RDY_BIT) == 0) {
+            break;      // end of conversion
+        }
+        if (--timeout == 0) {
+            return -1;  // error
+        }
+        uint8_t spd = (buf[2] >> 2) & 0x03;
+        if (spd == SAMPLE_RATE_60SPS_14BIT) {
+            WAIT_MS(6);     // conversion time = 16.7ms
+        } else if (spd == SAMPLE_RATE_15SPS_16BIT) {
+            WAIT_MS(24);    // conversion time = 66.7ms
+        } else {  // == SAMPLE_RATE_240SPS_12BIT
+            WAIT_MS(2);     // no wait
+        }
+    } while(true);
+    dt_adc16 = (uint16_t)buf[0] << 8;
+    dt_adc16 += (uint16_t)buf[1];
+    return dt_adc16;
+}
+
+float MCP3425::read_voltage()
+{
+    float dt16 = (float)read_16bit();
+    switch(config.sample_rate) {
+        case SAMPLE_RATE_240SPS_12BIT:
+            dt16 /=  2048.0f; // 11bit (0x7ff +1)
+            break;
+        case SAMPLE_RATE_60SPS_14BIT:
+            dt16 /= 16384.0f; // 14bit (0x3fff +1)
+            break;
+        case SAMPLE_RATE_15SPS_16BIT:
+            dt16 /= 32768.0f; // 15bit (0x7fff +1)
+            break;
+        default:
+            return -1;
+    }
+    switch(config.pga_gain) {
+        case PGA_GAIN_1:
+            dt16 /= 1.0f;
+            break;
+        case PGA_GAIN_2:
+            dt16 /= 2.0f;
+            break;
+        case PGA_GAIN_4:
+            dt16 /= 4.0f;
+            break;
+        case PGA_GAIN_8:
+            dt16 /= 8.0f;
+            break;
+        default:
+            return -1;
+    }
+    dt_adc_f = dt16 * 2.048f;
+    dt_adc_f -= offset_volt;
+    dt_adc_f *= compensation_ref;
+    return dt_adc_f;
+}
+
+void MCP3425::set_offset_volt(float offset)
+{
+    offset_volt = offset;
+}
+
+void MCP3425::set_vref_compensation(float compensation)
+{
+    compensation_ref = compensation;
+}
+
+void MCP3425::set_config(mcp3425_config_t *parameter)
+{
+    config.pga_gain = parameter->pga_gain & 0x03;
+    config.sample_rate = parameter->sample_rate & 0x03;
+    config.conversion_mode = parameter->conversion_mode & 0x01;
+    config_byte = convert_config2byte(&config);
+    buf[0] = config_byte;
+    _i2c.write((int)mcp3425_addr, (char *)buf, 1);
+}
+
+void MCP3425::read_config(mcp3425_config_t *parameter)
+{
+    _i2c.read( (int)mcp3425_addr, (char *)buf, 3);
+    config_byte = buf[2] & 0x1f;
+    parameter->pga_gain = config_byte & PGA_GAIN_BIT;
+    parameter->sample_rate  = (config_byte & SAMPLE_RATE_BIT) >> 2;
+    parameter->conversion_mode  = (config_byte & CONVERSION_MODE_BIT) >> 4;
+    config = *parameter;
+}
+
+void MCP3425::frequency(uint32_t hz)
+{
+    _i2c.frequency(hz);
+}
+
+uint8_t MCP3425::convert_config2byte(mcp3425_config_t *config)
+{
+    uint8_t byte = config->pga_gain;
+    byte |= config->sample_rate << 2;
+    byte |= config->conversion_mode << 4;
+    config_byte = byte;
+    return config_byte;
+}