/**
 * Clears the interrupt by writing to the command register
 * as a special function
 * ______________________________________________________
 * |   CMD |     TYPE    |         ADDR/SF              |
 * |    7  |     6:5     |           4:0                |
 * |    1  |      11     |          00110               |
 * |_______|_____________|______________________________|
 *
 * @param The sensor interface
 * @return 0 on success, non-zero on failure
 */
int
tcs34725_clear_interrupt(struct sensor_itf *itf)
{
    int rc;
    uint8_t payload = TCS34725_COMMAND_BIT | TCS34725_CMD_TYPE | TCS34725_CMD_ADDR;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 0,
        .buffer = &payload
    };

    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        goto err;
    }

    return 0;
err:
    return rc;
}

/**
 * Sets threshold limits for interrupts, if the low threshold is set above
 * the high threshold, the high threshold is ignored and only the low
 * threshold is evaluated
 *
 * @param The sensor interface
 * @param lower threshold
 * @param higher threshold
 *
 * @return 0 on success, non-zero on failure
 */
int
tcs34725_set_int_limits(struct sensor_itf *itf, uint16_t low, uint16_t high)
{
    uint8_t payload[4];
    int rc;

    payload[0] = low & 0xFF;
    payload[1] = low >> 8;
    payload[2] = high & 0xFF;
    payload[3] = high >> 8;

    rc = tcs34725_writelen(itf, TCS34725_REG_AILTL, payload, sizeof(payload));
    if (rc) {
        return rc;
    }
    return 0;
}
Example #2
0
/**
 * Writes a single byte to the specified register
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero error on failure.
 */
int
mpu6050_write8(struct sensor_itf *itf, uint8_t reg, uint32_t value)
{
    int rc;
    uint8_t payload[2] = { reg, value & 0xFF };

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 2,
        .buffer = payload
    };

    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);

    if (rc) {
        MPU6050_ERR("Failed to write to 0x%02X:0x%02X with value 0x%02X\n",
                       itf->si_addr, reg, value);
        STATS_INC(g_mpu6050stats, read_errors);
    }

    return rc;
}

/**
 * Reads a single byte from the specified register
 *
 * @param The sensor interface
 * @param The register address to read from
 * @param Pointer to where the register value should be written
 *
 * @return 0 on success, non-zero error on failure.
 */
int
mpu6050_read8(struct sensor_itf *itf, uint8_t reg, uint8_t *value)
{
    int rc;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &reg
    };

    /* Register write */
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 0);
    if (rc) {
        MPU6050_ERR("I2C access failed at address 0x%02X\n", itf->si_addr);
        STATS_INC(g_mpu6050stats, write_errors);
        return rc;
    }

    /* Read one byte back */
    data_struct.buffer = value;
    rc = hal_i2c_master_read(itf->si_num, &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);

    if (rc) {
         MPU6050_ERR("Failed to read from 0x%02X:0x%02X\n", itf->si_addr, reg);
         STATS_INC(g_mpu6050stats, read_errors);
    }
    return rc;
}

/**
 * Reads a six bytes from the specified register
 *
 * @param The sensor interface
 * @param The register address to read from
 * @param Pointer to where the register value should be written
 *
 * @return 0 on success, non-zero error on failure.
 */
int
mpu6050_read48(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer)
{
    int rc;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &reg
    };

    /* Register write */
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 0);
    if (rc) {
        MPU6050_ERR("I2C access failed at address 0x%02X\n", itf->si_addr);
        STATS_INC(g_mpu6050stats, write_errors);
        return rc;
    }

    /* Read six bytes back */
    data_struct.len = 6;
    data_struct.buffer = buffer;
    rc = hal_i2c_master_read(itf->si_num, &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);

    if (rc) {
         MPU6050_ERR("Failed to read from 0x%02X:0x%02X\n", itf->si_addr, reg);
         STATS_INC(g_mpu6050stats, read_errors);
    }
    return rc;
}

int
mpu6050_reset(struct sensor_itf *itf)
{
    return mpu6050_write8(itf, MPU6050_PWR_MGMT_1, MPU6050_DEVICE_RESET);
}

int
mpu6050_sleep(struct sensor_itf *itf, uint8_t enable)
{
    uint8_t reg;
    int rc;

    rc = mpu6050_read8(itf, MPU6050_PWR_MGMT_1, &reg);
    if (rc) {
        return rc;
    }

    if (enable) {
        reg |= MPU6050_SLEEP;
    } else {
        reg &= ~MPU6050_SLEEP;
    }

    return mpu6050_write8(itf, MPU6050_PWR_MGMT_1, reg);
}
int
tsl2561_write8(struct sensor_itf *itf, uint8_t reg, uint32_t value)
{
    int rc;
    uint8_t payload[2] = { reg, value & 0xFF };

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 2,
        .buffer = payload
    };

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TSL2561_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_LOG(ERROR,
                    "Failed to write 0x%02X:0x%02X with value 0x%02lX\n",
                    data_struct.address, reg, value);
        STATS_INC(g_tsl2561stats, errors);
    }

    sensor_itf_unlock(itf);

    return rc;
}

