668 lines
16 KiB
C++
Executable File
668 lines
16 KiB
C++
Executable File
/**
|
|
* Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved.
|
|
*
|
|
* BSD-3-Clause
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* 3. Neither the name of the copyright holder nor the names of its
|
|
* contributors may be used to endorse or promote products derived from
|
|
* this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
* @file bme68xLibrary.cpp
|
|
* @date 8 Feb 2022
|
|
* @version 1.1.40407
|
|
*
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "bme68xLibrary.h"
|
|
|
|
/* Maximum transaction size. Field size 17 x 3 */
|
|
#define BME68X_MAX_READ_LENGTH 51
|
|
|
|
#ifdef ARDUINO_ARCH_ESP32
|
|
#define BME68X_I2C_BUFFER_SIZE I2C_BUFFER_LENGTH
|
|
|
|
#define BME68X_BURST_SPI_TRANSFER
|
|
#endif
|
|
|
|
#ifdef ARDUINO_ARCH_MBED
|
|
/* Assuming all MBED implementations of Wire have 256 byte sized buffers */
|
|
#define BME68X_I2C_BUFFER_SIZE 256
|
|
|
|
#define BME68X_BURST_SPI_TRANSFER
|
|
#endif
|
|
|
|
#ifdef ARDUINO_ARCH_ESP8266
|
|
#define BME68X_I2C_BUFFER_SIZE BUFFER_LENGTH
|
|
|
|
#define BME68X_BURST_SPI_TRANSFER
|
|
#endif
|
|
|
|
#ifdef ARDUINO_ARCH_AVR
|
|
#define BME68X_I2C_BUFFER_SIZE BUFFER_LENGTH
|
|
|
|
#define BME68X_BURST_SPI_TRANSFER
|
|
#endif
|
|
|
|
#ifdef ARDUINO_ARCH_NRF52
|
|
#define BME68X_I2C_BUFFER_SIZE SERIAL_BUFFER_SIZE
|
|
|
|
#define BME68X_BURST_SPI_TRANSFER
|
|
#endif
|
|
|
|
#ifdef ARDUINO_ARCH_SAMD
|
|
/* Assuming all Arduino's and Adafruit's SAMD
|
|
* implementations of Wire have 256 byte sized buffers */
|
|
#define BME68X_I2C_BUFFER_SIZE 256
|
|
|
|
#define BME68X_BURST_SPI_TRANSFER
|
|
#endif
|
|
|
|
#ifdef ARDUINO_ARCH_SAM
|
|
#define BME68X_I2C_BUFFER_SIZE BUFFER_LENGTH
|
|
|
|
#define BME68X_BURST_SPI_TRANSFER
|
|
#endif
|
|
|
|
/* Optimistically assume support for at least 64 byte reads */
|
|
#ifndef BME68X_I2C_BUFFER_SIZE
|
|
#define BME68X_I2C_BUFFER_SIZE 64
|
|
#endif
|
|
|
|
#if BME68X_MAX_READ_LENGTH > BME68X_I2C_BUFFER_SIZE
|
|
#warning "Wire read requires a larger buffer size. Use SPI"
|
|
#endif
|
|
|
|
MyLibs::Bme68x::Bme68x(void)
|
|
{
|
|
comm.i2c.wireobj = NULL;
|
|
comm.i2c.i2cAddr = 0;
|
|
comm.spi.spiobj = NULL;
|
|
comm.spi.cs = 0;
|
|
status = BME68X_OK;
|
|
memset(&bme6, 0, sizeof(bme6));
|
|
memset(&conf, 0, sizeof(conf));
|
|
memset(&heatrConf, 0, sizeof(heatrConf));
|
|
memset(sensorData, 0, sizeof(sensorData));
|
|
bme6.amb_temp = 25; /* Typical room temperature in Celsius */
|
|
nFields = 0;
|
|
iFields = 0;
|
|
lastOpMode = BME68X_SLEEP_MODE;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to initialize the sensor based on custom callbacks
|
|
*/
|
|
void MyLibs::Bme68x::begin(bme68xIntf intf, bme68x_read_fptr_t read, bme68x_write_fptr_t write,
|
|
bme68x_delay_us_fptr_t idleTask, void *intfPtr)
|
|
{
|
|
|
|
bme6.intf = intf;
|
|
bme6.read = read;
|
|
bme6.write = write;
|
|
bme6.delay_us = idleTask;
|
|
bme6.intf_ptr = intfPtr;
|
|
bme6.amb_temp = 25;
|
|
|
|
status = bme68x_init(&bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to initialize the sensor based on the Wire library
|
|
*/
|
|
void MyLibs::Bme68x::begin(uint8_t i2cAddr, TwoWire &i2c, bme68x_delay_us_fptr_t idleTask)
|
|
{
|
|
comm.i2c.i2cAddr = i2cAddr;
|
|
comm.i2c.wireobj = &i2c;
|
|
bme6.intf = BME68X_I2C_INTF;
|
|
bme6.read = bme68xI2cRead;
|
|
bme6.write = bme68xI2cWrite;
|
|
bme6.delay_us = idleTask;
|
|
bme6.intf_ptr = &comm;
|
|
bme6.amb_temp = 25;
|
|
|
|
status = bme68x_init(&bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to initialize the sensor based on the SPI library
|
|
*/
|
|
void MyLibs::Bme68x::begin(uint8_t chipSelect, SPIClass &spi, bme68x_delay_us_fptr_t idleTask)
|
|
{
|
|
pinMode(chipSelect, OUTPUT);
|
|
digitalWrite(chipSelect, HIGH);
|
|
delay(1);
|
|
digitalWrite(chipSelect, LOW); /* Switch to SPI with a dummy transaction */
|
|
delay(1);
|
|
digitalWrite(chipSelect, HIGH);
|
|
comm.spi.cs = chipSelect;
|
|
comm.spi.spiobj = &spi;
|
|
bme6.intf = BME68X_SPI_INTF;
|
|
bme6.read = bme68xSpiRead;
|
|
bme6.write = bme68xSpiWrite;
|
|
bme6.delay_us = idleTask;
|
|
bme6.intf_ptr = &comm;
|
|
bme6.amb_temp = 25;
|
|
|
|
status = bme68x_init(&bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to read a register
|
|
*/
|
|
uint8_t MyLibs::Bme68x::readReg(uint8_t regAddr)
|
|
{
|
|
uint8_t regData;
|
|
readReg(regAddr, ®Data, 1);
|
|
return regData;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to read multiple registers
|
|
*/
|
|
void MyLibs::Bme68x::readReg(uint8_t regAddr, uint8_t *regData, uint32_t length)
|
|
{
|
|
status = bme68x_get_regs(regAddr, regData, length, &bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to write data to a register
|
|
*/
|
|
void MyLibs::Bme68x::writeReg(uint8_t regAddr, uint8_t regData)
|
|
{
|
|
status = bme68x_set_regs(®Addr, ®Data, 1, &bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to write multiple registers
|
|
*/
|
|
void MyLibs::Bme68x::writeReg(uint8_t *regAddr, const uint8_t *regData, uint32_t length)
|
|
{
|
|
status = bme68x_set_regs(regAddr, regData, length, &bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to trigger a soft reset
|
|
*/
|
|
void MyLibs::Bme68x::softReset(void)
|
|
{
|
|
status = bme68x_soft_reset(&bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the ambient temperature for better configuration
|
|
*/
|
|
void MyLibs::Bme68x::setAmbientTemp(int8_t temp)
|
|
{
|
|
bme6.amb_temp = temp;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get the measurement duration in microseconds
|
|
*/
|
|
uint32_t MyLibs::Bme68x::getMeasDur(uint8_t opMode)
|
|
{
|
|
if (opMode == BME68X_SLEEP_MODE)
|
|
opMode = lastOpMode;
|
|
|
|
return bme68x_get_meas_dur(opMode, &conf, &bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the operation mode
|
|
*/
|
|
void MyLibs::Bme68x::setOpMode(uint8_t opMode)
|
|
{
|
|
status = bme68x_set_op_mode(opMode, &bme6);
|
|
if ((status == BME68X_OK) && (opMode != BME68X_SLEEP_MODE))
|
|
lastOpMode = opMode;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get the operation mode
|
|
*/
|
|
uint8_t MyLibs::Bme68x::getOpMode(void)
|
|
{
|
|
uint8_t opMode;
|
|
status = bme68x_get_op_mode(&opMode, &bme6);
|
|
return opMode;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get the Temperature, Pressure and Humidity over-sampling
|
|
*/
|
|
void MyLibs::Bme68x::getTPH(uint8_t &osHum, uint8_t &osTemp, uint8_t &osPres)
|
|
{
|
|
status = bme68x_get_conf(&conf, &bme6);
|
|
|
|
if (status == BME68X_OK)
|
|
{
|
|
osHum = conf.os_hum;
|
|
osTemp = conf.os_temp;
|
|
osPres = conf.os_pres;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the Temperature, Pressure and Humidity over-sampling
|
|
*/
|
|
void MyLibs::Bme68x::setTPH(uint8_t osTemp, uint8_t osPres, uint8_t osHum)
|
|
{
|
|
status = bme68x_get_conf(&conf, &bme6);
|
|
|
|
if (status == BME68X_OK)
|
|
{
|
|
conf.os_hum = osHum;
|
|
conf.os_temp = osTemp;
|
|
conf.os_pres = osPres;
|
|
|
|
status = bme68x_set_conf(&conf, &bme6);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get the filter configuration
|
|
*/
|
|
uint8_t MyLibs::Bme68x::getFilter(void)
|
|
{
|
|
status = bme68x_get_conf(&conf, &bme6);
|
|
|
|
return conf.filter;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the filter configuration
|
|
*/
|
|
void MyLibs::Bme68x::setFilter(uint8_t filter)
|
|
{
|
|
status = bme68x_get_conf(&conf, &bme6);
|
|
|
|
if (status == BME68X_OK)
|
|
{
|
|
conf.filter = filter;
|
|
|
|
status = bme68x_set_conf(&conf, &bme6);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get the sleep duration during Sequential mode
|
|
*/
|
|
uint8_t MyLibs::Bme68x::getSeqSleep(void)
|
|
{
|
|
status = bme68x_get_conf(&conf, &bme6);
|
|
|
|
return conf.odr;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the sleep duration during Sequential mode
|
|
*/
|
|
void MyLibs::Bme68x::setSeqSleep(uint8_t odr)
|
|
{
|
|
status = bme68x_get_conf(&conf, &bme6);
|
|
|
|
if (status == BME68X_OK)
|
|
{
|
|
conf.odr = odr;
|
|
|
|
status = bme68x_set_conf(&conf, &bme6);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the heater profile for Forced mode
|
|
*/
|
|
void MyLibs::Bme68x::setHeaterProf(uint16_t temp, uint16_t dur)
|
|
{
|
|
heatrConf.enable = BME68X_ENABLE;
|
|
heatrConf.heatr_temp = temp;
|
|
heatrConf.heatr_dur = dur;
|
|
|
|
status = bme68x_set_heatr_conf(BME68X_FORCED_MODE, &heatrConf, &bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the heater profile for Sequential mode
|
|
*/
|
|
void MyLibs::Bme68x::setHeaterProf(uint16_t *temp, uint16_t *dur, uint8_t profileLen)
|
|
{
|
|
heatrConf.enable = BME68X_ENABLE;
|
|
heatrConf.heatr_temp_prof = temp;
|
|
heatrConf.heatr_dur_prof = dur;
|
|
heatrConf.profile_len = profileLen;
|
|
|
|
status = bme68x_set_heatr_conf(BME68X_SEQUENTIAL_MODE, &heatrConf, &bme6);
|
|
|
|
}
|
|
|
|
/**
|
|
* @brief Function to set the heater profile for Parallel mode
|
|
*/
|
|
void MyLibs::Bme68x::setHeaterProf(uint16_t *temp, uint16_t *mul, uint16_t sharedHeatrDur, uint8_t profileLen)
|
|
{
|
|
heatrConf.enable = BME68X_ENABLE;
|
|
heatrConf.heatr_temp_prof = temp;
|
|
heatrConf.heatr_dur_prof = mul;
|
|
heatrConf.shared_heatr_dur = sharedHeatrDur;
|
|
heatrConf.profile_len = profileLen;
|
|
|
|
status = bme68x_set_heatr_conf(BME68X_PARALLEL_MODE, &heatrConf, &bme6);
|
|
}
|
|
|
|
/**
|
|
* @brief Function to fetch data from the sensor into the local buffer
|
|
*/
|
|
uint8_t MyLibs::Bme68x::fetchData(void)
|
|
{
|
|
nFields = 0;
|
|
status = bme68x_get_data(lastOpMode, sensorData, &nFields, &bme6);
|
|
iFields = 0;
|
|
|
|
return nFields;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get a single data field
|
|
*/
|
|
uint8_t MyLibs::Bme68x::getData(bme68xData &data)
|
|
{
|
|
if (lastOpMode == BME68X_FORCED_MODE)
|
|
{
|
|
data = sensorData[0];
|
|
} else
|
|
{
|
|
if (nFields)
|
|
{
|
|
/* iFields spans from 0-2 while nFields spans from
|
|
* 0-3, where 0 means that there is no new data
|
|
*/
|
|
data = sensorData[iFields];
|
|
iFields++;
|
|
|
|
/* Limit reading continuously to the last fields read */
|
|
if (iFields >= nFields)
|
|
{
|
|
iFields = nFields - 1;
|
|
return 0;
|
|
}
|
|
|
|
/* Indicate if there is something left to read */
|
|
return nFields - iFields;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get whole sensor data
|
|
*/
|
|
MyLibs::bme68xData* MyLibs::Bme68x::getAllData(void)
|
|
{
|
|
return sensorData;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get the BME68x heater configuration
|
|
*/
|
|
const MyLibs::bme68xHeatrConf& MyLibs::Bme68x::getHeaterConfiguration(void)
|
|
{
|
|
return heatrConf;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to retrieve the sensor's unique ID
|
|
*/
|
|
uint32_t MyLibs::Bme68x::getUniqueId(void)
|
|
{
|
|
uint8_t id_regs[4];
|
|
uint32_t uid;
|
|
readReg(BME68X_REG_UNIQUE_ID, id_regs, 4);
|
|
|
|
uint32_t id1 = ((uint32_t) id_regs[3] + ((uint32_t) id_regs[2] << 8)) & 0x7fff;
|
|
uid = (id1 << 16) + (((uint32_t) id_regs[1]) << 8) + (uint32_t) id_regs[0];
|
|
|
|
return uid;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get the error code of the interface functions
|
|
*/
|
|
BME68X_INTF_RET_TYPE MyLibs::Bme68x::intfError(void)
|
|
{
|
|
return bme6.intf_rslt;
|
|
}
|
|
|
|
/**
|
|
* @brief Function to check if an error / warning has occurred
|
|
*/
|
|
int8_t MyLibs::Bme68x::checkStatus(void)
|
|
{
|
|
if (status < BME68X_OK)
|
|
{
|
|
return BME68X_ERROR;
|
|
}
|
|
else if(status > BME68X_OK)
|
|
{
|
|
return BME68X_WARNING;
|
|
}
|
|
else
|
|
{
|
|
return BME68X_OK;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Function to get a brief text description of the error
|
|
*/
|
|
String MyLibs::Bme68x::statusString(void)
|
|
{
|
|
String ret = "";
|
|
switch (status)
|
|
{
|
|
case BME68X_OK:
|
|
/* Don't return a text for OK */
|
|
break;
|
|
case BME68X_E_NULL_PTR:
|
|
ret = "Null pointer";
|
|
break;
|
|
case BME68X_E_COM_FAIL:
|
|
ret = "Communication failure";
|
|
break;
|
|
case BME68X_E_DEV_NOT_FOUND:
|
|
ret = "Sensor not found";
|
|
break;
|
|
case BME68X_E_INVALID_LENGTH:
|
|
ret = "Invalid length";
|
|
break;
|
|
case BME68X_W_DEFINE_OP_MODE:
|
|
ret = "Set the operation mode";
|
|
break;
|
|
case BME68X_W_NO_NEW_DATA:
|
|
ret = "No new data";
|
|
break;
|
|
case BME68X_W_DEFINE_SHD_HEATR_DUR:
|
|
ret = "Set the shared heater duration";
|
|
break;
|
|
default:
|
|
ret = "Undefined error code";
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
namespace MyLibs
|
|
{
|
|
|
|
/**
|
|
* @brief Function that implements the default microsecond delay callback
|
|
*/
|
|
void bme68xDelayUs(uint32_t periodUs, void *intfPtr) {
|
|
(void) intfPtr;
|
|
delayMicroseconds(periodUs);
|
|
}
|
|
|
|
/**
|
|
* @brief Function that implements the default SPI write transaction
|
|
*/
|
|
int8_t bme68xSpiWrite(uint8_t regAddr, const uint8_t *regData,
|
|
uint32_t length, void *intfPtr) {
|
|
MyLibs::bme68xScommT *comm = NULL;
|
|
|
|
if (intfPtr) {
|
|
comm = (MyLibs::bme68xScommT *) intfPtr;
|
|
|
|
if (comm->spi.spiobj) {
|
|
digitalWrite(comm->spi.cs, LOW);
|
|
|
|
comm->spi.spiobj->transfer(regAddr);
|
|
#ifdef BME68X_BURST_SPI_TRANSFER
|
|
comm->spi.spiobj->transfer((uint8_t *)regData, length);
|
|
#else
|
|
for(uint32_t i = 0; i < length; i++) {
|
|
comm->spi.spiobj->transfer(regData[i]);
|
|
}
|
|
#endif
|
|
|
|
digitalWrite(comm->spi.cs, HIGH);
|
|
} else {
|
|
return BME68X_E_NULL_PTR;
|
|
}
|
|
} else {
|
|
return BME68X_E_NULL_PTR;
|
|
}
|
|
|
|
return BME68X_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Function that implements the default SPI read transaction
|
|
*/
|
|
int8_t bme68xSpiRead(uint8_t regAddr, uint8_t *regData, uint32_t length,
|
|
void *intfPtr) {
|
|
MyLibs::bme68xScommT *comm = NULL;
|
|
|
|
if (intfPtr) {
|
|
comm = (MyLibs::bme68xScommT *) intfPtr;
|
|
|
|
if (comm->spi.spiobj) {
|
|
digitalWrite(comm->spi.cs, LOW);
|
|
|
|
comm->spi.spiobj->transfer(regAddr);
|
|
memset(regData, 0xFF, length);
|
|
#ifdef BME68X_BURST_SPI_TRANSFER
|
|
comm->spi.spiobj->transfer(regData, length);
|
|
#else
|
|
for(uint32_t i = 0; i < length; i++) {
|
|
regData[i] = comm->spi.spiobj->transfer(0xFF);
|
|
}
|
|
#endif
|
|
|
|
digitalWrite(comm->spi.cs, HIGH);
|
|
} else {
|
|
return BME68X_E_NULL_PTR;
|
|
}
|
|
} else {
|
|
return BME68X_E_NULL_PTR;
|
|
}
|
|
|
|
return BME68X_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Function that implements the default I2C write transaction
|
|
*/
|
|
int8_t bme68xI2cWrite(uint8_t regAddr, const uint8_t *regData,
|
|
uint32_t length, void *intfPtr) {
|
|
uint32_t i;
|
|
int8_t rslt = BME68X_OK;
|
|
MyLibs::bme68xScommT *comm = NULL;
|
|
|
|
#ifdef BME68X_I2C_BUFFER_SIZE
|
|
if (length + 1 > BME68X_I2C_BUFFER_SIZE)
|
|
return BME68X_E_COM_FAIL;
|
|
#endif
|
|
|
|
if (intfPtr) {
|
|
comm = (MyLibs::bme68xScommT *) intfPtr;
|
|
if (comm->i2c.wireobj) {
|
|
comm->i2c.wireobj->beginTransmission(comm->i2c.i2cAddr);
|
|
comm->i2c.wireobj->write(regAddr);
|
|
for (i = 0; i < length; i++) {
|
|
comm->i2c.wireobj->write(regData[i]);
|
|
}
|
|
if (comm->i2c.wireobj->endTransmission()) {
|
|
rslt = BME68X_E_COM_FAIL;
|
|
}
|
|
} else {
|
|
rslt = BME68X_E_NULL_PTR;
|
|
}
|
|
} else {
|
|
rslt = BME68X_E_NULL_PTR;
|
|
}
|
|
|
|
return rslt;
|
|
}
|
|
|
|
/**
|
|
* @brief Function that implements the default I2C read transaction
|
|
*/
|
|
int8_t bme68xI2cRead(uint8_t regAddr, uint8_t *regData, uint32_t length,
|
|
void *intfPtr) {
|
|
uint32_t i;
|
|
int8_t rslt = BME68X_OK;
|
|
MyLibs::bme68xScommT *comm = NULL;
|
|
|
|
#ifdef BME68X_I2C_BUFFER_SIZE
|
|
if (length > BME68X_I2C_BUFFER_SIZE)
|
|
return BME68X_E_COM_FAIL;
|
|
#endif
|
|
|
|
if (intfPtr) {
|
|
comm = (MyLibs::bme68xScommT *) intfPtr;
|
|
if (comm->i2c.wireobj) {
|
|
comm->i2c.wireobj->beginTransmission(comm->i2c.i2cAddr);
|
|
comm->i2c.wireobj->write(regAddr);
|
|
if (comm->i2c.wireobj->endTransmission()) {
|
|
return BME68X_E_COM_FAIL;
|
|
}
|
|
comm->i2c.wireobj->requestFrom((int) comm->i2c.i2cAddr,
|
|
(int) length);
|
|
for (i = 0; (i < length) && comm->i2c.wireobj->available(); i++) {
|
|
regData[i] = comm->i2c.wireobj->read();
|
|
}
|
|
} else {
|
|
rslt = BME68X_E_NULL_PTR;
|
|
}
|
|
} else {
|
|
rslt = BME68X_E_NULL_PTR;
|
|
}
|
|
|
|
return rslt;
|
|
}
|
|
} |