Library for the AMS CC811 digitial gas sensor

Dependencies:   AMS_ENS210_temp_humid_sensor

Committer:
UHSLMarcus
Date:
Thu Jan 19 13:25:08 2017 +0000
Revision:
3:782a719f47a5
Parent:
2:e394671ef5f6
Child:
4:a6b8881eae87
almost all simple implimentations done

Who changed what in which revision?

UserRevisionLine numberNew contents of line
UHSLMarcus 0:5edbf3550350 1
UHSLMarcus 2:e394671ef5f6 2 #include "AMS_CCS811.h"
UHSLMarcus 0:5edbf3550350 3
UHSLMarcus 0:5edbf3550350 4
UHSLMarcus 0:5edbf3550350 5 AMS_CCS811::AMS_CCS811(I2C * i2c, PinName n_wake_pin) {
UHSLMarcus 1:acfca1d3256d 6 _n_wake_out = new (std::nothrow) DigitalOut(n_wake_pin);
UHSLMarcus 0:5edbf3550350 7 _i2c = i2c;
UHSLMarcus 0:5edbf3550350 8
UHSLMarcus 0:5edbf3550350 9 set_defaults();
UHSLMarcus 0:5edbf3550350 10 }
UHSLMarcus 0:5edbf3550350 11
UHSLMarcus 0:5edbf3550350 12 AMS_CCS811::AMS_CCS811(I2C * i2c, PinName n_wake_pin, I2C * ens210_i2c) {
UHSLMarcus 1:acfca1d3256d 13 _n_wake_out = new (std::nothrow) DigitalOut(n_wake_pin);
UHSLMarcus 0:5edbf3550350 14 _i2c = i2c;
UHSLMarcus 0:5edbf3550350 15 _ens210_i2c = ens210_i2c;
UHSLMarcus 0:5edbf3550350 16
UHSLMarcus 0:5edbf3550350 17 set_defaults();
UHSLMarcus 0:5edbf3550350 18
UHSLMarcus 0:5edbf3550350 19 }
UHSLMarcus 0:5edbf3550350 20
UHSLMarcus 1:acfca1d3256d 21 AMS_CCS811::~AMS_CCS811() {
UHSLMarcus 1:acfca1d3256d 22 delete _n_wake_out;
UHSLMarcus 1:acfca1d3256d 23 delete _addr_out;
UHSLMarcus 1:acfca1d3256d 24 delete _int_data;
UHSLMarcus 1:acfca1d3256d 25 }
UHSLMarcus 1:acfca1d3256d 26
UHSLMarcus 1:acfca1d3256d 27 bool AMS_CCS811::init() {
UHSLMarcus 3:782a719f47a5 28 return true;
UHSLMarcus 1:acfca1d3256d 29 }
UHSLMarcus 1:acfca1d3256d 30
UHSLMarcus 1:acfca1d3256d 31 bool AMS_CCS811::mode(OP_MODES mode) {
UHSLMarcus 1:acfca1d3256d 32 OP_MODES old = _mode; // incase the write fails, to roll back
UHSLMarcus 1:acfca1d3256d 33 _mode = mode;
UHSLMarcus 1:acfca1d3256d 34
UHSLMarcus 1:acfca1d3256d 35 bool success = write_config();
UHSLMarcus 1:acfca1d3256d 36 if (!success)
UHSLMarcus 1:acfca1d3256d 37 _mode = old;
UHSLMarcus 1:acfca1d3256d 38
UHSLMarcus 1:acfca1d3256d 39 return success;
UHSLMarcus 1:acfca1d3256d 40 }
UHSLMarcus 1:acfca1d3256d 41
UHSLMarcus 1:acfca1d3256d 42 AMS_CCS811::OP_MODES AMS_CCS811::mode() {
UHSLMarcus 1:acfca1d3256d 43 OP_MODES result = _mode; // rather not rely on this, but just incase the read fails
UHSLMarcus 1:acfca1d3256d 44
UHSLMarcus 1:acfca1d3256d 45 read_config_result read_result = read_config();
UHSLMarcus 1:acfca1d3256d 46 if (read_result.success) {
UHSLMarcus 1:acfca1d3256d 47 int mode = (read_result.byte >> 4) & 0b111;
UHSLMarcus 2:e394671ef5f6 48 result = mode > 4 ? INVALID : (OP_MODES)mode;
UHSLMarcus 1:acfca1d3256d 49 } // todo ... add a new "last error" here
UHSLMarcus 1:acfca1d3256d 50
UHSLMarcus 2:e394671ef5f6 51 return result;
UHSLMarcus 1:acfca1d3256d 52 }
UHSLMarcus 1:acfca1d3256d 53
UHSLMarcus 1:acfca1d3256d 54 bool AMS_CCS811::addr_mode(bool high) {
UHSLMarcus 1:acfca1d3256d 55 _addr_dir = high;
UHSLMarcus 1:acfca1d3256d 56 if (_addr_out != NULL) *_addr_out = _addr_dir;
UHSLMarcus 1:acfca1d3256d 57
UHSLMarcus 2:e394671ef5f6 58 update_slave_addr();
UHSLMarcus 2:e394671ef5f6 59
UHSLMarcus 1:acfca1d3256d 60 return addr_mode() == high;
UHSLMarcus 1:acfca1d3256d 61 }
UHSLMarcus 1:acfca1d3256d 62
UHSLMarcus 1:acfca1d3256d 63 bool AMS_CCS811::addr_mode() {
UHSLMarcus 1:acfca1d3256d 64 if (_addr_out != NULL) {
UHSLMarcus 1:acfca1d3256d 65 _addr_dir = *_addr_out;
UHSLMarcus 1:acfca1d3256d 66 }
UHSLMarcus 1:acfca1d3256d 67
UHSLMarcus 1:acfca1d3256d 68 return _addr_dir;
UHSLMarcus 1:acfca1d3256d 69 }
UHSLMarcus 1:acfca1d3256d 70
UHSLMarcus 1:acfca1d3256d 71 bool AMS_CCS811::addr_pin(PinName pin) {
UHSLMarcus 1:acfca1d3256d 72 _addr_out = _addr_out == NULL ? new (std::nothrow) DigitalOut(pin) : new (_addr_out) DigitalOut(pin);
UHSLMarcus 1:acfca1d3256d 73 addr_mode(_addr_dir);
UHSLMarcus 1:acfca1d3256d 74
UHSLMarcus 1:acfca1d3256d 75 return _addr_out != NULL;
UHSLMarcus 1:acfca1d3256d 76 }
UHSLMarcus 1:acfca1d3256d 77
UHSLMarcus 1:acfca1d3256d 78 bool AMS_CCS811::n_wake_pin(PinName pin) {
UHSLMarcus 1:acfca1d3256d 79 _n_wake_out = _n_wake_out == NULL ? new (std::nothrow) DigitalOut(pin) : new (_n_wake_out) DigitalOut(pin);
UHSLMarcus 1:acfca1d3256d 80 return _n_wake_out != NULL;
UHSLMarcus 1:acfca1d3256d 81 }
UHSLMarcus 1:acfca1d3256d 82
UHSLMarcus 2:e394671ef5f6 83 bool AMS_CCS811::env_data(float humid, float temp) {
UHSLMarcus 1:acfca1d3256d 84 return true;
UHSLMarcus 1:acfca1d3256d 85 }
UHSLMarcus 1:acfca1d3256d 86
UHSLMarcus 1:acfca1d3256d 87
UHSLMarcus 1:acfca1d3256d 88 AMS_CCS811::DATA_STATUS AMS_CCS811::has_new_data() {
UHSLMarcus 1:acfca1d3256d 89 return (DATA_STATUS) 0;
UHSLMarcus 1:acfca1d3256d 90 }
UHSLMarcus 1:acfca1d3256d 91
UHSLMarcus 1:acfca1d3256d 92 uint16_t AMS_CCS811::co2_read() {
UHSLMarcus 1:acfca1d3256d 93 return 0;
UHSLMarcus 2:e394671ef5f6 94 }
UHSLMarcus 1:acfca1d3256d 95
UHSLMarcus 1:acfca1d3256d 96 uint16_t AMS_CCS811::tvoc_read() {
UHSLMarcus 1:acfca1d3256d 97 return 0;
UHSLMarcus 1:acfca1d3256d 98 }
UHSLMarcus 1:acfca1d3256d 99
UHSLMarcus 1:acfca1d3256d 100 uint16_t AMS_CCS811::raw_read() {
UHSLMarcus 1:acfca1d3256d 101 return 0;
UHSLMarcus 1:acfca1d3256d 102 }
UHSLMarcus 1:acfca1d3256d 103
UHSLMarcus 1:acfca1d3256d 104 const char * AMS_CCS811::last_error() {
UHSLMarcus 1:acfca1d3256d 105 return "";
UHSLMarcus 1:acfca1d3256d 106 }
UHSLMarcus 1:acfca1d3256d 107
UHSLMarcus 1:acfca1d3256d 108 bool AMS_CCS811::enable_interupt(bool enable) {
UHSLMarcus 1:acfca1d3256d 109 bool old = _int_data_enabled; // incase the write fails, to roll back
UHSLMarcus 1:acfca1d3256d 110 _int_data_enabled = enable;
UHSLMarcus 1:acfca1d3256d 111
UHSLMarcus 1:acfca1d3256d 112 bool success = write_config();
UHSLMarcus 1:acfca1d3256d 113 if (!success)
UHSLMarcus 1:acfca1d3256d 114 _int_data_enabled = old;
UHSLMarcus 1:acfca1d3256d 115
UHSLMarcus 1:acfca1d3256d 116 return success;
UHSLMarcus 1:acfca1d3256d 117
UHSLMarcus 1:acfca1d3256d 118 }
UHSLMarcus 1:acfca1d3256d 119
UHSLMarcus 1:acfca1d3256d 120 bool AMS_CCS811::interupt_enabled() {
UHSLMarcus 1:acfca1d3256d 121 bool enabled = _int_data_enabled; // rather not rely on this, but just incase the read fails
UHSLMarcus 1:acfca1d3256d 122
UHSLMarcus 1:acfca1d3256d 123 read_config_result read_result = read_config();
UHSLMarcus 1:acfca1d3256d 124 if (read_result.success) {
UHSLMarcus 1:acfca1d3256d 125 enabled = (read_result.byte >> 3) & 1;
UHSLMarcus 1:acfca1d3256d 126 } // todo ... add a new "last error" here? or maybe the read method itself should set that.
UHSLMarcus 1:acfca1d3256d 127
UHSLMarcus 2:e394671ef5f6 128 return enabled;
UHSLMarcus 1:acfca1d3256d 129 }
UHSLMarcus 1:acfca1d3256d 130
UHSLMarcus 1:acfca1d3256d 131 bool AMS_CCS811::interrupt_pin(PinName pin) {
UHSLMarcus 1:acfca1d3256d 132 bool success = false;
UHSLMarcus 1:acfca1d3256d 133
UHSLMarcus 2:e394671ef5f6 134 _int_data = _int_data == NULL ? new (std::nothrow) InterruptIn(pin) : new (_int_data) InterruptIn(pin);
UHSLMarcus 1:acfca1d3256d 135 if (_int_data != NULL) {
UHSLMarcus 2:e394671ef5f6 136 _int_data->fall(callback(this, &AMS_CCS811::_isr_data));
UHSLMarcus 1:acfca1d3256d 137 success = true;
UHSLMarcus 1:acfca1d3256d 138 }
UHSLMarcus 1:acfca1d3256d 139
UHSLMarcus 1:acfca1d3256d 140 return success;
UHSLMarcus 1:acfca1d3256d 141 }
UHSLMarcus 0:5edbf3550350 142
UHSLMarcus 0:5edbf3550350 143
UHSLMarcus 0:5edbf3550350 144
UHSLMarcus 1:acfca1d3256d 145
UHSLMarcus 1:acfca1d3256d 146 /** Private **/
UHSLMarcus 1:acfca1d3256d 147
UHSLMarcus 1:acfca1d3256d 148 bool AMS_CCS811::set_defaults() {
UHSLMarcus 1:acfca1d3256d 149 if (_mode == NULL)
UHSLMarcus 1:acfca1d3256d 150 _mode = CONFIG_OP_MODE;
UHSLMarcus 1:acfca1d3256d 151 if (_addr_dir == NULL)
UHSLMarcus 1:acfca1d3256d 152 _addr_dir = CONFIG_ADDR_DIR;
UHSLMarcus 1:acfca1d3256d 153 if (_int_data_enabled == NULL)
UHSLMarcus 1:acfca1d3256d 154 _int_data_enabled = CONFIG_INTR;
UHSLMarcus 2:e394671ef5f6 155 if (_ens210_poll_split == NULL)
UHSLMarcus 2:e394671ef5f6 156 _ens210_poll_split = CONFIG_ENS210_POLL;
UHSLMarcus 2:e394671ef5f6 157
UHSLMarcus 2:e394671ef5f6 158 update_slave_addr();
UHSLMarcus 1:acfca1d3256d 159
UHSLMarcus 1:acfca1d3256d 160 return write_config();
UHSLMarcus 1:acfca1d3256d 161 }
UHSLMarcus 2:e394671ef5f6 162
UHSLMarcus 3:782a719f47a5 163 void AMS_CCS811::update_slave_addr() {
UHSLMarcus 2:e394671ef5f6 164 slave_addr = addr_mode() ? SLAVE_ADDR_RAW_H : SLAVE_ADDR_RAW_L;
UHSLMarcus 2:e394671ef5f6 165 }
UHSLMarcus 1:acfca1d3256d 166
UHSLMarcus 1:acfca1d3256d 167 void AMS_CCS811::_isr_data() {
UHSLMarcus 3:782a719f47a5 168 _isr_data_fp.call();
UHSLMarcus 1:acfca1d3256d 169 }
UHSLMarcus 1:acfca1d3256d 170
UHSLMarcus 1:acfca1d3256d 171 bool AMS_CCS811::write_config() {
UHSLMarcus 3:782a719f47a5 172 char cmd[1] = {0 | (_int_data_enabled << 3) | (_mode << 4)};
UHSLMarcus 2:e394671ef5f6 173 return i2c_write(SYS_MODE, cmd, 1) == 1;
UHSLMarcus 1:acfca1d3256d 174 }
UHSLMarcus 1:acfca1d3256d 175
UHSLMarcus 3:782a719f47a5 176 AMS_CCS811::read_config_result AMS_CCS811::read_config() {
UHSLMarcus 2:e394671ef5f6 177 read_config_result result;
UHSLMarcus 2:e394671ef5f6 178 char byte[1];
UHSLMarcus 2:e394671ef5f6 179 if (i2c_read(SYS_MODE, byte, 1) == 1) {
UHSLMarcus 2:e394671ef5f6 180 result.success = true;
UHSLMarcus 2:e394671ef5f6 181 result.byte = byte[1];
UHSLMarcus 2:e394671ef5f6 182 }
UHSLMarcus 2:e394671ef5f6 183
UHSLMarcus 2:e394671ef5f6 184 return result;
UHSLMarcus 2:e394671ef5f6 185 }
UHSLMarcus 2:e394671ef5f6 186
UHSLMarcus 2:e394671ef5f6 187 int AMS_CCS811::i2c_read(char reg_addr, char* output, int len) {
UHSLMarcus 2:e394671ef5f6 188
UHSLMarcus 2:e394671ef5f6 189 int read_count = 0;
UHSLMarcus 2:e394671ef5f6 190 if (_n_wake_out != NULL) { // check nWAKE pin is set
UHSLMarcus 2:e394671ef5f6 191 if (_i2c != NULL) { // check I2C interface is set
UHSLMarcus 2:e394671ef5f6 192 _i2c->start(); // send start condition for write
UHSLMarcus 2:e394671ef5f6 193 if(_i2c->write(SLAVE_ADDR_W) == 1) { // write slave address with write bit
UHSLMarcus 2:e394671ef5f6 194 if(_i2c->write(reg_addr) == 1) { // write register address
UHSLMarcus 2:e394671ef5f6 195 _i2c->start(); // send another start condition for read
UHSLMarcus 2:e394671ef5f6 196 if(_i2c->write(SLAVE_ADDR_R) == 1) { // write slave address with read bit
UHSLMarcus 2:e394671ef5f6 197 for (int i = 0; i < len; i++) { // read len bytes
UHSLMarcus 2:e394671ef5f6 198 output[i] = _i2c->read(i < len-1 ? 1 : 0); // ack all reads aside from the final one (i == len-1)
UHSLMarcus 2:e394671ef5f6 199 read_count++;
UHSLMarcus 2:e394671ef5f6 200 }
UHSLMarcus 2:e394671ef5f6 201 }
UHSLMarcus 2:e394671ef5f6 202 }
UHSLMarcus 2:e394671ef5f6 203 }
UHSLMarcus 2:e394671ef5f6 204 _i2c->stop(); // send stop condition
UHSLMarcus 2:e394671ef5f6 205 }
UHSLMarcus 2:e394671ef5f6 206 }
UHSLMarcus 2:e394671ef5f6 207
UHSLMarcus 2:e394671ef5f6 208 return read_count;
UHSLMarcus 2:e394671ef5f6 209 }
UHSLMarcus 2:e394671ef5f6 210
UHSLMarcus 2:e394671ef5f6 211 int AMS_CCS811::i2c_write(char reg_addr, char* input, int len) { // to do... error reporting
UHSLMarcus 2:e394671ef5f6 212
UHSLMarcus 2:e394671ef5f6 213 int write_count = 0;
UHSLMarcus 2:e394671ef5f6 214 if (_n_wake_out != NULL) { // check nWAKE pin is set
UHSLMarcus 2:e394671ef5f6 215 if (_i2c != NULL) { // check I2C interface is set
UHSLMarcus 2:e394671ef5f6 216 _i2c->start(); // send start condition for write
UHSLMarcus 2:e394671ef5f6 217 if(_i2c->write(SLAVE_ADDR_W) == 1) { // write slave address
UHSLMarcus 2:e394671ef5f6 218 if(_i2c->write(reg_addr) == 1) { // write register address
UHSLMarcus 2:e394671ef5f6 219 for (int i = 0; i < len; i++) { // write len bytes
UHSLMarcus 2:e394671ef5f6 220 if(_i2c->write(input[i]) == 1) write_count++; // write each byte, if successful increment count
UHSLMarcus 2:e394671ef5f6 221 }
UHSLMarcus 2:e394671ef5f6 222 }
UHSLMarcus 2:e394671ef5f6 223 }
UHSLMarcus 2:e394671ef5f6 224 _i2c->stop(); // send stop condition
UHSLMarcus 2:e394671ef5f6 225 }
UHSLMarcus 2:e394671ef5f6 226 }
UHSLMarcus 2:e394671ef5f6 227
UHSLMarcus 2:e394671ef5f6 228 return write_count;
UHSLMarcus 1:acfca1d3256d 229 }