int
tsl2561_write16(struct sensor_itf *itf, uint8_t reg, uint16_t value)
{
    int rc;
    uint8_t payload[3] = { reg, value & 0xFF, (value >> 8) & 0xFF };

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 3,
        .buffer = payload
    };

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TSL2561_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_LOG(ERROR,
                    "Failed to write @0x%02X with value 0x%02X 0x%02X\n",
                    reg, payload[0], payload[1]);
    }

    sensor_itf_unlock(itf);

    return rc;
}

int
tsl2561_read8(struct sensor_itf *itf, uint8_t reg, uint8_t *value)
{
    int rc;
    uint8_t payload;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &payload
    };

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TSL2561_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    /* Register write */
    payload = reg;
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_LOG(ERROR, "Failed to address sensor\n");
        goto err;
    }

    /* Read one byte back */
    payload = 0;
    rc = hal_i2c_master_read(itf->si_num, &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);
    *value = payload;
    if (rc) {
        TSL2561_LOG(ERROR, "Failed to read @0x%02X\n", reg);
    }

err:
    sensor_itf_unlock(itf);

    return rc;
}

int
tsl2561_read16(struct sensor_itf *itf, uint8_t reg, uint16_t *value)
{
    int rc;
    uint8_t payload[2] = { reg, 0 };

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = payload
    };

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TSL2561_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    /* Register write */
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_LOG(ERROR, "Failed to address sensor\n");
        goto err;
    }

    /* Read two bytes back */
    memset(payload, 0, 2);
    data_struct.len = 2;
    rc = hal_i2c_master_read(itf->si_num, &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);
    *value = (uint16_t)payload[0] | ((uint16_t)payload[1] << 8);
    if (rc) {
        TSL2561_LOG(ERROR, "Failed to read @0x%02X\n", reg);
        goto err;
    }

err:
    sensor_itf_unlock(itf);

    return rc;
}

/**
 * Enable or disables the sensor to save power
 *
 * @param The sensor interface
 * @param state  1 to enable the sensor, 0 to disable it
 *
 * @return 0 on success, non-zero on failure
 */
int
tsl2561_enable(struct sensor_itf *itf, uint8_t state)
{
    /* Enable the device by setting the control bit to 0x03 */
    return tsl2561_write8(itf, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
                          state ? TSL2561_CONTROL_POWERON :
                          TSL2561_CONTROL_POWEROFF);
}

/**
 * Checks if the sensor in enabled or not
 *
 * @param The sensor interface
 * @param ptr to enabled
 *
 * @return 0 on success, non-zero on fialure
 */
int
tsl2561_get_enable(struct sensor_itf *itf, uint8_t *enabled)
{
    int rc;
    uint8_t reg;

    /* Enable the device by setting the control bit to 0x03 */
    rc =  tsl2561_read8(itf, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
                        &reg);
    if (rc) {
        goto err;
    }

    *enabled = reg & 0x03 ? 1 : 0;

    return 0;
err:
    return rc;
}

/**
 * Sets the integration time used when sampling light values.
 *
 * @param The sensor interface
 * @param int_time The integration time which can be one of:
 *                  - 0x00: 13ms
 *                  - 0x01: 101ms
 *                  - 0x02: 402ms
 *
 * @return 0 on success, non-zero on failure
 */
int
tsl2561_set_integration_time(struct sensor_itf *itf,
                             uint8_t int_time)
{
    int rc;
    uint8_t gain;

    rc = tsl2561_get_gain(itf, &gain);
    if (rc) {
        goto err;
    }

    rc = tsl2561_write8(itf, TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
                        int_time | gain);
    if (rc) {
        goto err;
    }

    return 0;
err:
    return rc;
}
/**
 * Clear an asserted interrupt on the device
 *
 * @param The sensor interface
 * @return 0 on success, non-zero on failure
 */
int
tsl2561_clear_interrupt(struct sensor_itf *itf)
{
    int rc;
    uint8_t payload = { TSL2561_COMMAND_BIT | TSL2561_CLEAR_BIT };

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &payload
    };

    /* To clear the interrupt set the CLEAR bit in the COMMAND register */
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        goto err;
    }

    STATS_INC(g_tsl2561stats, ints_cleared);

    return 0;
err:
    return rc;
}

/**
 * Expects to be called back through os_dev_create().
 *
 * @param The device object associated with this luminosity sensor
 * @param Argument passed to OS device init, unused
 *
 * @return 0 on success, non-zero error on failure.
 */
