Move to their own repos

This commit is contained in:
Pim van Pelt
2018-04-22 16:55:12 +02:00
parent a6edfa4c3b
commit c9b29def6c
15 changed files with 0 additions and 1084 deletions

View File

@ -1,74 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "mgos.h"
#include "mgos_i2c.h"
#ifdef __cplusplus
extern "C" {
#endif
enum mgos_barometer_type {
BARO_NONE = 0,
BARO_MPL115,
BARO_MPL3115,
BARO_BME280 // Also BMP280
};
struct mgos_barometer;
struct mgos_barometer_stats {
double last_read_time; // value of mg_time() upon last call to _read()
uint32_t read; // calls to _read()
uint32_t read_success; // successful _read()
uint32_t read_success_cached; // calls to _read() which were cached
// Note: read_errors := read - read_success - read_success_cached
double read_success_usecs; // time spent in successful uncached _read()
};
struct mgos_barometer *mgos_barometer_create_i2c(struct mgos_i2c *i2c, uint8_t i2caddr, enum mgos_barometer_type type);
void mgos_barometer_destroy(struct mgos_barometer **sensor);
bool mgos_barometer_has_thermometer(struct mgos_barometer *sensor);
bool mgos_barometer_has_barometer(struct mgos_barometer *sensor);
/* Set cache TTL -- will limit reads and return cached data. Set msecs=0 to turn off */
bool mgos_barometer_set_cache_ttl(struct mgos_barometer *sensor, uint16_t msecs);
/* Read all available sensor data from the IMU */
bool mgos_barometer_read(struct mgos_barometer *sensor);
/* Return barometer data in units of Pascals */
bool mgos_barometer_get_pressure(struct mgos_barometer *sensor, float *p);
/* Return temperature data in units of Celcius */
bool mgos_barometer_get_temperature(struct mgos_barometer *sensor, float *t);
/*
* Return statistics on the sensor.
*/
bool mgos_barometer_get_stats(struct mgos_barometer *sensor, struct mgos_barometer_stats *stats);
/*
* Initialization function for MGOS -- currently a noop.
*/
bool mgos_barometer_init(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,166 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mgos.h"
#include "mgos_barometer_internal.h"
#include "mgos_barometer_mpl115.h"
#include "mgos_barometer_mpl3115.h"
#include "mgos_barometer_bme280.h"
// Private functions follow
// Private functions end
// Public functions follow
struct mgos_barometer *mgos_barometer_create_i2c(struct mgos_i2c *i2c, uint8_t i2caddr, enum mgos_barometer_type type) {
struct mgos_barometer *sensor;
if (!i2c) {
return NULL;
}
sensor = calloc(1, sizeof(struct mgos_barometer));
if (!sensor) {
return NULL;
}
memset(sensor, 0, sizeof(struct mgos_barometer));
sensor->i2c=i2c;
sensor->i2caddr=i2caddr;
switch(type) {
case BARO_MPL115:
sensor->create = mgos_barometer_mpl115_create;
sensor->read = mgos_barometer_mpl115_read;
sensor->destroy = mgos_barometer_mpl115_destroy;
break;
case BARO_MPL3115:
sensor->detect = mgos_barometer_mpl3115_detect;
sensor->create = mgos_barometer_mpl3115_create;
sensor->read = mgos_barometer_mpl3115_read;
break;
case BARO_BME280:
sensor->detect = mgos_barometer_bme280_detect;
sensor->create = mgos_barometer_bme280_create;
sensor->read = mgos_barometer_bme280_read;
sensor->destroy = mgos_barometer_bme280_destroy;
break;
default:
LOG(LL_ERROR, ("Unknown mgos_barometer_type %d", type));
free(sensor);
return NULL;
}
sensor->type=type;
if (sensor->detect) {
if (!sensor->detect(sensor)) {
LOG(LL_ERROR, ("Could not detect mgos_barometer_type %d at I2C 0x%02x", type, i2caddr));
free(sensor);
return NULL;
} else {
LOG(LL_DEBUG, ("Successfully detected mgos_barometer_type %d at I2C 0x%02x", type, i2caddr));
}
}
if (sensor->create) {
if (!sensor->create(sensor)) {
LOG(LL_ERROR, ("Could not create mgos_barometer_type %d at I2C 0x%02x", type, i2caddr));
free(sensor);
return NULL;
} else {
LOG(LL_DEBUG, ("Successfully created mgos_barometer_type %d at I2C 0x%02x", type, i2caddr));
}
}
return sensor;
}
void mgos_barometer_destroy(struct mgos_barometer **sensor) {
if (!*sensor) {
return;
}
if ((*sensor)->destroy && !(*sensor)->destroy(*sensor)) {
LOG(LL_ERROR, ("Could not destroy mgos_barometer_type %d at I2C 0x%02x", (*sensor)->type, (*sensor)->i2caddr));
}
if ((*sensor)->user_data) free ((*sensor)->user_data);
free(*sensor);
*sensor = NULL;
return;
}
bool mgos_barometer_has_thermometer(struct mgos_barometer *sensor) {
if (!sensor) return false;
return (sensor->capabilities & MGOS_BAROMETER_CAP_THERMOMETER);
}
bool mgos_barometer_has_barometer(struct mgos_barometer *sensor) {
if (!sensor) return false;
return (sensor->capabilities & MGOS_BAROMETER_CAP_BAROMETER);
}
bool mgos_barometer_read(struct mgos_barometer *sensor) {
double start = mg_time();
bool ret = false;
if (!sensor) return false;
if (!sensor->read) return false;
sensor->stats.read++;
if (1000*(start - sensor->stats.last_read_time) < sensor->cache_ttl_ms) {
sensor->stats.read_success_cached++;
return true;
}
ret = sensor->read(sensor);
if (ret) {
sensor->stats.read_success++;
sensor->stats.read_success_usecs += 1000000 * (mg_time() - start);
sensor->stats.last_read_time = start;
}
return ret;
}
bool mgos_barometer_get_pressure(struct mgos_barometer *sensor, float *p) {
if (!mgos_barometer_has_barometer(sensor)) return false;
if (!mgos_barometer_read(sensor)) return false;
if (*p) *p=sensor->pressure;
return true;
}
bool mgos_barometer_get_temperature(struct mgos_barometer *sensor, float *t) {
if (!mgos_barometer_has_thermometer(sensor)) return false;
if (!mgos_barometer_read(sensor)) return false;
if (*t) *t=sensor->temperature;
return true;
}
bool mgos_barometer_set_cache_ttl(struct mgos_barometer *sensor, uint16_t msecs) {
if (!sensor) return false;
sensor->cache_ttl_ms = msecs;
return true;
}
bool mgos_barometer_get_stats(struct mgos_barometer *sensor, struct mgos_barometer_stats *stats) {
if (!sensor || !stats) {
return false;
}
memcpy((void *)stats, (const void *)&sensor->stats, sizeof(struct mgos_barometer_stats));
return true;
}
bool mgos_barometer_init(void) {
return true;
}
// Public functions end

View File

@ -1,142 +0,0 @@
#include "mgos_barometer_bme280.h"
#include "mgos_i2c.h"
// Datasheet:
// https://cdn-shop.adafruit.com/datasheets/BST-BME280_DS001-10.pdf
//
// TODO(pim): Add humidity sensing
bool mgos_barometer_bme280_detect(struct mgos_barometer *dev) {
int val;
if (!dev) {
return false;
}
if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, BME280_REG_DEVID)) < 0) {
return false;
}
if (val == 0x56 || val == 0x57) {
LOG(LL_INFO, ("Preproduction version of BMP280 detected (0x%02x)", val));
return true;
}
if (val == 0x58) { // Mass production BMP280
return true;
}
if (val == 0x60) { // Mass production BME280
dev->capabilities |= MGOS_BAROMETER_CAP_HYGROMETER;
return true;
}
return true;
}
bool mgos_barometer_bme280_create(struct mgos_barometer *dev) {
struct mgos_barometer_bme280_data *bme280_data;
if (!dev) {
return false;
}
bme280_data = calloc(1, sizeof(struct mgos_barometer_bme280_data));
if (!bme280_data) {
return false;
}
dev->user_data = bme280_data;
// Reset device
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_RESET, 0xB6)) {
return false;
}
mgos_usleep(10000);
// Read calibration data
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_TEMPERATURE_CALIB_DIG_T1_LSB, 24, (uint8_t *)bme280_data)) {
return false;
}
// SPI | 0.5ms period | 16X IIR filter
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CONFIG, 0x00 | BME280_STANDBY_500us << 2 | BME280_FILTER_16X << 5)) {
return false;
}
mgos_usleep(10000);
// Mode | Pressure OS | Temp OS
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, BME280_REG_CTRL_MEAS, BME280_MODE_NORMAL | BME280_OVERSAMP_16X << 2 | BME280_OVERSAMP_2X << 5)) {
return false;
}
dev->capabilities |= MGOS_BAROMETER_CAP_BAROMETER;
dev->capabilities |= MGOS_BAROMETER_CAP_THERMOMETER;
return true;
}
bool mgos_barometer_bme280_destroy(struct mgos_barometer *dev) {
if (!dev) {
return false;
}
if (dev->user_data) {
free(dev->user_data);
dev->user_data = NULL;
}
return true;
}
bool mgos_barometer_bme280_read(struct mgos_barometer *dev) {
struct mgos_barometer_bme280_data *bme280_data;
if (!dev) {
return false;
}
bme280_data = (struct mgos_barometer_bme280_data *)dev->user_data;
if (!bme280_data) {
return false;
}
// read data from sensor
uint8_t data[6];
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, BME280_REG_PRESSURE_MSB, 6, data)) {
return false;
}
int32_t Padc, Tadc;
Padc = (int32_t)((((uint32_t)(data[0])) << 12) | (((uint32_t)(data[1])) << 4) | ((uint32_t)data[2] >> 4));
Tadc = (int32_t)((((uint32_t)(data[3])) << 12) | (((uint32_t)(data[4])) << 4) | ((uint32_t)data[5] >> 4));
// LOG(LL_DEBUG, ("Padc=%d Tadc=%d", Padc, Tadc));
// Convert data (from datasheet, section 8.1)
double var1, var2, T, P;
int32_t t_fine;
// Compensation for temperature -- double precision
var1 = (((double)Tadc) / 16384.0 - ((double)bme280_data->calib.dig_T1) / 1024.0) * ((double)bme280_data->calib.dig_T2);
var2 = ((((double)Tadc) / 131072.0 - ((double)bme280_data->calib.dig_T1) / 8192.0) *
(((double)Tadc) / 131072.0 - ((double)bme280_data->calib.dig_T1) / 8192.0)) * ((double)bme280_data->calib.dig_T3);
t_fine = (int32_t)(var1 + var2);
T = (var1 + var2) / 5120.0;
dev->temperature = (float)T;
// Compensation for pressure -- double precision
var1 = ((double)t_fine / 2.0) - 64000.0;
var2 = var1 * var1 * ((double)bme280_data->calib.dig_P6) / 32768.0;
var2 = var2 + var1 * ((double)bme280_data->calib.dig_P5) * 2.0;
var2 = (var2 / 4.0) + (((double)bme280_data->calib.dig_P4) * 65536.0);
var1 = (((double)bme280_data->calib.dig_P3) * var1 * var1 / 524288.0 + ((double)bme280_data->calib.dig_P2) * var1) / 524288.0;
var1 = (1.0 + var1 / 32768.0) * ((double)bme280_data->calib.dig_P1);
if (var1 == 0.0) {
P = 0.0;
} else {
P = 1048576.0 - (double)Padc;
P = (P - (var2 / 4096.0)) * 6250.0 / var1;
var1 = ((double)bme280_data->calib.dig_P9) * P * P / 2147483648.0;
var2 = P * ((double)bme280_data->calib.dig_P8) / 32768.0;
P = P + (var1 + var2 + ((double)bme280_data->calib.dig_P7)) / 16.0;
}
dev->pressure = (float)P;
// LOG(LL_DEBUG, ("P=%.2f T=%.2f", dev->pressure, dev->temperature));
return true;
}

