Driver for the Microchip MCP432x series of ADCs.

Dependents:   AKDP-RevD7_014

Fork of MCP342x by Osamu Koizumi

Committer:
coisme
Date:
Fri Apr 29 23:53:18 2016 +0000
Revision:
1:bc877c37027c
Parent:
0:78c512aa4d18
Child:
2:96d9bfe25b03
Implementation completed.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
coisme 1:bc877c37027c 1 #include "mcp342x.h"
coisme 1:bc877c37027c 2
coisme 1:bc877c37027c 3
coisme 1:bc877c37027c 4 #define LEN_DATA_REGISTER 3 // Length of the data registers.
coisme 1:bc877c37027c 5 #define LEN_ONE_BYTE 1
coisme 1:bc877c37027c 6
coisme 1:bc877c37027c 7 MCP342X::MCP342X(I2C *conn, SlaveAddress addr) {
coisme 1:bc877c37027c 8 slaveAddress = addr;
coisme 1:bc877c37027c 9 connection = conn;
coisme 1:bc877c37027c 10
coisme 1:bc877c37027c 11 init();
coisme 1:bc877c37027c 12 }
coisme 1:bc877c37027c 13
coisme 1:bc877c37027c 14 MCP342X::Status MCP342X::init() {
coisme 1:bc877c37027c 15 Status status;
coisme 1:bc877c37027c 16 int16_t val = 0;
coisme 1:bc877c37027c 17
coisme 1:bc877c37027c 18 // Reads the current configuration.
coisme 1:bc877c37027c 19 if ((status=readData(&val, &currentConfig)) != SUCCESS) {
coisme 1:bc877c37027c 20 return status;
coisme 1:bc877c37027c 21 }
coisme 1:bc877c37027c 22
coisme 1:bc877c37027c 23 // Initialize internal variable
coisme 1:bc877c37027c 24 currentConfig.measurementTrigger = NONE;
coisme 1:bc877c37027c 25
coisme 1:bc877c37027c 26 return status;
coisme 1:bc877c37027c 27 }
coisme 1:bc877c37027c 28
coisme 1:bc877c37027c 29 MCP342X::Status MCP342X::readData(int16_t *val, Config *config) {
coisme 1:bc877c37027c 30 char buf[LEN_DATA_REGISTER];
coisme 1:bc877c37027c 31
coisme 1:bc877c37027c 32 // Reads data registers.
coisme 1:bc877c37027c 33 if (connection->read((slaveAddress << 1), buf, LEN_DATA_REGISTER) != 0) {
coisme 1:bc877c37027c 34 return ERROR_I2C_READ;
coisme 1:bc877c37027c 35 }
coisme 1:bc877c37027c 36
coisme 1:bc877c37027c 37 // Decodes configuration register data.
coisme 1:bc877c37027c 38 decodeConfigurationRegister(config, buf[2]);
coisme 1:bc877c37027c 39
coisme 1:bc877c37027c 40 // Converts AD value
coisme 1:bc877c37027c 41 *val = (int16_t)((buf[0] << 8) | buf[1]);
coisme 1:bc877c37027c 42
coisme 1:bc877c37027c 43 return SUCCESS;
coisme 1:bc877c37027c 44 }
coisme 1:bc877c37027c 45
coisme 1:bc877c37027c 46 void MCP342X::decodeConfigurationRegister(Config *config, uint8_t regVal) {
coisme 1:bc877c37027c 47 uint8_t tmp = 0;
coisme 1:bc877c37027c 48
coisme 1:bc877c37027c 49 // For the meaning of each bit, see the section 5.2 in the datasheet.
coisme 1:bc877c37027c 50
coisme 1:bc877c37027c 51 // Decodes Ready Bit (~RDY), Bit 7
coisme 1:bc877c37027c 52 tmp = ((0x80 & regVal) >> 7);
coisme 1:bc877c37027c 53 if (tmp == 0x00) {
coisme 1:bc877c37027c 54 config->dataStatus = DATA_UPDATED;
coisme 1:bc877c37027c 55 } else {
coisme 1:bc877c37027c 56 config->dataStatus = DATA_NOT_UPDATED;
coisme 1:bc877c37027c 57 }
coisme 1:bc877c37027c 58
coisme 1:bc877c37027c 59 // Decodes Channel Selection Bits, Bit 6-5
coisme 1:bc877c37027c 60 tmp = ((0x60 & regVal) >> 5);
coisme 1:bc877c37027c 61 if (tmp == 0x00) {
coisme 1:bc877c37027c 62 config->adcChannel = ADC_CH1;
coisme 1:bc877c37027c 63 } else if (tmp == 0x01) {
coisme 1:bc877c37027c 64 config->adcChannel = ADC_CH2;
coisme 1:bc877c37027c 65 } else if (tmp == 0x02) {
coisme 1:bc877c37027c 66 config->adcChannel = ADC_CH3;
coisme 1:bc877c37027c 67 } else { // ch == 0x03
coisme 1:bc877c37027c 68 config->adcChannel = ADC_CH4;
coisme 1:bc877c37027c 69 }
coisme 1:bc877c37027c 70
coisme 1:bc877c37027c 71 // Decodes Conversion Mode Bit, Bit 4
coisme 1:bc877c37027c 72 tmp = ((0x10 & regVal) >> 4);
coisme 1:bc877c37027c 73 if (tmp == 0x01) {
coisme 1:bc877c37027c 74 config->conversionMode = CONTINUOUS;
coisme 1:bc877c37027c 75 } else {
coisme 1:bc877c37027c 76 config->conversionMode = ONE_SHOT;
coisme 1:bc877c37027c 77 }
coisme 1:bc877c37027c 78
coisme 1:bc877c37027c 79 // Decodes Sample Rate Selection Bit
coisme 1:bc877c37027c 80 tmp = ((0x0C & regVal) >> 2);
coisme 1:bc877c37027c 81 if (tmp == 0x00) {
coisme 1:bc877c37027c 82 config->sampleSetting = SAMPLE_240HZ_12BIT;
coisme 1:bc877c37027c 83 } else if (tmp == 0x01) {
coisme 1:bc877c37027c 84 config->sampleSetting = SAMPLE_60HZ_14BIT;
coisme 1:bc877c37027c 85 } else {
coisme 1:bc877c37027c 86 config->sampleSetting = SAMPLE_15HZ_16BIT;
coisme 1:bc877c37027c 87 }
coisme 1:bc877c37027c 88
coisme 1:bc877c37027c 89 // Decodes PGA Gain Selection Bits
coisme 1:bc877c37027c 90 tmp = (0x03 & regVal);
coisme 1:bc877c37027c 91 if (tmp == 0x00) {
coisme 1:bc877c37027c 92 config->pgaSetting = PGA_1X;
coisme 1:bc877c37027c 93 } else if (tmp == 0x01) {
coisme 1:bc877c37027c 94 config->pgaSetting = PGA_2X;
coisme 1:bc877c37027c 95 } else if (tmp == 0x02) {
coisme 1:bc877c37027c 96 config->pgaSetting = PGA_4X;
coisme 1:bc877c37027c 97 } else {
coisme 1:bc877c37027c 98 config->pgaSetting = PGA_8X;
coisme 1:bc877c37027c 99 }
coisme 1:bc877c37027c 100 }
coisme 1:bc877c37027c 101
coisme 1:bc877c37027c 102 MCP342X::Status MCP342X::setConfig(const Config *config) {
coisme 1:bc877c37027c 103 char val = 0;
coisme 1:bc877c37027c 104
coisme 1:bc877c37027c 105 // Measurement trigger
coisme 1:bc877c37027c 106 if (config->measurementTrigger == TRIGGER) {
coisme 1:bc877c37027c 107 val |= 0x80;
coisme 1:bc877c37027c 108 } else {
coisme 1:bc877c37027c 109 val |= 0x00;
coisme 1:bc877c37027c 110 }
coisme 1:bc877c37027c 111
coisme 1:bc877c37027c 112 // Channel Selection
coisme 1:bc877c37027c 113 if (config->adcChannel == ADC_CH1) {
coisme 1:bc877c37027c 114 val |= 0x00;
coisme 1:bc877c37027c 115 } else if (config->adcChannel == ADC_CH2) {
coisme 1:bc877c37027c 116 val |= 0x20;
coisme 1:bc877c37027c 117 } else if (config->adcChannel == ADC_CH3) {
coisme 1:bc877c37027c 118 val |= 0x40;
coisme 1:bc877c37027c 119 } else { // config->adcChannel == ADC_CH4
coisme 1:bc877c37027c 120 val |= 0x60;
coisme 1:bc877c37027c 121 }
coisme 1:bc877c37027c 122
coisme 1:bc877c37027c 123 // Conversion Mode
coisme 1:bc877c37027c 124 if (config->conversionMode == CONTINUOUS) {
coisme 1:bc877c37027c 125 val |= 0x10;
coisme 1:bc877c37027c 126 } else if (config->conversionMode == ONE_SHOT) {
coisme 1:bc877c37027c 127 val |= 0x00;
coisme 1:bc877c37027c 128 }
coisme 1:bc877c37027c 129
coisme 1:bc877c37027c 130 // Sample Rate
coisme 1:bc877c37027c 131 if (config->sampleSetting == SAMPLE_240HZ_12BIT) {
coisme 1:bc877c37027c 132 val |= 0x00;
coisme 1:bc877c37027c 133 } else if (config->sampleSetting == SAMPLE_60HZ_14BIT) {
coisme 1:bc877c37027c 134 val |= 0x04;
coisme 1:bc877c37027c 135 } else { //config->sampleSetting == SAMPLE_15HZ_16BIT
coisme 1:bc877c37027c 136 val |= 0x08;
coisme 1:bc877c37027c 137 }
coisme 1:bc877c37027c 138
coisme 1:bc877c37027c 139 // PGA Gain Selection
coisme 1:bc877c37027c 140 if (config->pgaSetting == PGA_1X) {
coisme 1:bc877c37027c 141 val |= 0x00;
coisme 1:bc877c37027c 142 } else if (config->pgaSetting == PGA_2X) {
coisme 1:bc877c37027c 143 val |= 0x01;
coisme 1:bc877c37027c 144 } else if (config->pgaSetting == PGA_4X) {
coisme 1:bc877c37027c 145 val |= 0x02;
coisme 1:bc877c37027c 146 } else { // config->pgaSetting == PGA_8X) {
coisme 1:bc877c37027c 147 val |= 0x03;
coisme 1:bc877c37027c 148 }
coisme 1:bc877c37027c 149
coisme 1:bc877c37027c 150 // Write to the device.
coisme 1:bc877c37027c 151 if (connection->write((slaveAddress << 1), &val, LEN_ONE_BYTE) != 0) {
coisme 1:bc877c37027c 152 return ERROR_I2C_WRITE;
coisme 1:bc877c37027c 153 }
coisme 1:bc877c37027c 154
coisme 1:bc877c37027c 155 return SUCCESS;
coisme 1:bc877c37027c 156 }
coisme 1:bc877c37027c 157
coisme 1:bc877c37027c 158
coisme 1:bc877c37027c 159 MCP342X::Status MCP342X::setChannel(AdcChannel ch) {
coisme 1:bc877c37027c 160 currentConfig.adcChannel = ch;
coisme 1:bc877c37027c 161 return setConfig(&currentConfig);
coisme 1:bc877c37027c 162 }
coisme 1:bc877c37027c 163
coisme 1:bc877c37027c 164 MCP342X::AdcChannel MCP342X::getChannel() {
coisme 1:bc877c37027c 165 return currentConfig.adcChannel;
coisme 1:bc877c37027c 166 }
coisme 1:bc877c37027c 167
coisme 1:bc877c37027c 168 MCP342X::Status MCP342X::setConversionMode(ConversionMode mode) {
coisme 1:bc877c37027c 169 currentConfig.conversionMode = mode;
coisme 1:bc877c37027c 170 return setConfig(&currentConfig);
coisme 1:bc877c37027c 171 }
coisme 1:bc877c37027c 172
coisme 1:bc877c37027c 173 MCP342X::ConversionMode MCP342X::getConversionMode() {
coisme 1:bc877c37027c 174 return currentConfig.conversionMode;
coisme 1:bc877c37027c 175 }
coisme 1:bc877c37027c 176
coisme 1:bc877c37027c 177 MCP342X::Status MCP342X::setSampleSetting(SampleSetting s) {
coisme 1:bc877c37027c 178 currentConfig.sampleSetting = s;
coisme 1:bc877c37027c 179 return setConfig(&currentConfig);
coisme 1:bc877c37027c 180 }
coisme 1:bc877c37027c 181
coisme 1:bc877c37027c 182 MCP342X::SampleSetting MCP342X::getSampleSetting() {
coisme 1:bc877c37027c 183 return currentConfig.sampleSetting;
coisme 1:bc877c37027c 184 }
coisme 1:bc877c37027c 185
coisme 1:bc877c37027c 186 MCP342X::Status MCP342X::setPgaSetting(PgaSetting s) {
coisme 1:bc877c37027c 187 currentConfig.pgaSetting = s;
coisme 1:bc877c37027c 188 return setConfig(&currentConfig);
coisme 1:bc877c37027c 189 }
coisme 1:bc877c37027c 190
coisme 1:bc877c37027c 191 MCP342X::PgaSetting MCP342X::getPgaSetting() {
coisme 1:bc877c37027c 192 return currentConfig.pgaSetting;
coisme 1:bc877c37027c 193 }
coisme 1:bc877c37027c 194
coisme 1:bc877c37027c 195 MCP342X::Status MCP342X::getData(Data *pt) {
coisme 1:bc877c37027c 196 Status status;
coisme 1:bc877c37027c 197
coisme 1:bc877c37027c 198 int16_t val = 0;
coisme 1:bc877c37027c 199 if ((status=readData(&val, &currentConfig)) != SUCCESS) {
coisme 1:bc877c37027c 200 return status;
coisme 1:bc877c37027c 201 }
coisme 1:bc877c37027c 202
coisme 1:bc877c37027c 203 pt->st = currentConfig.dataStatus;
coisme 1:bc877c37027c 204 pt->value = val;
coisme 1:bc877c37027c 205
coisme 1:bc877c37027c 206 return status;
coisme 1:bc877c37027c 207 }
coisme 1:bc877c37027c 208
coisme 1:bc877c37027c 209 MCP342X::Status MCP342X::trigger(){
coisme 1:bc877c37027c 210 Status status;
coisme 1:bc877c37027c 211
coisme 1:bc877c37027c 212 currentConfig.measurementTrigger = TRIGGER;
coisme 1:bc877c37027c 213 status = setConfig(&currentConfig);
coisme 1:bc877c37027c 214 currentConfig.measurementTrigger = NONE;
coisme 1:bc877c37027c 215
coisme 1:bc877c37027c 216 return status;
coisme 1:bc877c37027c 217 }