simple CCS811 driver
Dependencies: AMS_ENS210_temp_humid_sensor
Dependents: TBSense2_Sensor_Demo
Fork of AMS_CCS811_gas_sensor by
AMS_CCS811.cpp
00001 00002 #include "AMS_CCS811.h" 00003 #include "AMS_CCS811_fw_2_0_0.h" 00004 #include "mbed_trace.h" 00005 00006 #define TRACE_GROUP "CCS" 00007 00008 AMS_CCS811::AMS_CCS811(I2C * i2c, PinName n_wake_pin) : _n_wake_out(), _addr_out(), _int_data(), _ens210(), _i2c() { 00009 _n_wake_out = new (std::nothrow) DigitalOut(n_wake_pin, 1); 00010 _i2c = i2c; 00011 } 00012 00013 AMS_CCS811::AMS_CCS811(I2C * i2c, PinName n_wake_pin, I2C * ens210_i2c) : _n_wake_out(), _addr_out(), _int_data(), _ens210(), _i2c() { 00014 _n_wake_out = new (std::nothrow) DigitalOut(n_wake_pin, 1); 00015 _i2c = i2c; 00016 ens210_i2c_interface(ens210_i2c); 00017 } 00018 00019 AMS_CCS811::~AMS_CCS811() { 00020 delete _n_wake_out; 00021 delete _addr_out; 00022 delete _int_data; 00023 delete _ens210; 00024 } 00025 00026 bool AMS_CCS811::init() { 00027 00028 bool success = false; 00029 00030 _init_errors(); 00031 _init_fractions(); 00032 set_defaults(); 00033 00034 temp_reading = 0; 00035 humid_reading = 0; 00036 00037 if (_n_wake_out) { 00038 char buffer[2]; 00039 00040 if(i2c_read(HW_ID, buffer, 1) == 1) { 00041 if(buffer[0] != 0x81) { 00042 // not a CCS811 00043 tr_err("Not a CCS: %02x", buffer[0]); 00044 return false; 00045 } 00046 } else { 00047 return false; 00048 } 00049 00050 if(i2c_read(STATUS, buffer, 1) == 1) { 00051 if((buffer[0] & 0x10) == 0) { 00052 // does not have valid FW 00053 flash_firmware(); 00054 } 00055 } else { 00056 return false; 00057 } 00058 00059 if(i2c_read(FW_APP_VERSION, buffer, 2) == 2) { 00060 tr_warn("CCS version %02x %02x", buffer[0], buffer[1]); 00061 if (buffer[0] < CCS_FW_UPGRADE_VERSION) { 00062 tr_warn("Flashing Firmware"); 00063 flash_firmware(); 00064 } 00065 } else { 00066 return false; 00067 } 00068 00069 int fw_mode = firmware_mode(); 00070 00071 if (fw_mode == 1) { 00072 success = write_config(); 00073 enable_ens210(true); 00074 00075 } else if (fw_mode == 0) { // is in boot mode, needs to be loaded into app mode 00076 if (boot_app_start()) // if succesfully writes to app_start, retry init 00077 success = init(); 00078 } 00079 } 00080 00081 return success; 00082 } 00083 00084 bool AMS_CCS811::flash_firmware() { 00085 // kick into bootloader mode 00086 int fw_mode = firmware_mode(); 00087 if (fw_mode == 1) { 00088 const char reset_sequence[] = {0x11, 0xE5, 0x72, 0x8A}; 00089 if(i2c_write(0xFF, (char*)reset_sequence, 4) == 4) { 00090 fw_mode = firmware_mode(); 00091 if(fw_mode == 1) { 00092 tr_err("Couldn't exit app mode"); 00093 return false; 00094 } 00095 } else { 00096 tr_err("Couldn't issue reset command"); 00097 return false; 00098 } 00099 } 00100 00101 // assert nwake 00102 if (_n_wake_out != NULL) { 00103 int write_count; 00104 00105 _n_wake_out->write(0); 00106 wait_ms(100); 00107 00108 // erase current FW 00109 static const char erase_sequence[4] = {0xE7, 0xA7, 0xE6, 0x09}; 00110 write_count = 0; 00111 _i2c->start(); 00112 if(_i2c->write(CCS811_SLAVE_ADDR_W) == 1) { 00113 if(_i2c->write(FW_ERASE) == 1) { 00114 for (size_t i = 0; i < 4; i++) { 00115 if(_i2c->write(erase_sequence[i]) == 1) write_count++; 00116 else new_error(CCS811_LIB_I2CWRITE_ID); 00117 } 00118 } else new_error(CCS811_LIB_REG_ADDR_ID); 00119 } else new_error(CCS811_LIB_SLAVE_W_ID); 00120 _i2c->stop(); 00121 00122 if (write_count != 4) { 00123 _n_wake_out->write(1); 00124 return false; 00125 } 00126 tr_info("CCS FW erased"); 00127 wait_ms(500); 00128 00129 // upload new FW 00130 tr_info("uploading new FW"); 00131 char payload[8]; 00132 for(size_t offset = 0; offset < 5120; offset += 8) { 00133 for(size_t j = 0; j < 8; j++) { 00134 payload[j] = ams_fw_image[offset + j]; 00135 } 00136 00137 write_count = 0; 00138 _i2c->start(); 00139 if(_i2c->write(CCS811_SLAVE_ADDR_W) == 1) { 00140 if(_i2c->write(FW_FLASH) == 1) { 00141 for (size_t j = 0; j < 8; j++) { 00142 if(_i2c->write(payload[j]) == 1) write_count++; 00143 else new_error(CCS811_LIB_I2CWRITE_ID); 00144 } 00145 } else new_error(CCS811_LIB_REG_ADDR_ID); 00146 } else new_error(CCS811_LIB_SLAVE_W_ID); 00147 _i2c->stop(); 00148 00149 wait_ms(50); 00150 00151 if (write_count != 8) { 00152 _n_wake_out->write(1); 00153 tr_err("flash error"); 00154 return false; 00155 } 00156 00157 tr_debug("Flashed byte %d of 5120", offset); 00158 } 00159 tr_info("CCS FW uploaded"); 00160 00161 // verify new FW 00162 write_count = 0; 00163 _i2c->start(); 00164 if(_i2c->write(CCS811_SLAVE_ADDR_W) == 1) { 00165 if(_i2c->write(FW_VERIFY) == 1) { 00166 write_count = 1; 00167 } else new_error(CCS811_LIB_REG_ADDR_ID); 00168 } else new_error(CCS811_LIB_SLAVE_W_ID); 00169 _i2c->stop(); 00170 00171 wait_ms(500); 00172 00173 if (write_count != 1) { 00174 _n_wake_out->write(1); 00175 tr_err("Failed to issue verify"); 00176 return false; 00177 } 00178 00179 char status = 0; 00180 _i2c->start(); 00181 if(_i2c->write(CCS811_SLAVE_ADDR_W) == 1) { 00182 if(_i2c->write(STATUS) == 1) { 00183 _i2c->start(); 00184 if(_i2c->write(CCS811_SLAVE_ADDR_R) == 1) { 00185 status = _i2c->read(0); 00186 } else new_error(CCS811_LIB_SLAVE_R_ID); 00187 } else new_error(CCS811_LIB_REG_ADDR_ID); 00188 } else new_error(CCS811_LIB_SLAVE_W_ID); 00189 _i2c->stop(); 00190 00191 if (status == 0) { 00192 tr_err("Failed update"); 00193 _n_wake_out->write(1); 00194 return false; 00195 } 00196 00197 if ((status & 0x30) != 0x30) { 00198 tr_err("Failed verify"); 00199 _n_wake_out->write(1); 00200 return false; 00201 } 00202 00203 // boot into new FW 00204 tr_info("upgraded"); 00205 _n_wake_out->write(1); 00206 wait_ms(50); 00207 return boot_app_start(); 00208 } else { 00209 tr_err("No nWAKE available"); 00210 return false; 00211 } 00212 } 00213 00214 void AMS_CCS811::i2c_interface(I2C * i2c) { 00215 _i2c = i2c; 00216 } 00217 00218 bool AMS_CCS811::ens210_i2c_interface(I2C * i2c) { 00219 00220 bool success; 00221 00222 if (_ens210 == NULL) { 00223 _ens210 = new (std::nothrow) AMS_ENS210(i2c, true, true); 00224 if (_ens210 != NULL) { 00225 if (_ens210->init()) { 00226 success = _ens210->start(); 00227 } 00228 } 00229 } else { 00230 _ens210->i2c_interface(i2c); 00231 success = true; 00232 } 00233 00234 if (!success) new_error(CCS811_LIB_ENS210_INIT_ID); 00235 00236 return success; 00237 } 00238 00239 bool AMS_CCS811::enable_ens210(bool enable) { 00240 00241 _ens210_enabled = false; 00242 if (_ens210 != NULL) { 00243 if (_ens210->i2c_interface() != NULL) _ens210_enabled = enable; 00244 } 00245 update_ens210_timer(); 00246 return _ens210_enabled; 00247 } 00248 00249 bool AMS_CCS811::ens210_is_enabled() { 00250 enable_ens210(_ens210_enabled); // Make sure the state is representive 00251 return _ens210_enabled; 00252 } 00253 00254 void AMS_CCS811::ens210_poll_interval(int poll_ms) { 00255 _ens210_poll_split = poll_ms; 00256 enable_ens210(_ens210_enabled); // makes sure the state is representive, and will also update the timer 00257 } 00258 00259 int AMS_CCS811::ens210_poll_interval() { 00260 return _ens210_poll_split; 00261 } 00262 00263 int AMS_CCS811::firmware_mode() { 00264 int firmware_result = -1; 00265 00266 clear_errors(); 00267 00268 read_byte_result read_result = read_status(); 00269 if (read_result.success) { 00270 firmware_result = (read_result.byte >> 7) & 1; 00271 } 00272 00273 return firmware_result; 00274 } 00275 00276 bool AMS_CCS811::mode(OP_MODES mode) { 00277 clear_errors(); 00278 00279 OP_MODES old = _mode; // incase the write fails, to roll back 00280 _mode = mode; 00281 00282 bool success = write_config(); 00283 if (!success) 00284 _mode = old; 00285 00286 return success; 00287 } 00288 00289 AMS_CCS811::OP_MODES AMS_CCS811::mode() { 00290 clear_errors(); 00291 00292 OP_MODES result = INVALID; 00293 00294 read_byte_result read_result = read_config(); 00295 if (read_result.success) { 00296 int mode = (read_result.byte >> 4) & 0b111; 00297 result = mode > 4 ? INVALID : (OP_MODES)mode; 00298 } 00299 00300 return result; 00301 } 00302 00303 bool AMS_CCS811::addr_mode(bool high) { 00304 _addr_dir = high; 00305 if (_addr_out != NULL) _addr_out->write(_addr_dir); 00306 00307 update_slave_addr(); 00308 00309 return addr_mode() == high; 00310 } 00311 00312 bool AMS_CCS811::addr_mode() { 00313 _addr_dir = false; 00314 if (_addr_out != NULL) { 00315 _addr_dir = _addr_out->read(); 00316 } 00317 00318 return _addr_dir; 00319 } 00320 00321 bool AMS_CCS811::addr_pin(PinName pin) { 00322 _addr_out = _addr_out == NULL ? new (std::nothrow) DigitalOut(pin) : new (_addr_out) DigitalOut(pin); 00323 addr_mode(_addr_dir); 00324 00325 return _addr_out != NULL; 00326 } 00327 00328 bool AMS_CCS811::n_wake_pin(PinName pin) { 00329 _n_wake_out = _n_wake_out == NULL ? new (std::nothrow) DigitalOut(pin) : new (_n_wake_out) DigitalOut(pin); 00330 return _n_wake_out != NULL; 00331 } 00332 00333 bool AMS_CCS811::env_data(float humid, float temp) { 00334 char bytes[4]; 00335 if (humid > CCS811_MAX_HUMID) humid = CCS811_MAX_HUMID; 00336 if (humid < 0) humid = 0; 00337 00338 temp += 25; 00339 if (temp > CCS811_MAX_TEMP) humid = CCS811_MAX_TEMP; 00340 if (temp < 0) temp = 0; 00341 00342 float_to_short(humid, bytes); 00343 float_to_short(temp, bytes+2); 00344 00345 return i2c_write(ENV_DATA, bytes, 4) == 4; 00346 } 00347 00348 00349 int AMS_CCS811::has_new_data() { 00350 00351 clear_errors(); 00352 00353 int result = -1; 00354 00355 char meas_mode[1]; 00356 if(i2c_read(MEAS_MODE, meas_mode, 1) == 1) { // one read here is quicker than calling read_config() twice 00357 00358 int curr_mode = (meas_mode[0] >> 4) & 0b111; 00359 if (curr_mode < 5) { 00360 if (curr_mode > 0) { // check for all valid modes other than idle 00361 if (((meas_mode[0] >> 3) & 1) == 0) { // check if interrupts are disabled 00362 char status[1]; 00363 if (i2c_read(STATUS, status, 1) == 1) // for some reason the status register in ALG_RESULT_DATA is not updated after reading data, however the STATUS register is 00364 result = (status[0] >> 3) & 1; 00365 00366 } else result = 1; 00367 00368 if (result == 1) 00369 if (i2c_read(ALG_RESULT_DATA, _alg_result_data, 8) != 8) result = -1; 00370 00371 00372 } else result = 0; // return 0 when in idle 00373 } else new_error(CCS811_LIB_INV_MODE_ID); 00374 } 00375 00376 return result; 00377 } 00378 00379 uint16_t AMS_CCS811::co2_read() { 00380 return 0 | (_alg_result_data[0] << 8) | _alg_result_data[1]; 00381 } 00382 00383 uint16_t AMS_CCS811::tvoc_read() { 00384 return 0 | (_alg_result_data[2] << 8) | _alg_result_data[3]; 00385 } 00386 00387 uint16_t AMS_CCS811::raw_read() { 00388 return 0 | (_alg_result_data[6] << 8) | _alg_result_data[7]; 00389 } 00390 00391 float AMS_CCS811::temp_read() { 00392 return temp_reading; 00393 } 00394 00395 float AMS_CCS811::humid_read() { 00396 return humid_reading; 00397 } 00398 00399 bool AMS_CCS811::error_status() { 00400 bool result = false; 00401 00402 read_byte_result read_result = read_status(); 00403 if (read_result.success) { 00404 result = read_result.byte & 1; 00405 } 00406 00407 result = result || (_error_count > 0); 00408 00409 return result; 00410 } 00411 00412 AMS_CCS811::ccs811_errors AMS_CCS811::errors() { 00413 ccs811_errors error_result; 00414 00415 char byte[1]; 00416 if (i2c_read(ERROR_ID, byte, 1) == 1) { 00417 for(int i = 0; i < CCS811_ERR_NUM; i++) { 00418 if ((byte[0] << i) & 1) { 00419 error_result.codes[error_result.count++] = i; 00420 } 00421 } 00422 } 00423 for(int i = 0; i < CCS811_LIB_ERR_NUM; i++) { 00424 if (_errors[i]) { 00425 error_result.codes[error_result.count++] = i + CCS811_ERR_NUM; 00426 } 00427 } 00428 00429 return error_result; 00430 00431 } 00432 00433 const char * AMS_CCS811::error_string(int err_code){ 00434 static char result[255]; 00435 result[0] = 0; 00436 if (err_code < CCS811_TOTAL_ERR_NUM && err_code > -1) 00437 strcpy(result, _error_strings[err_code]); 00438 else 00439 sprintf(result, "Invalid Code: %d is out of range (0 - %d)", err_code, CCS811_TOTAL_ERR_NUM-1); 00440 00441 return result; 00442 } 00443 00444 bool AMS_CCS811::enable_interupt(bool enable) { 00445 bool old = _int_data_enabled; // incase the write fails, to roll back 00446 _int_data_enabled = enable; 00447 00448 bool success = write_config(); 00449 if (!success) 00450 _int_data_enabled = old; 00451 00452 return success; 00453 00454 } 00455 00456 int AMS_CCS811::interupt_enabled() { 00457 int enabled = -1; 00458 00459 read_byte_result read_result = read_config(); 00460 if (read_result.success) { 00461 enabled = (read_result.byte >> 3) & 1; 00462 } 00463 00464 return enabled; 00465 } 00466 00467 bool AMS_CCS811::interrupt_pin(PinName pin) { 00468 bool success = false; 00469 00470 _int_data = _int_data == NULL ? new (std::nothrow) InterruptIn(pin) : new (_int_data) InterruptIn(pin); 00471 if (_int_data != NULL) { 00472 _int_data->fall(callback(this, &AMS_CCS811::_isr_data)); 00473 success = true; 00474 } 00475 00476 return success; 00477 } 00478 00479 00480 00481 00482 /** Private **/ 00483 00484 void AMS_CCS811::set_defaults() { 00485 if (_mode == NULL) 00486 _mode = CONFIG_OP_MODE; 00487 if (_addr_dir == NULL) 00488 _addr_dir = CONFIG_ADDR_DIR; 00489 if (_int_data_enabled == NULL) 00490 _int_data_enabled = CONFIG_INTR; 00491 if (_ens210_poll_split == NULL) 00492 _ens210_poll_split = CONFIG_ENS210_POLL; 00493 00494 update_slave_addr(); 00495 } 00496 00497 void AMS_CCS811::_init_errors() { 00498 clear_errors(); 00499 /* Sensor errors */ 00500 strcpy(_error_strings[0], CCS811_WRITE_REG_INVALID); 00501 strcpy(_error_strings[1], CCS811_READ_REG_INVALID); 00502 strcpy(_error_strings[2], CCS811_MEASMODE_INVALID); 00503 strcpy(_error_strings[3], CCS811_MAX_RESISTANCE); 00504 strcpy(_error_strings[4], CCS811_HEATER_FAULT); 00505 strcpy(_error_strings[5], CCS811_HEATER_SUPPLY); 00506 strcpy(_error_strings[6], CCS811_RESERVED); 00507 strcpy(_error_strings[7], CCS811_RESERVED); 00508 /* Library errors */ 00509 strcpy(_error_strings[CCS811_LIB_N_WAKE_ID+CCS811_ERR_NUM], CCS811_LIB_N_WAKE); 00510 strcpy(_error_strings[CCS811_LIB_I2C_ID+CCS811_ERR_NUM], CCS811_LIB_I2C); 00511 strcpy(_error_strings[CCS811_LIB_SLAVE_W_ID+CCS811_ERR_NUM], CCS811_LIB_SLAVE_W); 00512 strcpy(_error_strings[CCS811_LIB_REG_ADDR_ID+CCS811_ERR_NUM], CCS811_LIB_REG_ADDR); 00513 strcpy(_error_strings[CCS811_LIB_I2CWRITE_ID+CCS811_ERR_NUM], CCS811_LIB_I2CWRITE); 00514 strcpy(_error_strings[CCS811_LIB_SLAVE_R_ID+CCS811_ERR_NUM], CCS811_LIB_SLAVE_R); 00515 strcpy(_error_strings[CCS811_LIB_INV_MODE_ID+CCS811_ERR_NUM], CCS811_LIB_INV_MODE); 00516 strcpy(_error_strings[CCS811_LIB_ENS210_INIT_ID+CCS811_ERR_NUM], CCS811_LIB_ENS210_INIT); 00517 } 00518 00519 void AMS_CCS811::clear_errors() { 00520 _error_count = 0; 00521 for (int i = 0; i < CCS811_LIB_ERR_NUM; i++) { 00522 _errors[i] = false; 00523 } 00524 } 00525 00526 void AMS_CCS811::new_error(int error_id) { 00527 if (!_errors[error_id]) { 00528 _errors[error_id] = true; 00529 _error_count++; 00530 } 00531 } 00532 00533 void AMS_CCS811::update_ens210_timer() { 00534 _ens210_poll_t.detach(); 00535 if (_ens210_enabled) 00536 _ens210_poll_t.attach_us(callback(this, &AMS_CCS811::ens210_isr), _ens210_poll_split*1000); 00537 } 00538 00539 void AMS_CCS811::ens210_isr() { 00540 temp_reading = ((float)_ens210->temp_read() / 64) - - 273.15; 00541 humid_reading = (float)_ens210->humid_read()/512; 00542 env_data(humid_reading, temp_reading); 00543 } 00544 00545 void AMS_CCS811::_init_fractions() { 00546 00547 fractions[0] = 0.5; 00548 fractions[1] = 0.25; 00549 fractions[2] = 0.125; 00550 fractions[3] = 0.0625; 00551 fractions[4] = 0.03125; 00552 fractions[5] = 0.015625; 00553 fractions[6] = 0.0078125; 00554 fractions[7] = 0.00390625; 00555 fractions[8] = 0.001953125; 00556 00557 } 00558 00559 void AMS_CCS811::float_to_short(float in, char * output) { 00560 00561 uint8_t int_part = (uint8_t)in; 00562 float dec_part = in - int_part; 00563 00564 uint16_t _short = 0; 00565 for (int i = 0; i < 9; i++) { 00566 if (dec_part == 0) break; 00567 if (dec_part >= fractions[i]) { 00568 dec_part -= fractions[i]; 00569 _short |= 256 >> i; 00570 } 00571 } 00572 00573 _short |= int_part << 9; 00574 00575 output[0] = _short >> 8; 00576 output[1] = _short; 00577 } 00578 00579 void AMS_CCS811::update_slave_addr() { 00580 _slave_addr = addr_mode() ? CCS811_SLAVE_ADDR_RAW_H : CCS811_SLAVE_ADDR_RAW_L; 00581 } 00582 00583 void AMS_CCS811::_isr_data() { 00584 has_new_data(); // populate the data array 00585 _isr_data_fp.call(); 00586 } 00587 00588 bool AMS_CCS811::write_config() { 00589 char cmd[1] = {0 | (_int_data_enabled ? 1 << 3 : 0) | (_mode << 4)}; 00590 return i2c_write(MEAS_MODE, cmd, 1) == 1; 00591 } 00592 00593 AMS_CCS811::read_byte_result AMS_CCS811::read_config() { 00594 read_byte_result result; 00595 char byte[1]; 00596 if (i2c_read(MEAS_MODE, byte, 1) == 1) { 00597 result.success = true; 00598 result.byte = byte[0]; 00599 } 00600 return result; 00601 } 00602 00603 AMS_CCS811::read_byte_result AMS_CCS811::read_status() { 00604 read_byte_result result; 00605 char byte[1]; 00606 if (i2c_read(STATUS, byte, 1) == 1) { 00607 result.success = true; 00608 result.byte = byte[0]; 00609 } 00610 00611 return result; 00612 } 00613 00614 bool AMS_CCS811::boot_app_start() { 00615 bool success = false; 00616 00617 if (i2c_write(APP_START, NULL, 0) == 0) { 00618 wait_ms(70); 00619 success = true; 00620 } 00621 00622 return success; 00623 } 00624 00625 int AMS_CCS811::i2c_read(char reg_addr, char* output, int len) { 00626 00627 int read_count = 0; 00628 if (_n_wake_out != NULL) { // check nWAKE pin is set 00629 _n_wake_out->write(0); // Hold low 00630 wait_us(CCS811_T_AWAKE); // tAWAKE time to allow sensor I2C to wake up 00631 if (_i2c != NULL) { // check I2C interface is set 00632 _i2c->start(); // send start condition for write 00633 if(_i2c->write(CCS811_SLAVE_ADDR_W) == 1) { // write slave address with write bit 00634 if(_i2c->write(reg_addr) == 1) { // write register address 00635 _i2c->start(); // send another start condition for read 00636 if(_i2c->write(CCS811_SLAVE_ADDR_R) == 1) { // write slave address with read bit 00637 for (int i = 0; i < len; i++) { // read len bytes 00638 output[i] = _i2c->read(i < len-1 ? 1 : 0); // ack all reads aside from the final one (i == len-1) 00639 read_count++; 00640 } 00641 } else new_error(CCS811_LIB_SLAVE_R_ID); 00642 } else new_error(CCS811_LIB_REG_ADDR_ID); 00643 } else new_error(CCS811_LIB_SLAVE_W_ID); 00644 _i2c->stop(); // send stop condition 00645 } else new_error(CCS811_LIB_I2C_ID); 00646 _n_wake_out->write(1); // Set back to high 00647 wait_us(CCS811_T_DWAKE); // tDWAKE time to allow sensor I2C to sleep 00648 } else new_error(CCS811_LIB_N_WAKE_ID); 00649 00650 return read_count; 00651 } 00652 00653 int AMS_CCS811::i2c_write(char reg_addr, char* input, int len) { 00654 00655 int write_count = -1; 00656 if (_n_wake_out != NULL) { // check nWAKE pin is set 00657 _n_wake_out->write(0); // Hold low 00658 wait_us(CCS811_T_AWAKE); // tAWAKE time to allow sensor I2C to wake up 00659 if (_i2c != NULL) { // check I2C interface is set 00660 _i2c->start(); // send start condition for write 00661 if(_i2c->write(CCS811_SLAVE_ADDR_W) == 1) { // write slave address 00662 if(_i2c->write(reg_addr) == 1) { // write register address 00663 write_count = 0; 00664 for (int i = 0; i < len; i++) { // write len bytes 00665 if(_i2c->write(input[i]) == 1) write_count++; // write each byte, if successful increment count 00666 else new_error(CCS811_LIB_I2CWRITE_ID); 00667 } 00668 } else new_error(CCS811_LIB_REG_ADDR_ID); 00669 } else new_error(CCS811_LIB_SLAVE_W_ID); 00670 _i2c->stop(); // send stop condition 00671 } else new_error(CCS811_LIB_I2C_ID); 00672 _n_wake_out->write(1); // set back to high 00673 wait_us(CCS811_T_DWAKE); // tDWAKE time to allow sensor I2C to sleep 00674 }else new_error(CCS811_LIB_N_WAKE_ID); 00675 00676 return write_count; 00677 }
Generated on Thu Jul 14 2022 16:17:55 by 1.7.2