Driver for the Microchip MCP432x series of ADCs.

Dependents:   AKDP-RevD7_014

Fork of MCP342x by Osamu Koizumi

mcp342x.cpp

Committer:
tkstreet
Date:
2018-08-10
Revision:
10:9e1bb1e16e68
Parent:
9:9e70e215d39a

File content as of revision 10:9e1bb1e16e68:

#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();
}

/**
 * Destructor.
 *
 */
//MCP342X::~MCP342X(){
//    if (connection) delete connection;
//}

MCP342X::Status MCP342X::init() {
    Status status;
    
    // general call reset (software POR)
//    char general_reset = 0x06;
//    connection->write(0, &general_reset, LEN_ONE_BYTE);
    
    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;
}