int
tsl2561_init(struct os_dev *dev, void *arg)
{
    struct tsl2561 *tsl2561;
    struct sensor *sensor;
    int rc;

    if (!arg || !dev) {
        rc = SYS_ENODEV;
        goto err;
    }

    tsl2561 = (struct tsl2561 *) dev;

    tsl2561->cfg.mask = SENSOR_TYPE_ALL;

    sensor = &tsl2561->sensor;

    /* Initialise the stats entry */
    rc = stats_init(
        STATS_HDR(g_tsl2561stats),
        STATS_SIZE_INIT_PARMS(g_tsl2561stats, STATS_SIZE_32),
        STATS_NAME_INIT_PARMS(tsl2561_stat_section));
    SYSINIT_PANIC_ASSERT(rc == 0);
    /* Register the entry with the stats registry */
    rc = stats_register(dev->od_name, STATS_HDR(g_tsl2561stats));
    SYSINIT_PANIC_ASSERT(rc == 0);

    rc = sensor_init(sensor, dev);
    if (rc) {
        goto err;
    }

    /* Add the light driver */
    rc = sensor_set_driver(sensor, SENSOR_TYPE_LIGHT,
            (struct sensor_driver *) &g_tsl2561_sensor_driver);
    if (rc) {
        goto err;
    }

    /* Set the interface */
    rc = sensor_set_interface(sensor, arg);
    if (rc) {
        goto err;
    }

    rc = sensor_mgr_register(sensor);
    if (rc) {
        goto err;
    }

    return 0;
err:
    return rc;

}

static uint32_t
tsl2561_calculate_lux(uint16_t broadband, uint16_t ir, struct tsl2561_cfg *cfg)
{
    uint64_t chscale;
    uint64_t channel1;
    uint64_t channel0;
    uint16_t clipthreshold;
    uint64_t ratio1;
    uint64_t ratio;
    int64_t  b, m;
    uint64_t temp;
    uint32_t lux;

    /* Make sure the sensor isn't saturated! */
    switch (cfg->integration_time) {
        case TSL2561_LIGHT_ITIME_13MS:
            clipthreshold = TSL2561_CLIPPING_13MS;
            break;
        case TSL2561_LIGHT_ITIME_101MS:
            clipthreshold = TSL2561_CLIPPING_101MS;
            break;
        default:
            clipthreshold = TSL2561_CLIPPING_402MS;
            break;
    }

    /* Return 65536 lux if the sensor is saturated */
    if ((broadband > clipthreshold) || (ir > clipthreshold)) {
        return 65536;
    }

    /* Get the correct scale depending on the intergration time */
    switch (cfg->integration_time) {
        case TSL2561_LIGHT_ITIME_13MS:
            chscale = TSL2561_LUX_CHSCALE_TINT0;
            break;
        case TSL2561_LIGHT_ITIME_101MS:
            chscale = TSL2561_LUX_CHSCALE_TINT1;
            break;
        default: /* No scaling ... integration time = 402ms */
            chscale = (1 << TSL2561_LUX_CHSCALE);
            break;
    }

    /* Scale for gain (1x or 16x) */
    if (!cfg->gain) {
        chscale = chscale << 4;
    }

    /* Scale the channel values */
    channel0 = (broadband * chscale) >> TSL2561_LUX_CHSCALE;
    channel1 = (ir * chscale) >> TSL2561_LUX_CHSCALE;

    ratio1 = 0;
    /* Find the ratio of the channel values (Channel1/Channel0) */
    if (channel0 != 0) {
        ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE+1)) / channel0;
    }

    /* round the ratio value */
    ratio = (ratio1 + 1) >> 1;

#if MYNEWT_VAL(TSL2561_PACKAGE_CS)
    if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1C)) {
        b = TSL2561_LUX_B1C;
        m = TSL2561_LUX_M1C;
    } else if (ratio <= TSL2561_LUX_K2C) {
        b = TSL2561_LUX_B2C;
        m = TSL2561_LUX_M2C;
    } else if (ratio <= TSL2561_LUX_K3C) {
        b = TSL2561_LUX_B3C;
        m = TSL2561_LUX_M3C;
    } else if (ratio <= TSL2561_LUX_K4C) {
        b = TSL2561_LUX_B4C;
        m = TSL2561_LUX_M4C;
    } else if (ratio <= TSL2561_LUX_K5C) {
        b = TSL2561_LUX_B5C;
        m = TSL2561_LUX_M5C;
    } else if (ratio <= TSL2561_LUX_K6C) {
        b = TSL2561_LUX_B6C;
        m = TSL2561_LUX_M6C;
    } else if (ratio <= TSL2561_LUX_K7C) {
        b = TSL2561_LUX_B7C;
        m = TSL2561_LUX_M7C;
    } else if (ratio > TSL2561_LUX_K8C) {
        b = TSL2561_LUX_B8C;
        m = TSL2561_LUX_M8C;
    }
