/** * 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; }
/** * 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 = ® }; /* 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 = ® }; /* 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, ®); 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, ®); 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; }
/** * 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 = ® }; /* 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, ®); 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; }
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; }
/** * 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; }