View File

@ -1,81 +0,0 @@
#pragma once
#include "mgos.h"
#include "mgos_barometer_internal.h"
// DevID: 0x56/0x57 are samples of BMP280; 0x58 is mass production BMP280; 0x60 is BME280
#define BME280_REG_DEVID (0xD0) /* Chip ID Register */
#define BME280_REG_RESET (0xE0) /* Softreset Register */
#define BME280_REG_STATUS (0xF3) /* Status Register */
#define BME280_REG_CTRL_MEAS (0xF4) /* Ctrl Measure Register */
#define BME280_REG_CONFIG (0xF5) /* Configuration Register */
#define BME280_REG_PRESSURE_MSB (0xF7) /* Pressure MSB Register */
#define BME280_REG_PRESSURE_LSB (0xF8) /* Pressure LSB Register */
#define BME280_REG_PRESSURE_XLSB (0xF9) /* Pressure XLSB Register */
#define BME280_REG_TEMPERATURE_MSB (0xFA) /* Temperature MSB Reg */
#define BME280_REG_TEMPERATURE_LSB (0xFB) /* Temperature LSB Reg */
#define BME280_REG_TEMPERATURE_XLSB (0xFC) /* Temperature XLSB Reg */
#define BME280_REG_HUMIDITY_MSB (0xFD) /* Humidity MSB Reg (BME280 only)*/
#define BME280_REG_HUMIDITY_LSB (0xFE) /* Humidity LSB Reg (BME280 only)*/
#define BME280_MODE_SLEEP (0x00)
#define BME280_MODE_FORCED (0x01)
#define BME280_MODE_NORMAL (0x03)
#define BME280_REG_TEMPERATURE_CALIB_DIG_T1_LSB (0x88)
#define BME280_OVERSAMP_SKIPPED (0x00)
#define BME280_OVERSAMP_1X (0x01)
#define BME280_OVERSAMP_2X (0x02)
#define BME280_OVERSAMP_4X (0x03)
#define BME280_OVERSAMP_8X (0x04)
#define BME280_OVERSAMP_16X (0x05)
#define BME280_STANDBY_500us (0x00)
#define BME280_STANDBY_62ms (0x01)
#define BME280_STANDBY_125ms (0x02)
#define BME280_STANDBY_250ms (0x03)
#define BME280_STANDBY_500ms (0x04)
#define BME280_STANDBY_1000ms (0x05)
// Note: Datasheet defines 110 == 10ms, 111 == 20ms, but BME280 and BMP280
// implement this differently.
#define BME280_FILTER_OFF (0x00)
#define BME280_FILTER_2X (0x01)
#define BME280_FILTER_4X (0x02)
#define BME280_FILTER_8X (0x03)
#define BME280_FILTER_16X (0x04)
struct mgos_barometer_bme280_calib_data {
// Calibration data:
uint16_t dig_T1;
int16_t dig_T2;
int16_t dig_T3;
uint16_t dig_P1;
int16_t dig_P2;
int16_t dig_P3;
int16_t dig_P4;
int16_t dig_P5;
int16_t dig_P6;
int16_t dig_P7;
int16_t dig_P8;
int16_t dig_P9;
// Additional calibration data for BME280
uint8_t dig_H1;
int16_t dig_H2;
uint8_t dig_H3;
int16_t dig_H4; // Note: this is 0xE4 / 0xE5[3:0]
int16_t dig_H5; // Note: this is 0xE5[7:4] / 0xE6
int8_t dig_H6;
};
struct mgos_barometer_bme280_data {
struct mgos_barometer_bme280_calib_data calib;
float humidity;
};
bool mgos_barometer_bme280_detect(struct mgos_barometer *dev);
bool mgos_barometer_bme280_create(struct mgos_barometer *dev);
bool mgos_barometer_bme280_destroy(struct mgos_barometer *dev);
bool mgos_barometer_bme280_read(struct mgos_barometer *dev);