#else
    if ((ratio >= 0) && (ratio <= TSL2561_LUX_K1T)) {
        b = TSL2561_LUX_B1T;
        m = TSL2561_LUX_M1T;
    } else if (ratio <= TSL2561_LUX_K2T) {
        b = TSL2561_LUX_B2T;
        m = TSL2561_LUX_M2T;
    } else if (ratio <= TSL2561_LUX_K3T) {
        b = TSL2561_LUX_B3T;
        m = TSL2561_LUX_M3T;
    } else if (ratio <= TSL2561_LUX_K4T) {
        b = TSL2561_LUX_B4T;
        m = TSL2561_LUX_M4T;
    } else if (ratio <= TSL2561_LUX_K5T) {
        b = TSL2561_LUX_B5T;
        m = TSL2561_LUX_M5T;
    } else if (ratio <= TSL2561_LUX_K6T) {
        b = TSL2561_LUX_B6T;
        m = TSL2561_LUX_M6T;
    } else if (ratio <= TSL2561_LUX_K7T) {
        b = TSL2561_LUX_B7T;
        m = TSL2561_LUX_M7T;
    } else if (ratio > TSL2561_LUX_K8T) {
        b = TSL2561_LUX_B8T;
        m = TSL2561_LUX_M8T;
    }
#endif

    temp = ((channel0 * b) - (channel1 * m));

    /* Do not allow negative lux value */
    if (temp < 0) {
        temp = 0;
    }
    /* Round lsb (2^(LUX_SCALE-1)) */
    temp += (1 << (TSL2561_LUX_LUXSCALE - 1));

    /* Strip off fractional portion */
    lux = temp >> TSL2561_LUX_LUXSCALE;

    return lux;
}
Example #5
0
/**
 * Writes a single byte to the specified register using i2c
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero error on failure.
 */
int
lis2dw12_i2c_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
{
    int rc;
    uint8_t payload[2] = { reg, value };
    
    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 2,
        .buffer = payload
    };

    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);

    if (rc) {
        LIS2DW12_ERR("Failed to write to 0x%02X:0x%02X with value 0x%02X\n",
                    itf->si_addr, reg, value);
        STATS_INC(g_lis2dw12stats, read_errors);
    }

    return rc;
}

/**
 * Read multiple bytes starting from specified register over i2c
 *    
 * @param The sensor interface
 * @param The register address start reading from
 * @param Pointer to where the register value should be written
 * @param Number of bytes to read
 *
 * @return 0 on success, non-zero error on failure.
 */
int
lis2dw12_i2c_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer, uint8_t len)
{
    int rc;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &reg
    };

    /* Register write */
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        LIS2DW12_ERR("I2C access failed at address 0x%02X\n", itf->si_addr);
        STATS_INC(g_lis2dw12stats, write_errors);
        return rc;
    }

    /* Read data */
    data_struct.len = len;
    data_struct.buffer = buffer;
    rc = hal_i2c_master_read(itf->si_num, &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);

    if (rc) {
        LIS2DW12_ERR("Failed to read from 0x%02X:0x%02X\n", itf->si_addr, reg);
        STATS_INC(g_lis2dw12stats, read_errors);
    }

    return rc;
}

/**
 * Writes a single byte to the specified register using SPI
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero error on failure.
 */
int
lis2dw12_spi_write8(struct sensor_itf *itf, uint8_t reg, uint8_t value)
{
    int rc;

    /* Select the device */
    hal_gpio_write(itf->si_cs_pin, 0);

    /* Send the address */
    rc = hal_spi_tx_val(itf->si_num, reg & ~LIS2DW12_SPI_READ_CMD_BIT);
    if (rc == 0xFFFF) {
        rc = SYS_EINVAL;
        LIS2DW12_ERR("SPI_%u register write failed addr:0x%02X\n",
                   itf->si_num, reg);
        STATS_INC(g_lis2dw12stats, write_errors);
        goto err;
    }

    /* Read data */
    rc = hal_spi_tx_val(itf->si_num, value);
    if (rc == 0xFFFF) {
        rc = SYS_EINVAL;
        LIS2DW12_ERR("SPI_%u write failed addr:0x%02X:0x%02X\n",
                   itf->si_num, reg);
        STATS_INC(g_lis2dw12stats, write_errors);
        goto err;
    }

    rc = 0;

err:
    /* De-select the device */
    hal_gpio_write(itf->si_cs_pin, 1);

    return rc;
}
/**
 * Writes a single byte to the specified register
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero error on failure.
 */
int
tcs34725_write8(struct sensor_itf *itf, uint8_t reg, uint32_t value)
{
    int rc;
    uint8_t payload[2] = { reg | TCS34725_COMMAND_BIT, value & 0xFF };

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 2,
        .buffer = payload
    };

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TCS34725_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TCS34725_LOG(ERROR,
                     "Failed to write to 0x%02X:0x%02X with value 0x%02lX\n",
                     data_struct.address, reg, value);
        STATS_INC(g_tcs34725stats, errors);
    }

    sensor_itf_unlock(itf);

    return rc;
}

