Driver for the Microchip MCP432x series of ADCs.

Dependents:   AKDP-RevD7_014

Fork of MCP342x by Osamu Koizumi

Revision:
1:bc877c37027c
Parent:
0:78c512aa4d18
Child:
2:96d9bfe25b03
--- a/mcp342x.cpp	Fri Apr 29 16:38:37 2016 +0000
+++ b/mcp342x.cpp	Fri Apr 29 23:53:18 2016 +0000
@@ -0,0 +1,217 @@
+#include "mcp342x.h"
+
+
+#define LEN_DATA_REGISTER  3          // Length of the data registers.
+#define LEN_ONE_BYTE       1
+
+MCP342X::MCP342X(I2C *conn, SlaveAddress addr) {
+    slaveAddress = addr;
+    connection = conn;
+    
+    init();
+}
+
+MCP342X::Status MCP342X::init() {
+    Status status;
+    int16_t val = 0;
+    
+    // Reads the current configuration.
+    if ((status=readData(&val, &currentConfig)) != SUCCESS) {
+        return status;
+    }
+
+    // Initialize internal variable    
+    currentConfig.measurementTrigger = NONE;
+    
+    return status;
+}
+
+MCP342X::Status MCP342X::readData(int16_t *val, Config *config) {
+    char buf[LEN_DATA_REGISTER];
+    
+    // Reads data registers.
+    if (connection->read((slaveAddress << 1), buf, LEN_DATA_REGISTER) != 0) {
+        return ERROR_I2C_READ;
+    }
+    
+    // Decodes configuration register data.
+    decodeConfigurationRegister(config, buf[2]);   
+
+    // Converts AD value
+    *val = (int16_t)((buf[0] << 8) | buf[1]);
+    
+    return SUCCESS;
+}
+
+void MCP342X::decodeConfigurationRegister(Config *config, uint8_t regVal) {
+    uint8_t tmp = 0;
+
+    // For the meaning of each bit, see the section 5.2 in the datasheet.
+    
+    // Decodes Ready Bit (~RDY), Bit 7
+    tmp = ((0x80 & regVal) >> 7);
+    if (tmp == 0x00) {
+        config->dataStatus = DATA_UPDATED;
+    } else {
+        config->dataStatus = DATA_NOT_UPDATED;
+    }
+    
+    // Decodes Channel Selection Bits, Bit 6-5
+    tmp = ((0x60 & regVal) >> 5);
+    if (tmp == 0x00) {
+        config->adcChannel = ADC_CH1;
+    } else if (tmp == 0x01) {
+        config->adcChannel = ADC_CH2;
+    } else if (tmp == 0x02) {
+        config->adcChannel = ADC_CH3;
+    } else {  //  ch == 0x03
+        config->adcChannel = ADC_CH4;
+    }
+
+    // Decodes Conversion Mode Bit, Bit 4
+    tmp = ((0x10 & regVal) >> 4);
+    if (tmp == 0x01) {
+        config->conversionMode = CONTINUOUS;
+    } else {
+        config->conversionMode = ONE_SHOT;
+    }
+
+    // Decodes Sample Rate Selection Bit
+    tmp = ((0x0C & regVal) >> 2);
+    if (tmp == 0x00) {
+        config->sampleSetting = SAMPLE_240HZ_12BIT;
+    } else if (tmp == 0x01) {
+        config->sampleSetting = SAMPLE_60HZ_14BIT;
+    } else {
+        config->sampleSetting = SAMPLE_15HZ_16BIT;
+    }
+    
+    // Decodes PGA Gain Selection Bits
+    tmp = (0x03 & regVal);
+    if (tmp == 0x00) {
+        config->pgaSetting = PGA_1X;
+    } else if (tmp == 0x01) {
+        config->pgaSetting = PGA_2X;
+    } else if (tmp == 0x02) {
+        config->pgaSetting = PGA_4X;
+    } else {
+        config->pgaSetting = PGA_8X;
+    }
+}
+
+MCP342X::Status MCP342X::setConfig(const Config *config) {
+    char val = 0;
+    
+    // Measurement trigger
+    if (config->measurementTrigger == TRIGGER) {
+        val |= 0x80;
+    } else {
+        val |= 0x00;
+    }
+
+    // Channel Selection
+    if (config->adcChannel == ADC_CH1) {
+        val |= 0x00;
+    } else if (config->adcChannel == ADC_CH2) {
+        val |= 0x20;
+    } else if (config->adcChannel == ADC_CH3) {
+        val |= 0x40;
+    } else {  // config->adcChannel == ADC_CH4
+        val |= 0x60;
+    }
+    
+    // Conversion Mode
+    if (config->conversionMode == CONTINUOUS) {
+        val |= 0x10;
+    } else if (config->conversionMode == ONE_SHOT) {
+        val |= 0x00;
+    }
+    
+    // Sample Rate
+    if (config->sampleSetting == SAMPLE_240HZ_12BIT) {
+        val |= 0x00;
+    } else if (config->sampleSetting == SAMPLE_60HZ_14BIT) {
+        val |= 0x04;
+    } else { //config->sampleSetting == SAMPLE_15HZ_16BIT
+        val |= 0x08;
+    }
+    
+    // PGA Gain Selection
+    if (config->pgaSetting == PGA_1X) {
+        val |= 0x00;
+    } else if (config->pgaSetting == PGA_2X) {
+        val |= 0x01;
+    } else if (config->pgaSetting == PGA_4X) {
+        val |= 0x02;
+    } else { // config->pgaSetting == PGA_8X) {
+        val |= 0x03;
+    }
+    
+    // Write to the device.
+    if (connection->write((slaveAddress << 1), &val, LEN_ONE_BYTE) != 0) {
+        return ERROR_I2C_WRITE;
+    }
+    
+    return SUCCESS;
+}
+
+
+MCP342X::Status MCP342X::setChannel(AdcChannel ch) {
+    currentConfig.adcChannel = ch;
+    return setConfig(&currentConfig);
+}
+
+MCP342X::AdcChannel MCP342X::getChannel() {
+    return currentConfig.adcChannel;
+}
+
+MCP342X::Status MCP342X::setConversionMode(ConversionMode mode) {
+    currentConfig.conversionMode = mode;
+    return setConfig(&currentConfig);
+}
+
+MCP342X::ConversionMode MCP342X::getConversionMode() {
+    return currentConfig.conversionMode;
+}
+
+MCP342X::Status MCP342X::setSampleSetting(SampleSetting s) {
+    currentConfig.sampleSetting = s;
+    return setConfig(&currentConfig);
+}
+
+MCP342X::SampleSetting MCP342X::getSampleSetting() {
+    return currentConfig.sampleSetting;
+}
+
+MCP342X::Status MCP342X::setPgaSetting(PgaSetting s) {
+    currentConfig.pgaSetting = s;
+    return setConfig(&currentConfig);
+}
+
+MCP342X::PgaSetting MCP342X::getPgaSetting() {
+    return currentConfig.pgaSetting;
+}
+
+MCP342X::Status MCP342X::getData(Data *pt) {
+    Status status;
+    
+    int16_t val = 0;
+    if ((status=readData(&val, &currentConfig)) != SUCCESS) {
+        return status;
+    }
+    
+    pt->st = currentConfig.dataStatus;
+    pt->value = val;
+    
+    return status;
+}
+
+MCP342X::Status MCP342X::trigger(){
+    Status status;
+    
+    currentConfig.measurementTrigger = TRIGGER;
+    status = setConfig(&currentConfig);
+    currentConfig.measurementTrigger = NONE;
+    
+    return status;
+}
\ No newline at end of file