View File

@ -1,59 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "mgos.h"
#include "mgos_barometer.h"
#ifdef __cplusplus
extern "C" {
#endif
// Barometer
typedef bool (*mgos_barometer_mag_detect_fn)(struct mgos_barometer *dev);
typedef bool (*mgos_barometer_mag_create_fn)(struct mgos_barometer *dev);
typedef bool (*mgos_barometer_mag_destroy_fn)(struct mgos_barometer *dev);
typedef bool (*mgos_barometer_mag_read_fn)(struct mgos_barometer *dev);
#define MGOS_BAROMETER_CAP_BAROMETER (0x01)
#define MGOS_BAROMETER_CAP_THERMOMETER (0x02)
#define MGOS_BAROMETER_CAP_HYGROMETER (0x04)
struct mgos_barometer {
struct mgos_i2c * i2c;
uint8_t i2caddr;
uint16_t cache_ttl_ms;
enum mgos_barometer_type type;
uint8_t capabilities;
mgos_barometer_mag_detect_fn detect;
mgos_barometer_mag_create_fn create;
mgos_barometer_mag_destroy_fn destroy;
mgos_barometer_mag_read_fn read;
void *user_data;
float pressure; // in Pascals
float temperature; // in Celcius
struct mgos_barometer_stats stats;
};
#ifdef __cplusplus
}
#endif

