Device driver for AD converters MCP3426, MCP3427, and MCP3428.
mcp342x.cpp@1:bc877c37027c, 2016-04-29 (annotated)
- 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?
User | Revision | Line number | New 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, ¤tConfig)) != 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(¤tConfig); |
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(¤tConfig); |
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(¤tConfig); |
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(¤tConfig); |
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, ¤tConfig)) != 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(¤tConfig); |
coisme | 1:bc877c37027c | 214 | currentConfig.measurementTrigger = NONE; |
coisme | 1:bc877c37027c | 215 | |
coisme | 1:bc877c37027c | 216 | return status; |
coisme | 1:bc877c37027c | 217 | } |