/**
 * Reads a single byte from the specified register
 *
 * @param The sensor interface
 * @param The register address to read from
 * @param Pointer to where the register value should be written
 *
 * @return 0 on success, non-zero error on failure.
 */
int
tcs34725_read8(struct sensor_itf *itf, uint8_t reg, uint8_t *value)
{
    int rc;
    uint8_t payload;

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = &payload
    };

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TCS34725_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    /* Register write */
    payload = reg | TCS34725_COMMAND_BIT;
    rc = hal_i2c_master_write(itf->si_num, &data_struct, OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TCS34725_LOG(ERROR, "I2C access failed at address 0x%02X\n",
                     data_struct.address);
        STATS_INC(g_tcs34725stats, errors);
        goto err;
    }

    /* Read one byte back */
    payload = 0;
    rc = hal_i2c_master_read(itf->si_num, &data_struct, OS_TICKS_PER_SEC / 10, 1);
    *value = payload;
    if (rc) {
        TCS34725_LOG(ERROR, "Failed to read from 0x%02X:0x%02X\n",
                     data_struct.address, reg);
        STATS_INC(g_tcs34725stats, errors);
    }

err:
    sensor_itf_unlock(itf);

    return rc;
}

/**
 * Read data from the sensor of variable length (MAX: 8 bytes)
 *
 * @param Register to read from
 * @param Bufer to read into
 * @param Length of the buffer
 *
 * @return 0 on success and non-zero on failure
 */
int
tcs34725_readlen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer, uint8_t len)
{
    int rc;
    uint8_t payload[9] = { reg | TCS34725_COMMAND_BIT, 0, 0, 0, 0, 0, 0, 0, 0};

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = payload
    };

    /* Clear the supplied buffer */
    memset(buffer, 0, len);

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TCS34725_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    /* Register write */
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TCS34725_LOG(ERROR, "I2C access failed at address 0x%02X\n",
                     data_struct.address);
        STATS_INC(g_tcs34725stats, errors);
        goto err;
    }

    /* Read len bytes back */
    memset(payload, 0, sizeof(payload));
    data_struct.len = len;
    rc = hal_i2c_master_read(itf->si_num, &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);

    if (rc) {
        TCS34725_LOG(ERROR, "Failed to read from 0x%02X:0x%02X\n",
                     data_struct.address, reg);
        STATS_INC(g_tcs34725stats, errors);
        goto err;
    }

    /* Copy the I2C results into the supplied buffer */
    memcpy(buffer, payload, len);

err:
    sensor_itf_unlock(itf);

    return rc;
}

/**
 * Writes a multiple bytes to the specified register (MAX: 8 bytes)
 *
 * @param The sensor interface
 * @param The register address to write to
 * @param The data buffer to write from
 *
 * @return 0 on success, non-zero error on failure.
 */
int
tcs34725_writelen(struct sensor_itf *itf, uint8_t reg, uint8_t *buffer, uint8_t len)
{
    int rc;
    uint8_t payload[9] = { reg, 0, 0, 0, 0, 0, 0, 0, 0};

    struct hal_i2c_master_data data_struct = {
        .address = itf->si_addr,
        .len = 1,
        .buffer = payload
    };

    if (len > (sizeof(payload) - 1)) {
        rc = OS_EINVAL;
        goto err;
    }

    memcpy(&payload[1], buffer, len);

    rc = sensor_itf_lock(itf, MYNEWT_VAL(TCS34725_ITF_LOCK_TMO));
    if (rc) {
        return rc;
    }

    /* Register write */
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TCS34725_LOG(ERROR, "I2C access failed at address 0x%02X\n",
                     data_struct.address);
        STATS_INC(g_tcs34725stats, errors);
        goto err;
    }

    memset(payload, 0, sizeof(payload));
    data_struct.len = len;
    rc = hal_i2c_master_write(itf->si_num, &data_struct,
                              OS_TICKS_PER_SEC / 10, len);

    if (rc) {
        TCS34725_LOG(ERROR, "Failed to read from 0x%02X:0x%02X\n",
                     data_struct.address, reg);
        STATS_INC(g_tcs34725stats, errors);
        goto err;
    }

err:
    sensor_itf_unlock(itf);

    return rc;
}


#if MYNEWT_VAL(MATHLIB_SUPPORT)
/**
 * Float power function
 *
 * @param float base
 * @param float exponent
 */
static float
powf(float base, float exp)
{
    return (float)(pow((double)base, (double)exp));
}

#endif

/**
 *
 * Enables the device
 *
 * @param The sensor interface
 * @param enable/disable
 * @return 0 on success, non-zero on error
 */