View File

@ -1,78 +0,0 @@
#include "mgos_barometer_mpl115.h"
#include "mgos_i2c.h"
// Datasheet:
// https://cdn-shop.adafruit.com/datasheets/MPL115A2.pdf
bool mgos_barometer_mpl115_create(struct mgos_barometer *dev) {
struct mgos_barometer_mpl115_data *mpl115_data;
if (!dev) return false;
uint8_t data[8];
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, MPL115_REG_COEFF_BASE, 8, data))
return false;
mpl115_data=calloc(1, sizeof(struct mgos_barometer_mpl115_data));
if (!mpl115_data) return false;
// TESTDATA:
// data[0]=0x3e; data[1]=0xce; data[2]=0xb3; data[3]=0xf9; data[4]=0xc5; data[5]=0x17; data[6]=0x33; data[7]=0xc8;
int16_t a0 = ((uint16_t) data[0] << 8) | data[1];
int16_t b1 = ((uint16_t) data[2] << 8) | data[3];
int16_t b2 = ((uint16_t) data[4] << 8) | data[5];
int16_t c12 = (((uint16_t) data[6] << 8) | data[7]) >> 2;
mpl115_data->a0=(float)a0/(1<<3);
mpl115_data->b1=(float)b1/(1<<13);
mpl115_data->b2=(float)b2/(1<<14);
mpl115_data->c12=(float)c12/(1<<22);
dev->user_data=mpl115_data;
dev->capabilities|=MGOS_BAROMETER_CAP_BAROMETER;
dev->capabilities|=MGOS_BAROMETER_CAP_THERMOMETER;
return true;
}
bool mgos_barometer_mpl115_destroy(struct mgos_barometer *dev) {
if (!dev) return false;
if (dev->user_data) {
free(dev->user_data);
dev->user_data=NULL;
}
return true;
}
bool mgos_barometer_mpl115_read(struct mgos_barometer *dev) {
struct mgos_barometer_mpl115_data *mpl115_data;
int16_t Padc, Tadc;
float Pcomp;
if (!dev) return false;
mpl115_data=(struct mgos_barometer_mpl115_data *) dev->user_data;
if (!mpl115_data) return false;
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL115_REG_START, 0x00))
return false;
mgos_usleep(4000);
uint8_t data[4];
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, MPL115_REG_PRESSURE, 4, data))
return false;
// TESTDATA:
// data[0]=0x66; data[1]=0x80; data[2]=0x7e; data[3]=0xc0;
Padc=(((uint16_t) data[0] << 8) | data[1]) >> 6;
Tadc=(((uint16_t) data[2] << 8) | data[3]) >> 6;
Pcomp=mpl115_data->a0 + (mpl115_data->b1 + mpl115_data->c12 * Tadc ) * Padc + mpl115_data->b2 * Tadc;
dev->pressure=(Pcomp*(65.0/1023) + 50.0)*1000; // Pascals
dev->temperature=((float) Tadc - 498.0F) / -5.35F +25.0F; // Celsius
/* TESTDATA (in mpl115_data and Padc/Tadc) yields:
* pressure=96587.33
* temperature=23.32
*/
return true;
}

