Steve Martin / libdev_si7021

si7021.cpp

Committer:
ninensei
Date:
2017-09-12
Revision:
0:9909c9c7d326

File content as of revision 0:9909c9c7d326:

#include "si7021.h"

#define SI7021A20_I2C_ADDR              0x80

#define SI7021A20_CMD_MEAS_RH_HMM       0xE5
#define SI7021A20_CMD_MEAS_RH_NHMM      0xF5
#define SI7021A20_CMD_MEAS_TEMP_HMM     0xE3
#define SI7021A20_CMD_MEAS_TEMP_NHMM    0xF3
#define SI7021A20_CMD_READ_TEMP         0xE0
#define SI7021A20_CMD_RESET             0xFE
#define SI7021A20_CMD_WRITE_USER1       0xE6
#define SI7021A20_CMD_WRITE_USER2       0xE7
#define SI7021A20_CMD_WRITE_HEAT_CTRL   0x51
#define SI7021A20_CMD_READ_HEAT_CTRL    0x11
#define SI7021A20_CMD_READ_ID1          0xFA0F
#define SI7021A20_CMD_READ_ID2          0xFCC9
#define SI7021A20_REGF_ID2_DEV_ID               0x15
#define SI7021A20_CMD_READ_FW_REV       0x84B8

bool SI7021::_i2c_transfer(int address, void * buff, size_t write_size, size_t read_size)
{
    bool ok;
    bool expect_response = (read_size != 0);
    
    ok = !_i2c->write(address, (char*)buff, write_size, expect_response);
    if (ok && expect_response)
        ok = !_i2c->read(address, (char*)buff, read_size);

    return ok;
}

/*
bool SI7021::_validate(void)
{
    bool    ok;
    uint8_t buff[4];

    buff[0] = (uint8_t)(SI7021A20_CMD_READ_ID2 >> 8);
    buff[1] = (uint8_t)(SI7021A20_CMD_READ_ID2);
    
    ok = (i2c_transfer(SI7021A20_I2C_ADDR, buff, 2, 1)) &&
         (SI7021A20_REGF_ID2_DEV_ID == buff[0]);
    
    return ok;
}
*/

bool SI7021::read(si7021_measurements_t * data) {
    bool    ok;
    union {
        char    cmd;
        struct {
            uint8_t  meas_msb;
            uint8_t  meas_lsb;
        };
    } buff;

    buff.cmd = SI7021A20_CMD_MEAS_RH_HMM;
    ok = (_i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2));
    if (ok) {
        // Humidity% = measurement * 125/65536 - 6
        int meas_raw        = ((int)buff.meas_msb << 8) + buff.meas_lsb;
        data->humidity_PR   = (float)meas_raw * (125.0F/65536.0F) - 6.0F;
//        data->humidity      = meas_raw / 2 - 1573;
//        data->humidity_norm = 262;
//        printf("<humidityH/r = %f/%d>", Humidity, meas_raw);
            
        buff.cmd = SI7021A20_CMD_READ_TEMP;
        ok = _i2c_transfer(SI7021A20_I2C_ADDR, &buff, 1, 2);
    }
    if (ok) {
        // TempC = measurement * 175.72/65536 - 46.85
        int meas_raw    = ((int)buff.meas_msb << 8) + buff.meas_lsb;
        data->temp_C    = meas_raw * (175.72/65536.0) - 46.85;
//        data->temp      = meas_raw / 2 - 8736;
//        data->temp_norm = 186;
//        printf("<tempC/F/r = %f/%f/%d>", Temp, Temp * 9 / 5 + 32, meas_raw);
    }
    return ok;
}