int
tcs34725_enable(struct sensor_itf *itf, uint8_t enable)
{
    int rc;
    uint8_t reg;

    rc = tcs34725_read8(itf, TCS34725_REG_ENABLE, &reg);
    if (rc) {
        goto err;
    }

    os_time_delay((3 * OS_TICKS_PER_SEC)/1000 + 1);

    if (enable) {
        rc = tcs34725_write8(itf, TCS34725_REG_ENABLE,
                             reg | TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
        if (rc) {
            goto err;
        }
    } else {
        rc = tcs34725_write8(itf, TCS34725_REG_ENABLE, reg &
                             ~(TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN));
        if (rc) {
            goto err;
        }
    }

    return 0;
err:
    return rc;
}
Example #7
0
int
tsl2561_write8(uint8_t reg, uint32_t value)
{
    int rc;
    uint8_t payload[2] = { reg, value & 0xFF };

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(TSL2561_I2CADDR),
        .len = 2,
        .buffer = payload
    };

    rc = hal_i2c_master_write(MYNEWT_VAL(TSL2561_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_ERR("Failed to write 0x%02X:0x%02X with value 0x%02X\n",
                    data_struct.address, reg, value);
#if MYNEWT_VAL(TSL2561_STATS)
        STATS_INC(g_tsl2561stats, errors);
#endif
    }

    return rc;
}

int
tsl2561_write16(uint8_t reg, uint16_t value)
{
    int rc;
    uint8_t payload[3] = { reg, value & 0xFF, (value >> 8) & 0xFF };

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(TSL2561_I2CADDR),
        .len = 3,
        .buffer = payload
    };

    rc = hal_i2c_master_write(MYNEWT_VAL(TSL2561_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_ERR("Failed to write @0x%02X with value 0x%02X 0x%02X\n",
                    reg, payload[0], payload[1]);
    }

    return rc;
}

int
tsl2561_read8(uint8_t reg, uint8_t *value)
{
    int rc;
    uint8_t payload;

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(TSL2561_I2CADDR),
        .len = 1,
        .buffer = &payload
    };

    /* Register write */
    payload = reg;
    rc = hal_i2c_master_write(MYNEWT_VAL(TSL2561_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_ERR("Failed to address sensor\n");
        goto err;
    }

    /* Read one byte back */
    payload = 0;
    rc = hal_i2c_master_read(MYNEWT_VAL(TSL2561_I2CBUS), &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);
    *value = payload;
    if (rc) {
        TSL2561_ERR("Failed to read @0x%02X\n", reg);
    }

err:
    return rc;
}

int
tsl2561_read16(uint8_t reg, uint16_t *value)
{
    int rc;
    uint8_t payload[2] = { reg, 0 };

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(TSL2561_I2CADDR),
        .len = 1,
        .buffer = payload
    };

    /* Register write */
    rc = hal_i2c_master_write(MYNEWT_VAL(TSL2561_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        TSL2561_ERR("Failed to address sensor\n");
        goto err;
    }

    /* Read two bytes back */
    memset(payload, 0, 2);
    data_struct.len = 2;
    rc = hal_i2c_master_read(MYNEWT_VAL(TSL2561_I2CBUS), &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);
    *value = (uint16_t)payload[0] | ((uint16_t)payload[1] << 8);
    if (rc) {
        TSL2561_ERR("Failed to read @0x%02X\n", reg);
        goto err;
    }

err:
    return rc;
}

int
tsl2561_enable(uint8_t state)
{
    int rc;

    /* Enable the device by setting the control bit to 0x03 */
    rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
                        state ? TSL2561_CONTROL_POWERON :
                                TSL2561_CONTROL_POWEROFF);
    if (!rc) {
        g_tsl2561_enabled = state ? 1 : 0;
    }

    return rc;
}

uint8_t
tsl2561_get_enable (void)
{
    return g_tsl2561_enabled;
}

int
tsl2561_set_integration_time(uint8_t int_time)
{
    int rc;

    rc = tsl2561_write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
                        int_time | g_tsl2561_gain);
    if (rc) {
        goto err;
    }

    g_tsl2561_integration_time = int_time;

err:
    return rc;
}
int
adp5061_get_reg(struct adp5061_dev *dev, uint8_t addr, uint8_t *value)
{
    int rc = 0;
    uint8_t payload;
    struct hal_i2c_master_data data_struct = {
        .address = dev->a_chg_ctrl.cc_itf.cci_addr,
        .len = 1,
        .buffer = &payload
    };

    rc = ad5061_itf_lock(&dev->a_chg_ctrl.cc_itf, OS_TIMEOUT_NEVER);
    if (rc) {
        return rc;
    }

    /* Register write */
    payload = addr;
    rc = hal_i2c_master_write(dev->a_chg_ctrl.cc_itf.cci_num, &data_struct,
            OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        goto err;
    }

    /* Read one byte back */
    payload = addr;
    rc = hal_i2c_master_read(dev->a_chg_ctrl.cc_itf.cci_num, &data_struct,
            OS_TICKS_PER_SEC / 10, 1);
    *value = payload;


err:
    adp5061_itf_unlock(&dev->a_chg_ctrl.cc_itf);

    return rc;
}