View File

@ -1,17 +0,0 @@
#pragma once
#include "mgos.h"
#include "mgos_barometer_internal.h"
#define MPL115_REG_PRESSURE (0x00)
#define MPL115_REG_TEMPERATURE (0x02)
#define MPL115_REG_COEFF_BASE (0x04)
#define MPL115_REG_START (0x12)
struct mgos_barometer_mpl115_data {
float a0, b1, b2, c12;
};
bool mgos_barometer_mpl115_create(struct mgos_barometer *dev);
bool mgos_barometer_mpl115_destroy(struct mgos_barometer *dev);
bool mgos_barometer_mpl115_read(struct mgos_barometer *dev);

View File

@ -1,107 +0,0 @@
#include "mgos_barometer_mpl3115.h"
#include "mgos_i2c.h"
// Datasheet:
// https://cdn-shop.adafruit.com/datasheets/1893_datasheet.pdf
bool mgos_barometer_mpl3115_detect(struct mgos_barometer *dev) {
int val;
if (!dev) {
return false;
}
if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_WHOAMI)) < 0) {
return false;
}
if (val != 0xC4) {
return false;
}
return true;
}
bool mgos_barometer_mpl3115_create(struct mgos_barometer *dev) {
if (!dev) {
return false;
}
// Reset
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_CTRL1, 0x04)) {
return false;
}
mgos_usleep(20000);
// Set sample period to 1sec ST[3:0], period 2^ST seconds
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_CTRL2, 0x00)) {
return false;
}
// Set Barometer Mode, OS[2:0], oversampling 2^OS times, continuous sampling
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_CTRL1, 0x39)) {
return false;
}
// Set event flags for temp+pressure
if (!mgos_i2c_write_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_PT_DATA, 0x07)) {
return false;
}
dev->capabilities|=MGOS_BAROMETER_CAP_BAROMETER;
dev->capabilities|=MGOS_BAROMETER_CAP_THERMOMETER;
return true;
}
bool mgos_barometer_mpl3115_read(struct mgos_barometer *dev) {
if (!dev) {
return false;
}
int val = 0;
uint8_t retries=100;
if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_STATUS)) < 0)
return false;
while (!(val & 0x08) && retries>0) { // Data Ready
if ((val = mgos_i2c_read_reg_b(dev->i2c, dev->i2caddr, MPL3115_REG_STATUS)) < 0) {
return false;
}
mgos_usleep(10000);
// LOG(LL_DEBUG, ("Snoozing, retries=%d", retries));
retries--;
}
if (retries==0) {
LOG(LL_ERROR, ("Timed out waiting for data ready"));
return false;
}
uint32_t pressure;
int16_t temperature;
uint8_t data[5];
if (!mgos_i2c_read_reg_n(dev->i2c, dev->i2caddr, MPL3115_REG_PRESSURE_MSB, 5, data)) {
return false;
}
pressure = data[0];
pressure <<= 8;
pressure |= data[1];
pressure <<= 8;
pressure |= data[2];
pressure >>= 4;
temperature = data[3];
temperature <<= 8;
temperature |= data[4];
temperature >>= 4;
if (temperature & 0x800) {
temperature |= 0xF000;
}
dev->pressure = pressure / 4.0;
dev->temperature = temperature / 16.0;
return true;
}

View File

@ -1,20 +0,0 @@
#pragma once
#include "mgos.h"
#include "mgos_barometer_internal.h"
#define MPL3115_REG_STATUS (0x00)
#define MPL3115_REG_PRESSURE_MSB (0x01)
#define MPL3115_REG_PRESSURE_CSB (0x02)
#define MPL3115_REG_PRESSURE_LSB (0x03)
#define MPL3115_REG_TEMP_MSB (0x04)
#define MPL3115_REG_TEMP_LSB (0x05)
#define MPL3115_REG_DR_STATUS (0x06)
#define MPL3115_REG_WHOAMI (0x0C)
#define MPL3115_REG_PT_DATA (0x13)
#define MPL3115_REG_CTRL1 (0x26)
#define MPL3115_REG_CTRL2 (0x27)
bool mgos_barometer_mpl3115_detect(struct mgos_barometer *dev);
bool mgos_barometer_mpl3115_create(struct mgos_barometer *dev);
bool mgos_barometer_mpl3115_read(struct mgos_barometer *dev);

View File

@ -1,76 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "mgos.h"
#include "mgos_i2c.h"
#ifdef __cplusplus
extern "C" {
#endif
enum mgos_imu_acc_type {
ACC_NONE = 0,
ACC_MPU9250
};
enum mgos_imu_gyro_type {
GYRO_NONE = 0,
GYRO_MPU9250
};
enum mgos_imu_mag_type {
MAG_NONE = 0,
MAG_AK8963
};
struct mgos_imu;
struct mgos_imu *mgos_imu_create_i2c(struct mgos_i2c *i2c);
bool mgos_imu_add_gyroscope_i2c(struct mgos_imu *sensor, uint8_t i2caddr, enum mgos_imu_gyro_type type);
bool mgos_imu_add_accelerometer_i2c(struct mgos_imu *sensor, uint8_t i2caddr, enum mgos_imu_acc_type type);
bool mgos_imu_add_magnetometer_i2c(struct mgos_imu *sensor, uint8_t i2caddr, enum mgos_imu_mag_type type);
void mgos_imu_destroy(struct mgos_imu **sensor);
bool mgos_imu_has_accelerometer(struct mgos_imu *sensor);
bool mgos_imu_has_gyroscope(struct mgos_imu *sensor);
bool mgos_imu_has_magnetometer(struct mgos_imu *sensor);
/* Read all available sensor data from the IMU */
bool mgos_imu_read(struct mgos_imu *sensor);
/* Return accelerometer data in units of m/s/s */
bool mgos_imu_get_accelerometer(struct mgos_imu *sensor, float *x, float *y, float *z);
/* Return accelerometer data in units of deg/sec rotation rate */
bool mgos_imu_get_gyroscope(struct mgos_imu *sensor, float *x, float *y, float *z);
/* Return magnetometer data in units of microtesla (1 microtesla = 10 milligauss) */
bool mgos_imu_get_magnetometer(struct mgos_imu *sensor, float *x, float *y, float *z);
/* Return compass heading based on magnetometer data, from [0..359] */
bool mgos_imu_get_compass_heading(struct mgos_imu *sensor, uint16_t *heading);
/*
* Initialization function for MGOS -- currently a noop.
*/
bool mgos_imu_init(void);
#ifdef __cplusplus
}
#endif