int
adp5061_set_reg(struct adp5061_dev *dev, uint8_t addr, uint8_t value)
{
    int rc = 0;
    uint8_t payload[2] = { addr, value };
    struct hal_i2c_master_data data_struct = {
        .address = dev->a_chg_ctrl.cc_itf.cci_addr,
        .len = 2,
        .buffer = payload
    };

    rc = ad5061_itf_lock(&dev->a_chg_ctrl.cc_itf, OS_TIMEOUT_NEVER);
    if (rc) {
        return rc;
    }

    rc = hal_i2c_master_write(dev->a_chg_ctrl.cc_itf.cci_num, &data_struct,
            OS_TICKS_PER_SEC / 10, 1);

    adp5061_itf_unlock(&dev->a_chg_ctrl.cc_itf);

    return rc;
}

int
adp5061_set_regs(struct adp5061_dev *dev, uint8_t addr,
        const uint8_t *values, int count)
{
    int rc = 0;
    int i;
    uint8_t payload[1 + count];
    struct hal_i2c_master_data data_struct = {
        .address = dev->a_chg_ctrl.cc_itf.cci_addr,
        .len = count + 1,
        .buffer = payload
    };

    payload[0] = addr;
    for (i = 0; i < count; ++i) {
        payload[i + 1] = values[i];
    }

    rc = ad5061_itf_lock(&dev->a_chg_ctrl.cc_itf, OS_TIMEOUT_NEVER);
    if (rc) {
        return rc;
    }

    rc = hal_i2c_master_write(dev->a_chg_ctrl.cc_itf.cci_num, &data_struct,
            OS_TICKS_PER_SEC / 10, 1);

    adp5061_itf_unlock(&dev->a_chg_ctrl.cc_itf);

    return rc;
}

int
adp5061_get_device_id(struct adp5061_dev *dev, uint8_t *dev_id)
{
    return adp5061_get_reg(dev, REG_PART_ID, dev_id);
}

int
adp5061_set_charge_currents(struct adp5061_dev *dev, uint8_t ichg,
        uint8_t itrk_dead, uint8_t i_lim)
{
    int rc = 0;

    if ((ichg > ((1<<ADP5061_ICHG_LEN)-1)) ||
        (itrk_dead > ((1<<ADP5061_ITRK_DEAD_LEN)-1))) {
        assert(0);
    }
    dev->a_cfg.charging_current &= ~(ADP5061_ICHG_MASK |
            ADP5061_ITRK_DEAD_MASK);
    dev->a_cfg.charging_current |= (ADP5061_ICHG_SET(ichg) |
            ADP5061_ITRK_DEAD_SET(itrk_dead));

    rc = adp5061_set_reg(dev, REG_CHARGING_CURRENT,
            dev->a_cfg.charging_current);
    if (rc != 0) {
        goto err;
    }

    /* ILIM in REG_VIN_PIN_SETTINGS*/
    dev->a_cfg.vinx_pin_settings &= ~(ADP5061_VIN_SETTINGS_MASK);
    dev->a_cfg.vinx_pin_settings |= ADP5061_VIN_SETTINGS_SET(i_lim);

    rc = adp5061_set_reg(dev, REG_VIN_PIN_SETTINGS,
            dev->a_cfg.vinx_pin_settings);
err:
    return rc;
}
Example #9
0
/**
 * Writes a single byte to the specified register
 *
 * @param The register address to write to
 * @param The value to write
 *
 * @return 0 on success, non-zero error on failure.
 */
int
bno055_write8(uint8_t reg, uint8_t value)
{
    int rc;
    uint8_t payload[2] = { reg, value};

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(BNO055_I2CADDR),
        .len = 2,
        .buffer = payload
    };

    rc = hal_i2c_master_write(MYNEWT_VAL(BNO055_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC, 1);
    if (rc) {
        BNO055_ERR("Failed to write to 0x%02X:0x%02X with value 0x%02X\n",
                       data_struct.address, reg, value);
#if MYNEWT_VAL(BNO055_STATS)
        STATS_INC(g_bno055stats, errors);
#endif
    }

    return rc;
}

/**
 * Writes a multiple bytes to the specified register
 *
 * @param The register address to write to
 * @param The data buffer to write from
 *
 * @return 0 on success, non-zero error on failure.
 */
int
bno055_writelen(uint8_t reg, uint8_t *buffer, uint8_t len)
{
    int rc;
    uint8_t payload[23] = { reg, 0, 0, 0, 0, 0, 0, 0,
                              0, 0, 0, 0, 0, 0, 0, 0,
                              0, 0, 0, 0, 0, 0, 0};

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(BNO055_I2CADDR),
        .len = 1,
        .buffer = payload
    };

    memcpy(&payload[1], buffer, len);

    /* Register write */
    rc = hal_i2c_master_write(MYNEWT_VAL(BNO055_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        BNO055_ERR("I2C access failed at address 0x%02X\n", addr);
#if MYNEWT_VAL(BNO055_STATS)
        STATS_INC(g_bno055stats, errors);
#endif
        goto err;
    }

    memset(payload, 0, sizeof(payload));
    data_struct.len = len;
    rc = hal_i2c_master_write(MYNEWT_VAL(BNO055_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, len);

    if (rc) {
        BNO055_ERR("Failed to read from 0x%02X:0x%02X\n", addr, reg);
#if MYNEWT_VAL(BNO055_STATS)
        STATS_INC(g_bno055stats, errors);
#endif
        goto err;
    }

    return 0;
err:
    return rc;
}

/**
 * Reads a single byte from the specified register
 *
 * @param The register address to read from
 * @param Pointer to where the register value should be written
 *
 * @return 0 on success, non-zero error on failure.
 */
int
bno055_read8(uint8_t reg, uint8_t *value)
{
    int rc;
    uint8_t payload;

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(BNO055_I2CADDR),
        .len = 1,
        .buffer = &payload
    };

    /* Register write */
    payload = reg;
    rc = hal_i2c_master_write(MYNEWT_VAL(BNO055_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, 0);
    if (rc) {
        BNO055_ERR("I2C register write failed at address 0x%02X:0x%02X\n",
                   data_struct.address, reg);
#if MYNEWT_VAL(BNO055_STATS)
        STATS_INC(g_bno055stats, errors);
#endif
        goto err;
    }

    /* Read one byte back */
    payload = 0;
    rc = hal_i2c_master_read(MYNEWT_VAL(BNO055_I2CBUS), &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);
    *value = payload;
    if (rc) {
        BNO055_ERR("Failed to read from 0x%02X:0x%02X\n", addr, reg);
#if MYNEWT_VAL(BNO055_STATS)
        STATS_INC(g_bno055stats, errors);
#endif
    }

err:
    return rc;
}

/**
 * Read data from the sensor of variable length (MAX: 8 bytes)
 *
 *
 * @param Register to read from
 * @param Bufer to read into
 * @param Length of the buffer
 *
 * @return 0 on success and non-zero on failure
 */
static int
bno055_readlen(uint8_t reg, uint8_t *buffer, uint8_t len)
{
    int rc;
    uint8_t payload[23] = { reg, 0, 0, 0, 0, 0, 0, 0,
                              0, 0, 0, 0, 0, 0, 0, 0,
                              0, 0, 0, 0, 0, 0, 0};

    struct hal_i2c_master_data data_struct = {
        .address = MYNEWT_VAL(BNO055_I2CADDR),
        .len = 1,
        .buffer = payload
    };

    /* Clear the supplied buffer */
    memset(buffer, 0, len);

    /* Register write */
    rc = hal_i2c_master_write(MYNEWT_VAL(BNO055_I2CBUS), &data_struct,
                              OS_TICKS_PER_SEC / 10, 1);
    if (rc) {
        BNO055_ERR("I2C access failed at address 0x%02X\n", addr);
#if MYNEWT_VAL(BNO055_STATS)
        STATS_INC(g_bno055stats, errors);
#endif
        goto err;
    }

    /* Read len bytes back */
    memset(payload, 0, sizeof(payload));
    data_struct.len = len;
    rc = hal_i2c_master_read(MYNEWT_VAL(BNO055_I2CBUS), &data_struct,
                             OS_TICKS_PER_SEC / 10, 1);

    if (rc) {
        BNO055_ERR("Failed to read from 0x%02X:0x%02X\n", addr, reg);
#if MYNEWT_VAL(BNO055_STATS)
        STATS_INC(g_bno055stats, errors);
#endif
        goto err;
    }

    /* Copy the I2C results into the supplied buffer */
    memcpy(buffer, payload, len);

    return 0;
err:
    return rc;
}

/**
 * Setting operation mode for the bno055 sensor
 *
 * @param Operation mode for the sensor
 * @return 0 on success, non-zero on failure
 */
int
bno055_set_opr_mode(uint8_t mode)
{
    int rc;

    rc = bno055_write8(BNO055_OPR_MODE_ADDR, BNO055_OPR_MODE_CONFIG);
    if (rc) {
        goto err;
    }

    os_time_delay((OS_TICKS_PER_SEC * 19)/1000 + 1);

    rc = bno055_write8(BNO055_OPR_MODE_ADDR, mode);
    if (rc) {
        goto err;
    }

    /* Refer table 3-6 in the datasheet for the delay values */
    os_time_delay((OS_TICKS_PER_SEC * 7)/1000 + 1);

    return 0;
err:
    return rc;
}