View File

@ -1,56 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mgos.h"
#include "mgos_imu_internal.h"
// Private functions follow
// Private functions end
// Public functions follow
struct mgos_imu *mgos_imu_create_i2c(struct mgos_i2c *i2c) {
struct mgos_imu *sensor;
if (!i2c) {
return NULL;
}
sensor = calloc(1, sizeof(struct mgos_imu));
if (!sensor) {
return NULL;
}
memset(sensor, 0, sizeof(struct mgos_imu));
return sensor;
}
void mgos_imu_destroy(struct mgos_imu **sensor) {
if (!*sensor) {
return;
}
if ((*sensor)->gyro) mgos_imu_gyro_destroy(&((*sensor)->gyro));
if ((*sensor)->acc) mgos_imu_acc_destroy(&((*sensor)->acc));
if ((*sensor)->mag) mgos_imu_mag_destroy(&((*sensor)->mag));
free(*sensor);
*sensor = NULL;
return;
}
bool mgos_imu_init(void) {
return true;
}
// Public functions end

View File

@ -1,35 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mgos.h"
#include "mgos_imu_internal.h"
struct mgos_imu_acc *mgos_imu_acc_create(void) {
struct mgos_imu_acc *acc;
acc = calloc(1, sizeof(struct mgos_imu_acc));
if (!acc) return NULL;
memset(acc, 0, sizeof(struct mgos_imu_acc));
acc->type=ACC_NONE;
return acc;
}
bool mgos_imu_acc_destroy(struct mgos_imu_acc **acc) {
if (!*acc) return false;
free(*acc);
*acc=NULL;
return true;
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mgos.h"
#include "mgos_imu_internal.h"
struct mgos_imu_gyro *mgos_imu_gyro_create(void) {
struct mgos_imu_gyro *gyro;
gyro = calloc(1, sizeof(struct mgos_imu_gyro));
if (!gyro) return NULL;
memset(gyro, 0, sizeof(struct mgos_imu_gyro));
gyro->type=GYRO_NONE;
return gyro;
}
bool mgos_imu_gyro_destroy(struct mgos_imu_gyro **gyro) {
if (!*gyro) return false;
free(*gyro);
*gyro=NULL;
return true;
}

View File

@ -1,103 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "mgos.h"
#include "mgos_imu.h"
#ifdef __cplusplus
extern "C" {
#endif
struct mgos_imu_mag;
struct mgos_imu_acc;
struct mgos_imu_gyro;
struct mgos_imu {
struct mgos_imu_mag * mag;
struct mgos_imu_acc * acc;
struct mgos_imu_gyro *gyro;
};
// Magnetometer
typedef bool (*mgos_imu_mag_detect_fn)(struct mgos_imu_mag *dev);
typedef bool (*mgos_imu_mag_start_fn)(struct mgos_imu_mag *dev);
typedef bool (*mgos_imu_mag_read_fn)(struct mgos_imu_mag *dev);
struct mgos_imu_mag {
mgos_imu_mag_detect_fn detect;
mgos_imu_mag_start_fn start;
mgos_imu_mag_read_fn read;
struct mgos_i2c * i2c;
uint8_t i2caddr;
enum mgos_imu_mag_type type;
float gain[3];
int16_t data[3];
};
struct mgos_imu_mag *mgos_imu_mag_create(void);
bool mgos_imu_mag_destroy(struct mgos_imu_mag **mag);
// Accelerometer
typedef bool (*mgos_imu_acc_detect_fn)(struct mgos_imu_acc *dev);
typedef bool (*mgos_imu_acc_start_fn)(struct mgos_imu_acc *dev);
typedef bool (*mgos_imu_acc_read_fn)(struct mgos_imu_acc *dev);
struct mgos_imu_acc {
mgos_imu_acc_detect_fn detect;
mgos_imu_acc_start_fn start;
mgos_imu_acc_read_fn read;
struct mgos_i2c * i2c;
uint8_t i2caddr;
enum mgos_imu_acc_type type;
float scale;
int16_t data[3];
};
struct mgos_imu_acc *mgos_imu_acc_create(void);
bool mgos_imu_acc_destroy(struct mgos_imu_acc **acc);
// Gyroscope
typedef bool (*mgos_imu_gyro_detect_fn)(struct mgos_imu_gyro *dev);
typedef bool (*mgos_imu_gyro_start_fn)(struct mgos_imu_gyro *dev);
typedef bool (*mgos_imu_gyro_read_fn)(struct mgos_imu_gyro *dev);
struct mgos_imu_gyro {
mgos_imu_gyro_detect_fn detect;
mgos_imu_gyro_start_fn start;
mgos_imu_gyro_read_fn read;
struct mgos_i2c * i2c;
uint8_t i2caddr;
enum mgos_imu_gyro_type type;
float scale;
float bias[3];
int16_t data[3];
int16_t temperature;
};
struct mgos_imu_gyro *mgos_imu_gyro_create(void);
bool mgos_imu_gyro_destroy(struct mgos_imu_gyro **gyro);
#ifdef __cplusplus
}
#endif

View File

@ -1,35 +0,0 @@
/*
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mgos.h"
#include "mgos_imu_internal.h"
struct mgos_imu_mag *mgos_imu_mag_create(void) {
struct mgos_imu_mag *mag;
mag = calloc(1, sizeof(struct mgos_imu_mag));
if (!mag) return NULL;
memset(mag, 0, sizeof(struct mgos_imu_mag));
mag->type=MAG_NONE;
return mag;
}
bool mgos_imu_mag_destroy(struct mgos_imu_mag **mag) {
if (!*mag) return false;
free(*mag);
*mag=NULL;
return true;
}