summaryrefslogtreecommitdiff
path: root/components/drivers
diff options
context:
space:
mode:
authorArda <[email protected]>2015-03-10 12:01:25 +0800
committerArda <[email protected]>2015-03-10 12:01:25 +0800
commit4a9c3fae2900da71cdf026063679d2c25f266fd7 (patch)
tree2fba8aec09a671cc36d281365351003a988eb57d /components/drivers
parent5fe489a3949cdbb947d3c719a7ef958a37e8d826 (diff)
parent89ceb7dc27895225bc221d22c035d5cc8802a256 (diff)
Merge pull request #3 from RT-Thread/master
sync with official source
Diffstat (limited to 'components/drivers')
-rw-r--r--components/drivers/include/drivers/pin.h79
-rw-r--r--components/drivers/include/rtdevice.h4
-rw-r--r--components/drivers/misc/SConscript14
-rw-r--r--components/drivers/misc/pin.c118
-rw-r--r--components/drivers/sensors/SConscript9
-rw-r--r--components/drivers/sensors/bmi055_sensor.cpp455
-rw-r--r--components/drivers/sensors/bmi055_sensor.h338
-rw-r--r--components/drivers/sensors/mpu6050_sensor.cpp462
-rw-r--r--components/drivers/sensors/mpu6050_sensor.h193
-rw-r--r--components/drivers/sensors/sensor.cpp169
-rw-r--r--components/drivers/sensors/sensor.h181
-rw-r--r--components/drivers/serial/serial.c3
-rw-r--r--components/drivers/src/ringbuffer.c10
13 files changed, 1961 insertions, 74 deletions
diff --git a/components/drivers/include/drivers/pin.h b/components/drivers/include/drivers/pin.h
new file mode 100644
index 0000000000..704114cf99
--- /dev/null
+++ b/components/drivers/include/drivers/pin.h
@@ -0,0 +1,79 @@
+/*
+ * File : pin.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2015, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-01-20 Bernard the first version
+ */
+
+#ifndef PIN_H__
+#define PIN_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* pin device and operations for RT-Thread */
+struct rt_device_pin
+{
+ struct rt_device parent;
+ const struct rt_pin_ops *ops;
+};
+
+#define PIN_LOW 0x00
+#define PIN_HIGH 0x01
+
+#define PIN_MODE_OUTPUT 0x00
+#define PIN_MODE_INPUT 0x01
+#define PIN_MODE_INPUT_PULLUP 0x02
+
+struct rt_device_pin_mode
+{
+ rt_uint16_t pin;
+ rt_uint16_t mode;
+};
+struct rt_device_pin_status
+{
+ rt_uint16_t pin;
+ rt_uint16_t status;
+};
+
+struct rt_pin_ops
+{
+ void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
+ void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);
+ int (*pin_read)(struct rt_device *device, rt_base_t pin);
+
+ /* TODO: add GPIO interrupt */
+};
+
+int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data);
+
+void rt_pin_mode(rt_base_t pin, rt_base_t mode);
+void rt_pin_write(rt_base_t pin, rt_base_t value);
+int rt_pin_read(rt_base_t pin);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/include/rtdevice.h b/components/drivers/include/rtdevice.h
index dc9761032e..bb01da2d12 100644
--- a/components/drivers/include/rtdevice.h
+++ b/components/drivers/include/rtdevice.h
@@ -358,5 +358,9 @@ rt_inline void rt_work_init(struct rt_work* work, void (*work_func)(struct rt_wo
#include "drivers/watchdog.h"
#endif
+#ifdef RT_USING_PIN
+#include "drivers/pin.h"
+#endif
+
#endif /* __RT_DEVICE_H__ */
diff --git a/components/drivers/misc/SConscript b/components/drivers/misc/SConscript
new file mode 100644
index 0000000000..7f269d4ee9
--- /dev/null
+++ b/components/drivers/misc/SConscript
@@ -0,0 +1,14 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = []
+CPPPATH = [cwd + '/../include']
+group = []
+
+if GetDepend(['RT_USING_PIN']):
+ src = src + ['pin.c']
+
+if len(src):
+ group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/components/drivers/misc/pin.c b/components/drivers/misc/pin.c
new file mode 100644
index 0000000000..d83c3d2f03
--- /dev/null
+++ b/components/drivers/misc/pin.c
@@ -0,0 +1,118 @@
+/*
+ * File : pin.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2015, RT-Thread Development Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-01-20 Bernard the first version
+ */
+
+#include <drivers/pin.h>
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+#endif
+
+static struct rt_device_pin _hw_pin;
+static rt_size_t _pin_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+ struct rt_device_pin_status *status;
+ struct rt_device_pin *pin = (struct rt_device_pin *)dev;
+
+ /* check parameters */
+ RT_ASSERT(pin != RT_NULL);
+
+ status = (struct rt_device_pin_status *) buffer;
+ if (status == RT_NULL || size != sizeof(*status)) return 0;
+
+ status->status = pin->ops->pin_read(dev, status->pin);
+ return size;
+}
+
+static rt_size_t _pin_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+ struct rt_device_pin_status *status;
+ struct rt_device_pin *pin = (struct rt_device_pin *)dev;
+
+ /* check parameters */
+ RT_ASSERT(pin != RT_NULL);
+
+ status = (struct rt_device_pin_status *) buffer;
+ if (status == RT_NULL || size != sizeof(*status)) return 0;
+
+ pin->ops->pin_write(dev, (rt_base_t)status->pin, (rt_base_t)status->status);
+
+ return size;
+}
+
+static rt_err_t _pin_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+{
+ struct rt_device_pin_mode *mode;
+ struct rt_device_pin *pin = (struct rt_device_pin *)dev;
+
+ /* check parameters */
+ RT_ASSERT(pin != RT_NULL);
+
+ mode = (struct rt_device_pin_mode *) args;
+ if (mode == RT_NULL) return -RT_ERROR;
+
+ pin->ops->pin_mode(dev, (rt_base_t)mode->pin, (rt_base_t)mode->mode);
+
+ return 0;
+}
+
+int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data)
+{
+ _hw_pin.parent.type = RT_Device_Class_Miscellaneous;
+ _hw_pin.parent.rx_indicate = RT_NULL;
+ _hw_pin.parent.tx_complete = RT_NULL;
+
+ _hw_pin.parent.init = RT_NULL;
+ _hw_pin.parent.open = RT_NULL;
+ _hw_pin.parent.close = RT_NULL;
+ _hw_pin.parent.read = _pin_read;
+ _hw_pin.parent.write = _pin_write;
+ _hw_pin.parent.control = _pin_control;
+
+ _hw_pin.ops = ops;
+ _hw_pin.parent.user_data = user_data;
+
+ /* register a character device */
+ rt_device_register(&_hw_pin.parent, "pin", RT_DEVICE_FLAG_RDWR);
+
+ return 0;
+}
+
+/* RT-Thread Hardware PIN APIs */
+void rt_pin_mode(rt_base_t pin, rt_base_t mode)
+{
+ _hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode);
+}
+FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_mode, pinMode, set hardware pin mode);
+
+void rt_pin_write(rt_base_t pin, rt_base_t value)
+{
+ _hw_pin.ops->pin_write(&_hw_pin.parent, pin, value);
+}
+FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_write, pinWrite, write value to hardware pin);
+
+int rt_pin_read(rt_base_t pin)
+{
+ return _hw_pin.ops->pin_read(&_hw_pin.parent, pin);
+}
+FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_read, pinRead, read status from hardware pin);
diff --git a/components/drivers/sensors/SConscript b/components/drivers/sensors/SConscript
index 14a7cd2450..db409cfd2b 100644
--- a/components/drivers/sensors/SConscript
+++ b/components/drivers/sensors/SConscript
@@ -3,10 +3,15 @@
from building import *
cwd = GetCurrentDir()
-src = Glob('*.c') + Glob('*.cpp')
+src = ['sensor.cpp']
CPPPATH = [cwd, cwd + '/../include']
+if GetDepend('SENSOR_USING_MPU6050') and GetDepend('RT_USING_I2C'):
+ src += ['mpu6050_sensor.cpp'];
+
+if GetDepend('SENSOR_USING_BMI055') and GetDepend('RT_USING_I2C'):
+ src += ['bmi055_sensor.cpp']
+
group = DefineGroup('Sensors', src, depend = ['RT_USING_SENSOR', 'RT_USING_DEVICE'], CPPPATH = CPPPATH)
Return('group')
-
diff --git a/components/drivers/sensors/bmi055_sensor.cpp b/components/drivers/sensors/bmi055_sensor.cpp
new file mode 100644
index 0000000000..705895f368
--- /dev/null
+++ b/components/drivers/sensors/bmi055_sensor.cpp
@@ -0,0 +1,455 @@
+/*
+ * File : bmi055_sensor.cpp
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2014, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-1-11 RT_learning the first version
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rtdevice.h>
+#include "bmi055_sensor.h"
+
+
+const static sensor_t _BMI055_sensor[] =
+{
+ {
+ .name = "Accelerometer",
+ .vendor = "Bosch",
+ .version = sizeof(sensor_t),
+ .handle = 0,
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .maxRange = SENSOR_ACCEL_RANGE_16G,
+ .resolution = 1.0f,
+ .power = 0.5f,
+ .minDelay = 10000,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 64,
+ },
+ {
+ .name = "Gyroscope",
+ .vendor = "Bosch",
+ .version = sizeof(sensor_t),
+ .handle = 0,
+ .type = SENSOR_TYPE_GYROSCOPE,
+ .maxRange = SENSOR_GYRO_RANGE_2000DPS,
+ .resolution = 1.0f,
+ .power = 0.5f,
+ .minDelay = 10000,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 64,
+ }
+};
+
+BMI055::BMI055(int sensor_type, const char* iic_bus, int addr)
+ : SensorBase(sensor_type)
+{
+ this->i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(iic_bus);
+ if (this->i2c_bus == NULL)
+ {
+ printf("BMI055: No IIC device:%s\n", iic_bus);
+ return;
+ }
+
+ this->i2c_addr = addr;
+
+ /* register to sensor manager */
+ SensorManager::registerSensor(this);
+}
+
+int BMI055::read_reg(rt_uint8_t reg, rt_uint8_t *value)
+{
+ struct rt_i2c_msg msgs[2];
+
+ msgs[0].addr = this->i2c_addr;
+ msgs[0].flags = RT_I2C_WR;
+ msgs[0].buf = &reg;
+ msgs[0].len = 1;
+
+ msgs[1].addr = this->i2c_addr;
+ msgs[1].flags = RT_I2C_RD; /* Read from slave */
+ msgs[1].buf = (rt_uint8_t *)value;
+ msgs[1].len = 1;
+
+ if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
+ return RT_EOK;
+
+ return -RT_ERROR;
+}
+
+int BMI055::read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size)
+{
+ struct rt_i2c_msg msgs[2];
+
+ msgs[0].addr = this->i2c_addr;
+ msgs[0].flags = RT_I2C_WR;
+ msgs[0].buf = &reg;
+ msgs[0].len = 1;
+
+ msgs[1].addr = this->i2c_addr;
+ msgs[1].flags = RT_I2C_RD; /* Read from slave */
+ msgs[1].buf = (rt_uint8_t *)value;
+ msgs[1].len = size;
+
+ if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
+ return RT_EOK;
+
+ return -RT_ERROR;
+}
+
+int BMI055::write_reg(rt_uint8_t reg, rt_uint8_t value)
+{
+ struct rt_i2c_msg msgs[2];
+
+ msgs[0].addr = this->i2c_addr;
+ msgs[0].flags = RT_I2C_WR;
+ msgs[0].buf = &reg;
+ msgs[0].len = 1;
+
+ msgs[1].addr = this->i2c_addr;
+ msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START;
+ msgs[1].buf = (rt_uint8_t *)&value;
+ msgs[1].len = 1;
+
+ if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
+ return RT_EOK;
+
+ return -RT_ERROR;
+}
+
+
+BMI055_Accelerometer::BMI055_Accelerometer(const char* iic_name, int addr)
+ : BMI055(SENSOR_TYPE_ACCELEROMETER, iic_name, addr)
+{
+ int index;
+ uint8_t id;
+ rt_uint8_t value[6] = {0};
+ rt_int32_t x, y, z;
+ SensorConfig config = {SENSOR_MODE_NORMAL, SENSOR_DATARATE_400HZ, SENSOR_ACCEL_RANGE_2G};
+
+ write_reg(BMI055_BGW_SOFTRESET, 0xB6); /* reset of the sensor P57 */
+ write_reg(BMI055_PMU_LPW, 0x00); /* PMU_LPW NORMAL mode P55 */
+ write_reg(BMI055_PMU_BW, 0x0A); /* 01010b 31.25 Hz P55 */
+ write_reg(BMI055_PMU_RANGE, 0x05); /* 0101b ±4g range PMU_RANGE set acc +-4g/s P54 */
+
+
+ x_offset = y_offset = z_offset = 0;
+ x = y = z = 0;
+
+ /* read BMI055 id */
+ read_buffer(BMI055_ACC_BGW_CHIPID, &id, 1); /* BGW_CHIPID P47*/
+ if (id != BMI055_ACC_BGW_CHIPID_VALUE)
+ {
+ printf("Warning: not found BMI055 id: %02x\n", id);
+ }
+
+ /* get offset */
+ for (index = 0; index < 200; index ++)
+ {
+ read_buffer(BMI055_ACCD_X_LSB, value, 6); /*ACCD_X_LSB P47 */
+
+ x += (((rt_int16_t)value[1] << 8) | value[0]);
+ y += (((rt_int16_t)value[3] << 8) | value[2]);
+ z += (((rt_int16_t)value[5] << 8) | value[4]);
+ }
+ x_offset = x / 200;
+ y_offset = y / 200;
+ z_offset = z / 200;
+
+ this->enable = RT_FALSE;
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
+ this->config = config;
+}
+
+int
+BMI055_Accelerometer::configure(SensorConfig *config)
+{
+ int range;
+ uint8_t value;
+
+ if (config == RT_NULL) return -1;
+
+ /* TODO: set datarate */
+
+ /* get range and calc the sensitivity */
+ range = config->range.accel_range;
+ switch (range)
+ {
+ case SENSOR_ACCEL_RANGE_2G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
+ range = 0x03; //0011b
+ break;
+ case SENSOR_ACCEL_RANGE_4G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_4G;
+ range = 0x05; //0101b
+ break;
+ case SENSOR_ACCEL_RANGE_8G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_8G;
+ range = 0x01 << 3; //1000b
+ break;
+ case SENSOR_ACCEL_RANGE_16G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_16G;
+ range = 0x03 << 2; //1100b
+ break;
+ default:
+ return -1;
+ }
+
+ /* set range to sensor */
+ read_reg(BMI055_PMU_RANGE, &value); /* PMU_RANGE P54 */
+ value &= 0xF0;
+ value |= range;
+ write_reg(BMI055_PMU_RANGE, value);
+
+ return 0;
+}
+
+int
+BMI055_Accelerometer::activate(int enable)
+{
+ uint8_t value;
+
+ if (enable && this->enable == RT_FALSE)
+ {
+ /* enable accelerometer */
+ read_reg(BMI055_PMU_LPW, &value); /* P55 */
+ value &= ~(0x07 << 7);
+ write_reg(BMI055_PMU_LPW, value);
+ }
+
+ if (!enable && this->enable == RT_TRUE)
+ {
+ /* disable accelerometer */
+ read_reg(BMI055_PMU_LPW, &value);
+ value &= ~(0x07 << 7);
+ value |= (0x01 << 7);
+ write_reg(BMI055_PMU_LPW, value);
+ }
+
+ if (enable) this->enable = RT_TRUE;
+ else this->enable = RT_FALSE;
+
+ return 0;
+}
+
+int
+BMI055_Accelerometer::poll(sensors_event_t *event)
+{
+ rt_uint8_t value[6];
+ rt_int16_t x, y, z;
+
+ /* parameters check */
+ if (event == NULL) return -1;
+
+ /* get event data */
+ event->version = sizeof(sensors_event_t);
+ event->sensor = (int32_t) this;
+ event->timestamp = rt_tick_get();
+ event->type = SENSOR_TYPE_ACCELEROMETER;
+
+ read_buffer(0x02, value, 6);
+
+ /* get raw data */
+ x = (((rt_int16_t)value[1] << 8) | value[0]);
+ y = (((rt_int16_t)value[3] << 8) | value[2]);
+ z = (((rt_int16_t)value[5] << 8) | value[4]);
+
+ if (config.mode == SENSOR_MODE_RAW)
+ {
+ event->raw_acceleration.x = x;
+ event->raw_acceleration.y = y;
+ event->raw_acceleration.z = z;
+ }
+ else
+ {
+
+ x -= x_offset; y -= y_offset; z -= z_offset;
+ event->acceleration.x = x * this->sensitivity * SENSORS_GRAVITY_STANDARD;
+ event->acceleration.y = y * this->sensitivity * SENSORS_GRAVITY_STANDARD;
+ event->acceleration.z = z * this->sensitivity * SENSORS_GRAVITY_STANDARD;
+ }
+
+ return 0;
+}
+
+void
+BMI055_Accelerometer::getSensor(sensor_t *sensor)
+{
+ /* get sensor description */
+ if (sensor)
+ {
+ memcpy(sensor, &_BMI055_sensor[0], sizeof(sensor_t));
+ }
+}
+
+BMI055_Gyroscope::BMI055_Gyroscope(const char* iic_name, int addr)
+ : BMI055(SENSOR_TYPE_GYROSCOPE, iic_name, addr)
+{
+ int index;
+ uint8_t id;
+ rt_uint8_t value[6];
+ rt_int32_t x, y, z;
+
+ /* initialize BMI055 */
+ write_reg(BMI055_MODE_LPM1_ADDR, 0x00); /* normal mode */
+ write_reg(BMI055_MODE_LPM2_ADDR, 0x80); /* fast powerup */
+ write_reg(BMI055_BW_ADDR, 0x03); /* ODR:400Hz Filter Bandwidth:47Hz */
+ write_reg(BMI055_RANGE_ADDR, 0x00); /* 2000dps */
+
+
+ x_offset = y_offset = z_offset = 0;
+ x = y = z = 0;
+
+ /* read BMI055 id */
+ read_buffer(BMI055_CHIP_ID_ADDR, &id, 1);
+ if (id != BMI055_GRRO_CHIP_ID)
+ {
+ printf("Warning: not found BMI055 id: %02x\n", id);
+ }
+
+ /* get offset */
+ for (index = 0; index < 200; index ++)
+ {
+ read_buffer(BMI055_RATE_X_LSB_ADDR, value, 6);
+
+ x += (((rt_int16_t)value[1] << 8) | value[0]);
+ y += (((rt_int16_t)value[3] << 8) | value[2]);
+ z += (((rt_int16_t)value[5] << 8) | value[4]);
+ }
+ x_offset = x / 200;
+ y_offset = y / 200;
+ z_offset = z / 200;
+
+ this->enable = RT_FALSE;
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
+}
+
+int
+BMI055_Gyroscope::configure(SensorConfig *config)
+{
+ int range;
+ uint8_t value;
+
+ if (config == RT_NULL) return -1;
+
+ /* TODO: set datarate */
+
+ /* get range and calc the sensitivity */
+ range = config->range.gyro_range;
+ switch (range)
+ {
+ //to do add more range e.g 125DPS
+ //case
+ case SENSOR_GYRO_RANGE_250DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
+ range = 0x11;
+ break;
+ case SENSOR_GYRO_RANGE_500DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_500DPS;
+ range = 0x10;
+ break;
+ case SENSOR_GYRO_RANGE_1000DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_1000DPS;
+ range = 0x01;
+ break;
+ case SENSOR_GYRO_RANGE_2000DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_2000DPS;
+ range = 0x00;
+ break;
+ default:
+ return -1;
+ }
+
+ /* set range to sensor */
+ read_reg(BMI055_RANGE_ADDR, &value);
+ value &= ~0x07;
+ value |= range;
+ write_reg(BMI055_RANGE_ADDR, value);
+
+ return 0;
+}
+
+int
+BMI055_Gyroscope::activate(int enable)
+{
+ uint8_t value;
+
+ if (enable && this->enable == RT_FALSE)
+ {
+ /* enable gyroscope */
+ read_reg(BMI055_MODE_LPM1_ADDR, &value);
+ value &= ~(0x1010 << 4); //{0; 0} NORMAL mode
+ write_reg(BMI055_MODE_LPM1_ADDR, value); //P101 NORMAL mode
+ }
+
+ if (!enable && this->enable == RT_TRUE)
+ {
+ /* disable gyroscope */
+ read_reg(BMI055_MODE_LPM1_ADDR, &value);
+ value &= ~(0x01 << 5); //set bit5 deep_suspend 0
+ value |= (0x01 << 7); //set bit1 suspend 1
+ write_reg(BMI055_MODE_LPM1_ADDR, value); //{1; 0} SUSPEND mode
+ }
+
+ if (enable) this->enable = RT_TRUE;
+ else this->enable = RT_FALSE;
+
+ return 0;
+}
+
+int
+BMI055_Gyroscope::poll(sensors_event_t *event)
+{
+ rt_uint8_t value[6];
+ rt_int16_t x, y, z;
+
+ /* parameters check */
+ if (event == NULL) return -1;
+
+ /* get event data */
+ event->version = sizeof(sensors_event_t);
+ event->sensor = (int32_t) this;
+ event->timestamp = rt_tick_get();
+ event->type = SENSOR_TYPE_GYROSCOPE;
+
+ read_buffer(BMI055_RATE_X_LSB_ADDR, value, 6);
+
+ /* get raw data */
+ x = (((rt_int16_t)value[1] << 8) | value[0]);
+ y = (((rt_int16_t)value[3] << 8) | value[2]);
+ z = (((rt_int16_t)value[5] << 8) | value[4]);
+
+
+ if (config.mode == SENSOR_MODE_RAW)
+ {
+ event->raw_gyro.x = x;
+ event->raw_gyro.y = y;
+ event->raw_gyro.z = z;
+ }
+ else
+ {
+ x -= x_offset; y -= y_offset; z -= z_offset;
+ event->gyro.x = x * this->sensitivity * SENSORS_DPS_TO_RADS;
+ event->gyro.y = y * this->sensitivity * SENSORS_DPS_TO_RADS;
+ event->gyro.z = z * this->sensitivity * SENSORS_DPS_TO_RADS;
+ }
+
+ return 0;
+}
+
+void
+BMI055_Gyroscope::getSensor(sensor_t *sensor)
+{
+ /* get sensor description */
+ if (sensor)
+ {
+ memcpy(sensor, &_BMI055_sensor[1], sizeof(sensor_t));
+ }
+}
diff --git a/components/drivers/sensors/bmi055_sensor.h b/components/drivers/sensors/bmi055_sensor.h
new file mode 100644
index 0000000000..7ec6d9e5cf
--- /dev/null
+++ b/components/drivers/sensors/bmi055_sensor.h
@@ -0,0 +1,338 @@
+/*
+ * File : bmi055_sensor.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2014, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2015-1-11 RT_learning the first version
+ */
+#ifndef __BMI055_H__
+#define __BMI055_H__
+
+#include <sensor.h>
+
+/**************************************************************************************************/
+/************************************Register map accelerometer************************************/
+
+#define BMI055_ACC_I2C_ADDR1 0x18 //SDO is low(GND)
+#define BMI055_ACC_I2C_ADDR2 0x19 //SDO is high(VCC)
+
+#define BMI055_ACC_DEFAULT_ADDRESS BMI055_ACC_I2C_ADDR2 //in the LPC54102 SPM-S
+
+#define BMI055_ACC_BGW_CHIPID_VALUE 0xFA
+
+#define BMI055_ACC_BGW_CHIPID 0x00
+/**<Address of ACC Chip ID Register */
+#define BMI055_ACCD_X_LSB 0x02
+/**< Address of X axis ACC LSB Register */
+#define BMI055_ACCD_X_MSB 0x03
+/**< Address of X axis ACC MSB Register */
+#define BMI055_ACCD_Y_LSB 0x04
+/**< Address of Y axis ACC LSB Register */
+#define BMI055_ACCD_Y_MSB 0x05
+/**< Address of Y axis ACC MSB Register */
+#define BMI055_ACCD_Z_LSB 0x06
+/**< Address of Z axis ACC LSB Register */
+#define BMI055_ACCD_Z_MSB 0x07
+/**< Address of Z axis ACC MSB Register */
+#define BMI055_ACCD_TEMP 0x08
+/**< Address of Temperature Data Register */
+
+/* Status Register */
+#define BMI055_INT_STATUS_0 0x09
+/**< Address of Interrupt status Register 0 */
+#define BMI055_INT_STATUS_1 0x0A
+/**< Address of Interrupt status Register 1 */
+#define BMI055_INT_STATUS_2 0x0B
+/**< Address of Interrupt status Register 2 */
+#define BMI055_INT_STATUS_3 0x0C
+/**< Address of Interrupt status Register 3 */
+#define BMI055_FIFO_STATUS 0x0E
+/**< Address of FIFO status Register */
+
+/* Control Register */
+#define BMI055_PMU_RANGE 0x0F
+/**< Address of Range address Register */
+#define BMI055_PMU_BW 0x10
+/**< Address of Bandwidth Register */
+#define BMI055_PMU_LPW 0x11
+/**< Address of PMU LPW */
+#define BMI055_PMU_LOW_POWER 0x12
+/**< Address of PMU LOW POWER */
+#define BMI055_ACCD_HBW 0x13
+/**< Address of ACCD HBW */
+#define BMI055_BGW_SOFTRESET 0x14
+/**< Address of BGW SOFTRESET */
+#define BMI055_INT_EN_0 0x16
+/**< Address of interrupt engines in group 0 */
+#define BMI055_INT_EN_1 0x17
+/**< Address of interrupt engines in group 1 */
+#define BMI055_INT_EN_2 0x18
+/**< Address of interrupt engines in group 2 */
+#define BMI055_INT_MAP_0 0x19
+/**< Address of Interrupt MAP 0 */
+#define BMI055_INT_MAP_1 0x1A
+/**< Address of Interrupt MAP 1 */
+#define BMI055_INT_MAP_2 0x1B
+/**< Address of Interrupt MAP 2 */
+#define BMI055_INT_SRC 0x1E
+/**< Address of Interrupt source */
+#define BMI055_INT_OUT_CTRL 0x20
+/**< Address of Interrupt Register */
+#define BMI055_INT_RST_LATCH 0x21
+/**< Address of Interrupt reset and mode Register */
+#define BMI055_INT_0 0x22
+/**< Address of low-g Interrupt delay time Register */
+#define BMI055_INT_1 0x23
+/**< Address of low-g Interrupt threshold Register */
+#define BMI055_INT_2 0x24
+/**< Address of Interrupt 2 Register */
+#define BMI055_INT_3 0x25
+/**< Address of high-g Interrupt delay time Register */
+#define BMI055_INT_4 0x26
+/**< Address of high-g Interrupt threshold Register */
+#define BMI055_INT_5 0x27
+/**< Address of high-g Interrupt 5 Register */
+#define BMI055_INT_6 0x28
+/**< Address of any-motion Interrupt threshold Register */
+#define BMI055_INT_7 0x29
+/**< Address of slow/no-motion interrupt threshold Register */
+#define BMI055_INT_8 0x2A
+/**< Address of high-g Interrupt 8 Register */
+#define BMI055_INT_9 0x2B
+/**< Address of high-g Interrupt 9 Register */
+#define BMI055_INT_A 0x2C
+/**< Address of Interrupt A Register */
+#define BMI055_INT_B 0x2D
+/**< Address of Interrupt B Register */
+#define BMI055_INT_C 0x2E
+/**< Address of Interrupt C Register */
+#define BMI055_INT_D 0x2F
+/**< Address of Interrupt D Register */
+#define BMI055_FIFO_CONFIG_0 0x30
+/**< Address of FIFO CONFIG 0 Register */
+#define BMI055_PMU_SELF_TEST 0x32
+/**< Address of PMU SELF TEST Register */
+#define BMI055_TRIM_NVM_CTRL 0x33
+/**< Address of TRIM NVM CTRL Register */
+#define BMI055_BGW_SPI3_WDT 0x34
+/**< Address of BGW SPI3 WDT Register */
+#define BMI055_OFC_CTRL 0x36
+/**< Address of OFC CTRL Register */
+#define BMI055_OFC_SETTING 0x37
+/**< Address of OFC SETTING Register */
+#define BMI055_OFC_OFFSET_X 0x38
+/**< Address of OFC OFFSET X Register */
+#define BMI055_OFC_OFFSET_Y 0x39
+/**< Address of OFC OFFSET Y Register */
+#define BMI055_OFC_OFFSET_Z 0x3A
+/**< Address of OFC OFFSET Z Register */
+
+/* Trim Register */
+#define BMI055_TRIM_GP0 0x3B
+/**< Address of TRIM GP0 Register */
+#define BMI055_TRIM_GP1 0x3C
+/**< Address of TRIM GP1 Register */
+
+/* Control Register */
+#define BMI055_FIFO_CONFIG_1 0x3E
+/**< Address of FIFO CONFIG 1 Register */
+
+/* Data Register */
+#define BMI055_FIFO_DATA 0x3F
+/**< Address of FIFO DATA Register */
+
+
+/**************************************************************************************************/
+
+
+
+
+/**************************************************************************************************/
+/************************************Register map gyroscope****************************************/
+
+
+/**< This refers BMI055 return type as signed */
+
+// #define BMI055_I2C_ADDR1 0x68 //SDO is low(GND)
+// #define BMI055_I2C_ADDR2 0x69 //SDO is high(VCC)
+#define BMI055_GYRO_I2C_ADDR1 0x68 //SDO is low(GND)
+#define BMI055_GYRO_I2C_ADDR2 0x69 //SDO is high(VCC)
+
+#define BMI055_GYRO_DEFAULT_ADDRESS BMI055_GYRO_I2C_ADDR2
+
+#define BMI055_GRRO_CHIP_ID 0x0F
+
+/*Define of registers*/
+
+/* Hard Wired */
+#define BMI055_CHIP_ID_ADDR 0x00
+/**<Address of Chip ID Register*/
+
+/* Data Register */
+#define BMI055_RATE_X_LSB_ADDR 0x02
+/**< Address of X axis Rate LSB Register */
+#define BMI055_RATE_X_MSB_ADDR 0x03
+/**< Address of X axis Rate MSB Register */
+#define BMI055_RATE_Y_LSB_ADDR 0x04
+/**< Address of Y axis Rate LSB Register */
+#define BMI055_RATE_Y_MSB_ADDR 0x05
+/**< Address of Y axis Rate MSB Register */
+#define BMI055_RATE_Z_LSB_ADDR 0x06
+/**< Address of Z axis Rate LSB Register */
+#define BMI055_RATE_Z_MSB_ADDR 0x07
+/**< Address of Z axis Rate MSB Register */
+#define BMI055_TEMP_ADDR 0x08
+/**< Address of Temperature Data LSB Register */
+
+/* Status Register */
+#define BMI055_INTR_STAT0_ADDR 0x09
+/**< Address of Interrupt status Register 0 */
+#define BMI055_INTR_STAT1_ADDR 0x0A
+/**< Address of Interrupt status Register 1 */
+#define BMI055_INTR_STAT2_ADDR 0x0B
+/**< Address of Interrupt status Register 2 */
+#define BMI055_INTR_STAT3_ADDR 0x0C
+/**< Address of Interrupt status Register 3 */
+#define BMI055_FIFO_STAT_ADDR 0x0E
+/**< Address of FIFO status Register */
+
+/* Control Register */
+#define BMI055_RANGE_ADDR 0x0F
+/**< Address of Range address Register */
+#define BMI055_BW_ADDR 0x10
+/**< Address of Bandwidth Register */
+#define BMI055_MODE_LPM1_ADDR 0x11
+/**< Address of Mode LPM1 Register */
+#define BMI055_MODE_LPM2_ADDR 0x12
+/**< Address of Mode LPM2 Register */
+#define BMI055_HIGH_BW_ADDR 0x13
+/**< Address of Rate HIGH_BW Register */
+#define BMI055_BGW_SOFT_RST_ADDR 0x14
+/**< Address of BGW Softreset Register */
+#define BMI055_INTR_ENABLE0_ADDR 0x15
+/**< Address of Interrupt Enable 0 */
+#define BMI055_INTR_ENABLE1_ADDR 0x16
+/**< Address of Interrupt Enable 1 */
+#define BMI055_INTR_MAP_ZERO_ADDR 0x17
+/**< Address of Interrupt MAP 0 */
+#define BMI055_INTR_MAP_ONE_ADDR 0x18
+/**< Address of Interrupt MAP 1 */
+#define BMI055_INTR_MAP_TWO_ADDR 0x19
+/**< Address of Interrupt MAP 2 */
+#define BMI055_INTR_ZERO_ADDR 0x1A
+/**< Address of Interrupt 0 register */
+#define BMI055_INTR_ONE_ADDR 0x1B
+/**< Address of Interrupt 1 register */
+#define BMI055_INTR_TWO_ADDR 0x1C
+/**< Address of Interrupt 2 register */
+#define BMI055_INTR_4_ADDR 0x1E
+/**< Address of Interrupt 4 register */
+#define BMI055_RST_LATCH_ADDR 0x21
+/**< Address of Reset Latch Register */
+#define BMI055_HIGHRATE_THRES_X_ADDR 0x22
+/**< Address of High Th x Address register */
+#define BMI055_HIGHRATE_DURN_X_ADDR 0x23
+/**< Address of High Dur x Address register */
+#define BMI055_HIGHRATE_THRES_Y_ADDR 0x24
+/**< Address of High Th y Address register */
+#define BMI055_HIGHRATE_DURN_Y_ADDR 0x25
+/**< Address of High Dur y Address register */
+#define BMI055_HIGHRATE_THRES_Z_ADDR 0x26
+/**< Address of High Th z Address register */
+#define BMI055_HIGHRATE_DURN_Z_ADDR 0x27
+/**< Address of High Dur z Address register */
+#define BMI055_SOC_ADDR 0x31
+/**< Address of SOC register */
+#define BMI055_A_FOC_ADDR 0x32
+/**< Address of A_FOC Register */
+#define BMI055_TRIM_NVM_CTRL_ADDR 0x33
+/**< Address of Trim NVM control register */
+#define BMI055_BGW_SPI3_WDT_ADDR 0x34
+/**< Address of BGW SPI3,WDT Register */
+
+/* Trim Register */
+#define BMI055_OFC1_ADDR 0x36
+/**< Address of OFC1 Register */
+#define BMI055_OFC2_ADDR 0x37
+/**< Address of OFC2 Register */
+#define BMI055_OFC3_ADDR 0x38
+/**< Address of OFC3 Register */
+#define BMI055_OFC4_ADDR 0x39
+/**< Address of OFC4 Register */
+#define BMI055_TRIM_GP0_ADDR 0x3A
+/**< Address of Trim GP0 Register */
+#define BMI055_TRIM_GP1_ADDR 0x3B
+/**< Address of Trim GP1 Register */
+#define BMI055_SELECTF_TEST_ADDR 0x3C
+/**< Address of BGW Self test Register */
+
+/* Control Register */
+#define BMI055_FIFO_CGF1_ADDR 0x3D
+/**< Address of FIFO CGF0 Register */
+#define BMI055_FIFO_CGF0_ADDR 0x3E
+/**< Address of FIFO CGF1 Register */
+
+/* Data Register */
+#define BMI055_FIFO_DATA_ADDR 0x3F
+/**< Address of FIFO Data Register */
+
+
+/**************************************************************************************************/
+
+class BMI055 :public SensorBase
+{
+public:
+ BMI055(int sensor_type, const char* iic_bus, int addr);
+
+ int read_reg(rt_uint8_t reg, rt_uint8_t* value);
+ int write_reg(rt_uint8_t reg, rt_uint8_t value);
+ int read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size);
+
+private:
+ struct rt_i2c_bus_device *i2c_bus;
+ int i2c_addr;
+};
+
+class BMI055_Accelerometer:public BMI055
+{
+public:
+ BMI055_Accelerometer(const char* iic_name, int addr);
+
+ virtual int configure(SensorConfig *config);
+ virtual int activate(int enable);
+
+ virtual int poll(sensors_event_t *event);
+ virtual void getSensor(sensor_t *sensor);
+
+private:
+ rt_int16_t x_offset, y_offset, z_offset;
+
+ rt_bool_t enable;
+ float sensitivity;
+};
+
+class BMI055_Gyroscope:public BMI055
+{
+public:
+ BMI055_Gyroscope(const char* iic_name, int addr);
+
+ virtual int configure(SensorConfig *config);
+ virtual int activate(int enable);
+
+ virtual int poll(sensors_event_t *event);
+ virtual void getSensor(sensor_t *sensor);
+
+private:
+ rt_int16_t x_offset, y_offset, z_offset;
+
+ rt_bool_t enable;
+ float sensitivity;
+};
+
+#endif
diff --git a/components/drivers/sensors/mpu6050_sensor.cpp b/components/drivers/sensors/mpu6050_sensor.cpp
new file mode 100644
index 0000000000..8f6557a7ce
--- /dev/null
+++ b/components/drivers/sensors/mpu6050_sensor.cpp
@@ -0,0 +1,462 @@
+/*
+ * File : MPU6050_sensor.cpp
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2014, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2014-12-20 Bernard the first version
+ * 2015-1-11 RT_learning modify the mpu6050 initialize
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rtdevice.h>
+
+#include "mpu6050_sensor.h"
+
+
+const static sensor_t _MPU6050_sensor[] =
+{
+ {
+ .name = "Accelerometer",
+ .vendor = "Invensense",
+ .version = sizeof(sensor_t),
+ .handle = 0,
+ .type = SENSOR_TYPE_ACCELEROMETER,
+ .maxRange = SENSOR_ACCEL_RANGE_16G,
+ .resolution = 1.0f,
+ .power = 0.5f,
+ .minDelay = 10000,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 64,
+ },
+ {
+ .name = "Gyroscope",
+ .vendor = "Invensense",
+ .version = sizeof(sensor_t),
+ .handle = 0,
+ .type = SENSOR_TYPE_GYROSCOPE,
+ .maxRange = SENSOR_GYRO_RANGE_2000DPS,
+ .resolution = 1.0f,
+ .power = 0.5f,
+ .minDelay = 10000,
+ .fifoReservedEventCount = 0,
+ .fifoMaxEventCount = 64,
+ }
+};
+
+MPU6050::MPU6050(int sensor_type, const char* iic_bus, int addr)
+ : SensorBase(sensor_type)
+{
+ this->i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(iic_bus);
+ if (this->i2c_bus == NULL)
+ {
+ printf("MPU6050: No IIC device:%s\n", iic_bus);
+ return;
+ }
+
+ this->i2c_addr = addr;
+
+ /* register to sensor manager */
+ SensorManager::registerSensor(this);
+}
+
+int MPU6050::read_reg(rt_uint8_t reg, rt_uint8_t *value)
+{
+ struct rt_i2c_msg msgs[2];
+
+ msgs[0].addr = this->i2c_addr;
+ msgs[0].flags = RT_I2C_WR;
+ msgs[0].buf = &reg;
+ msgs[0].len = 1;
+
+ msgs[1].addr = this->i2c_addr;
+ msgs[1].flags = RT_I2C_RD; /* Read from slave */
+ msgs[1].buf = (rt_uint8_t *)value;
+ msgs[1].len = 1;
+
+ if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
+ return RT_EOK;
+
+ return -RT_ERROR;
+}
+
+int MPU6050::read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size)
+{
+ struct rt_i2c_msg msgs[2];
+
+ msgs[0].addr = this->i2c_addr;
+ msgs[0].flags = RT_I2C_WR;
+ msgs[0].buf = &reg;
+ msgs[0].len = 1;
+
+ msgs[1].addr = this->i2c_addr;
+ msgs[1].flags = RT_I2C_RD; /* Read from slave */
+ msgs[1].buf = (rt_uint8_t *)value;
+ msgs[1].len = size;
+
+ if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
+ return RT_EOK;
+
+ return -RT_ERROR;
+}
+
+int MPU6050::write_reg(rt_uint8_t reg, rt_uint8_t value)
+{
+ struct rt_i2c_msg msgs[2];
+
+ msgs[0].addr = this->i2c_addr;
+ msgs[0].flags = RT_I2C_WR;
+ msgs[0].buf = &reg;
+ msgs[0].len = 1;
+
+ msgs[1].addr = this->i2c_addr;
+ msgs[1].flags = RT_I2C_WR | RT_I2C_NO_START;
+ msgs[1].buf = (rt_uint8_t *)&value;
+ msgs[1].len = 1;
+
+ if (rt_i2c_transfer(this->i2c_bus, msgs, 2) == 2)
+ return RT_EOK;
+
+ return -RT_ERROR;
+}
+
+
+MPU6050_Accelerometer::MPU6050_Accelerometer(const char* iic_name, int addr)
+ : MPU6050(SENSOR_TYPE_ACCELEROMETER, iic_name, addr)
+{
+ int index;
+ uint8_t id;
+ rt_uint8_t value[6] = {0};
+ rt_int32_t x, y, z;
+ SensorConfig config = {SENSOR_MODE_NORMAL, SENSOR_DATARATE_400HZ, SENSOR_ACCEL_RANGE_2G};
+
+ /* initialize MPU6050 */
+ write_reg(MPU6050_PWR_MGMT_1, 0x80); /* reset mpu6050 device */
+ write_reg(MPU6050_SMPLRT_DIV, 0x00); /* Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) */
+ write_reg(MPU6050_PWR_MGMT_1, 0x03); /* Wake up device , set device clock Z axis gyroscope */
+ write_reg(MPU6050_CONFIG, 0x03); /* set DLPF_CFG 42Hz */
+ write_reg(MPU6050_GYRO_CONFIG, 0x18); /* set gyro 2000deg/s */
+ write_reg(MPU6050_ACCEL_CONFIG, 0x08); /* set acc +-4g/s */
+
+
+ x_offset = y_offset = z_offset = 0;
+ x = y = z = 0;
+
+ /* read MPU6050 id */
+ read_buffer(MPU6050_WHOAMI, &id, 1);
+ if (id != MPU6050_ID)
+ {
+ printf("Warning: not found MPU6050 id: %02x\n", id);
+ }
+
+ /* get offset */
+ for (index = 0; index < 200; index ++)
+ {
+ read_buffer(MPU6050_ACCEL_XOUT_H, value, 6);
+
+ x += (((rt_int16_t)value[0] << 8) | value[1]);
+ y += (((rt_int16_t)value[2] << 8) | value[3]);
+ z += (((rt_int16_t)value[4] << 8) | value[5]);
+ }
+ x_offset = x / 200;
+ y_offset = y / 200;
+ z_offset = z / 200;
+
+ this->enable = RT_FALSE;
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
+ this->config = config;
+}
+
+int
+MPU6050_Accelerometer::configure(SensorConfig *config)
+{
+ int range;
+ uint8_t value;
+
+ if (config == RT_NULL) return -1;
+
+ /* TODO: set datarate */
+
+ /* get range and calc the sensitivity */
+ range = config->range.accel_range;
+ switch (range)
+ {
+ case SENSOR_ACCEL_RANGE_2G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_2G;
+ range = 0;
+ break;
+ case SENSOR_ACCEL_RANGE_4G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_4G;
+ range = 0x01 << 2;
+ break;
+ case SENSOR_ACCEL_RANGE_8G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_8G;
+ range = 0x02 << 2;
+ break;
+ case SENSOR_ACCEL_RANGE_16G:
+ this->sensitivity = SENSOR_ACCEL_SENSITIVITY_16G;
+ range = 0x03 << 2;
+ break;
+ default:
+ return -1;
+ }
+
+ /* set range to sensor */
+ read_reg(MPU6050_ACCEL_CONFIG, &value);
+ value &= ~(0x3 << 2);
+ value |= range;
+ write_reg(MPU6050_ACCEL_CONFIG, value);
+
+ return 0;
+}
+
+int
+MPU6050_Accelerometer::activate(int enable)
+{
+ uint8_t value;
+
+ if (enable && this->enable == RT_FALSE)
+ {
+ /* enable accelerometer */
+ read_reg(MPU6050_PWR_MGMT_2, &value);
+ value &= ~(0x07 << 2);
+ write_reg(MPU6050_PWR_MGMT_2, value);
+ }
+
+ if (!enable && this->enable == RT_TRUE)
+ {
+ /* disable accelerometer */
+ read_reg(MPU6050_PWR_MGMT_2, &value);
+ value |= (0x07 << 2);
+ write_reg(MPU6050_PWR_MGMT_2, value);
+ }
+
+ if (enable) this->enable = RT_TRUE;
+ else this->enable = RT_FALSE;
+
+ return 0;
+}
+
+int
+MPU6050_Accelerometer::poll(sensors_event_t *event)
+{
+ rt_uint8_t value[6];
+ rt_int16_t x, y, z;
+
+ /* parameters check */
+ if (event == NULL) return -1;
+
+ /* get event data */
+ event->version = sizeof(sensors_event_t);
+ event->sensor = (int32_t) this;
+ event->timestamp = rt_tick_get();
+ event->type = SENSOR_TYPE_ACCELEROMETER;
+
+ read_buffer(MPU6050_ACCEL_XOUT_H, value, 6);
+
+ /* get raw data */
+ x = (((rt_int16_t)value[0] << 8) | value[1]);
+ y = (((rt_int16_t)value[2] << 8) | value[3]);
+ z = (((rt_int16_t)value[4] << 8) | value[5]);
+
+ if (config.mode == SENSOR_MODE_RAW)
+ {
+ event->raw_acceleration.x = x;
+ event->raw_acceleration.y = y;
+ event->raw_acceleration.z = z;
+ }
+ else
+ {
+
+ x -= x_offset; y -= y_offset; z -= z_offset;
+ event->acceleration.x = x * this->sensitivity * SENSORS_GRAVITY_STANDARD;
+ event->acceleration.y = y * this->sensitivity * SENSORS_GRAVITY_STANDARD;
+ event->acceleration.z = z * this->sensitivity * SENSORS_GRAVITY_STANDARD;
+ }
+
+ return 0;
+}
+
+void
+MPU6050_Accelerometer::getSensor(sensor_t *sensor)
+{
+ /* get sensor description */
+ if (sensor)
+ {
+ memcpy(sensor, &_MPU6050_sensor[0], sizeof(sensor_t));
+ }
+}
+
+MPU6050_Gyroscope::MPU6050_Gyroscope(const char* iic_name, int addr)
+ : MPU6050(SENSOR_TYPE_GYROSCOPE, iic_name, addr)
+{
+ int index;
+ uint8_t id;
+ rt_uint8_t value[6];
+ rt_int32_t x, y, z;
+
+ /* initialize MPU6050 */
+ write_reg(MPU6050_PWR_MGMT_1, 0x80); /* reset mpu6050 device */
+ write_reg(MPU6050_SMPLRT_DIV, 0x00); /* Sample Rate = Gyroscope Output Rate / (1 + SMPLRT_DIV) */
+ write_reg(MPU6050_PWR_MGMT_1, 0x03); /* Wake up device , set device clock Z axis gyroscope */
+ write_reg(MPU6050_CONFIG, 0x03); /* set DLPF_CFG 42Hz */
+ write_reg(MPU6050_GYRO_CONFIG, 0x18); /* set gyro 2000deg/s */
+ write_reg(MPU6050_ACCEL_CONFIG, 0x08); /* set acc +-4g/s */
+
+ x_offset = y_offset = z_offset = 0;
+ x = y = z = 0;
+
+ /* read MPU6050 id */
+ read_reg(MPU6050_WHOAMI, &id);
+ if (id != MPU6050_ID)
+ {
+ printf("Warning: not found MPU6050 id: %02x\n", id);
+ }
+
+ /* get offset */
+ for (index = 0; index < 200; index ++)
+ {
+ read_buffer(MPU6050_GYRO_XOUT_H, value, 6);
+
+ x += (((rt_int16_t)value[0] << 8) | value[1]);
+ y += (((rt_int16_t)value[2] << 8) | value[3]);
+ z += (((rt_int16_t)value[4] << 8) | value[5]);
+ }
+ x_offset = x / 200;
+ y_offset = y / 200;
+ z_offset = z / 200;
+
+ this->enable = RT_FALSE;
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
+}
+
+int
+MPU6050_Gyroscope::configure(SensorConfig *config)
+{
+ int range;
+ uint8_t value;
+
+ if (config == RT_NULL) return -1;
+
+ /* TODO: set datarate */
+
+ /* get range and calc the sensitivity */
+ range = config->range.gyro_range;
+ switch (range)
+ {
+ case SENSOR_GYRO_RANGE_250DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_250DPS;
+ range = 0;
+ break;
+ case SENSOR_GYRO_RANGE_500DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_500DPS;
+ range = 0x01 << 2;
+ break;
+ case SENSOR_GYRO_RANGE_1000DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_1000DPS;
+ range = 0x02 << 2;
+ break;
+ case SENSOR_GYRO_RANGE_2000DPS:
+ this->sensitivity = SENSOR_GYRO_SENSITIVITY_2000DPS;
+ range = 0x03 << 2;
+ break;
+ default:
+ return -1;
+ }
+
+ /* set range to sensor */
+ read_reg(MPU6050_GYRO_CONFIG, &value);
+ value &= ~(0x3 << 2);
+ value |= range;
+ write_reg(MPU6050_GYRO_CONFIG, value);
+
+ return 0;
+}
+
+int
+MPU6050_Gyroscope::activate(int enable)
+{
+ uint8_t value;
+
+ if (enable && this->enable == RT_FALSE)
+ {
+ /* enable gyroscope */
+ read_reg(MPU6050_PWR_MGMT_1, &value);
+ value &= ~(0x01 << 4);
+ write_reg(MPU6050_PWR_MGMT_1, value);
+
+ read_reg(MPU6050_PWR_MGMT_2, &value);
+ value &= ~(0x07 << 0);
+ write_reg(MPU6050_PWR_MGMT_2, value);
+ }
+
+ if (!enable && this->enable == RT_TRUE)
+ {
+ /* disable gyroscope */
+ read_reg(MPU6050_PWR_MGMT_2, &value);
+ value |= (0x07 << 0);
+ write_reg(MPU6050_PWR_MGMT_2, value);
+ }
+
+ if (enable) this->enable = RT_TRUE;
+ else this->enable = RT_FALSE;
+
+ return 0;
+}
+
+int
+MPU6050_Gyroscope::poll(sensors_event_t *event)
+{
+ rt_uint8_t value[6];
+ rt_int16_t x, y, z;
+
+ /* parameters check */
+ if (event == NULL) return -1;
+
+ /* get event data */
+ event->version = sizeof(sensors_event_t);
+ event->sensor = (int32_t) this;
+ event->timestamp = rt_tick_get();
+ event->type = SENSOR_TYPE_GYROSCOPE;
+
+ read_buffer(MPU6050_GYRO_XOUT_H, value, 6);
+
+ /* get raw data */
+ x = (((rt_int16_t)value[0] << 8) | value[1]);
+ y = (((rt_int16_t)value[2] << 8) | value[3]);
+ z = (((rt_int16_t)value[4] << 8) | value[5]);
+
+
+ if (config.mode == SENSOR_MODE_RAW)
+ {
+ event->raw_gyro.x = x;
+ event->raw_gyro.y = y;
+ event->raw_gyro.z = z;
+ }
+ else
+ {
+ x -= x_offset; y -= y_offset; z -= z_offset;
+ event->gyro.x = x * this->sensitivity * SENSORS_DPS_TO_RADS;
+ event->gyro.y = y * this->sensitivity * SENSORS_DPS_TO_RADS;
+ event->gyro.z = z * this->sensitivity * SENSORS_DPS_TO_RADS;
+ }
+
+ return 0;
+}
+
+void
+MPU6050_Gyroscope::getSensor(sensor_t *sensor)
+{
+ /* get sensor description */
+ if (sensor)
+ {
+ memcpy(sensor, &_MPU6050_sensor[1], sizeof(sensor_t));
+ }
+}
+
diff --git a/components/drivers/sensors/mpu6050_sensor.h b/components/drivers/sensors/mpu6050_sensor.h
new file mode 100644
index 0000000000..c7e28ba28e
--- /dev/null
+++ b/components/drivers/sensors/mpu6050_sensor.h
@@ -0,0 +1,193 @@
+/*
+ * File : MPU6050_sensor.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2014, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2014-12-20 Bernard the first version
+ * 2015-1-11 RT_learning modify the mpu6050 ID
+ */
+
+#ifndef MPU6050_SENSOR_H__
+#define MPU6050_SENSOR_H__
+
+#include <sensor.h>
+
+#define MPU6050_ADDRESS_AD0_LOW 0x68 // address pin low (GND), default for InvenSense evaluation board
+#define MPU6050_ADDRESS_AD0_HIGH 0x69 // address pin high (VCC)
+#define MPU6050_DEFAULT_ADDRESS MPU6050_ADDRESS_AD0_LOW
+
+#define MPU6050_XG_OFFS_TC 0x00
+#define MPU6050_YG_OFFS_TC 0x01
+#define MPU6050_ZG_OFFS_TC 0x02
+#define MPU6050_X_FINE_GAIN 0x03
+#define MPU6050_Y_FINE_GAIN 0x04
+#define MPU6050_Z_FINE_GAIN 0x05
+#define MPU6050_XA_OFFS_H 0x06
+#define MPU6050_XA_OFFS_L 0x07
+#define MPU6050_YA_OFFS_H 0x08
+#define MPU6050_YA_OFFS_L 0x09
+#define MPU6050_ZA_OFFS_H 0x0A
+#define MPU6050_ZA_OFFS_L 0x0B
+#define MPU6050_PRODUCT_ID 0x0C
+#define MPU6050_SELF_TEST_X 0x0D
+#define MPU6050_SELF_TEST_Y 0x0E
+#define MPU6050_SELF_TEST_Z 0x0F
+#define MPU6050_SELF_TEST_A 0x10
+#define MPU6050_XG_OFFS_USRH 0x13
+#define MPU6050_XG_OFFS_USRL 0x14
+#define MPU6050_YG_OFFS_USRH 0x15
+#define MPU6050_YG_OFFS_USRL 0x16
+#define MPU6050_ZG_OFFS_USRH 0x17
+#define MPU6050_ZG_OFFS_USRL 0x18
+#define MPU6050_SMPLRT_DIV 0x19
+#define MPU6050_CONFIG 0x1A
+#define MPU6050_GYRO_CONFIG 0x1B
+#define MPU6050_ACCEL_CONFIG 0x1C
+#define MPU6050_ACCEL_CONFIG_2 0x1D
+#define MPU6050_LP_ACCEL_ODR 0x1E
+#define MPU6050_MOT_THR 0x1F
+#define MPU6050_FIFO_EN 0x23
+#define MPU6050_I2C_MST_CTRL 0x24
+#define MPU6050_I2C_SLV0_ADDR 0x25
+#define MPU6050_I2C_SLV0_REG 0x26
+#define MPU6050_I2C_SLV0_CTRL 0x27
+#define MPU6050_I2C_SLV1_ADDR 0x28
+#define MPU6050_I2C_SLV1_REG 0x29
+#define MPU6050_I2C_SLV1_CTRL 0x2A
+#define MPU6050_I2C_SLV2_ADDR 0x2B
+#define MPU6050_I2C_SLV2_REG 0x2C
+#define MPU6050_I2C_SLV2_CTRL 0x2D
+#define MPU6050_I2C_SLV3_ADDR 0x2E
+#define MPU6050_I2C_SLV3_REG 0x2F
+#define MPU6050_I2C_SLV3_CTRL 0x30
+#define MPU6050_I2C_SLV4_ADDR 0x31
+#define MPU6050_I2C_SLV4_REG 0x32
+#define MPU6050_I2C_SLV4_DO 0x33
+#define MPU6050_I2C_SLV4_CTRL 0x34
+#define MPU6050_I2C_SLV4_DI 0x35
+#define MPU6050_I2C_MST_STATUS 0x36
+#define MPU6050_INT_PIN_CFG 0x37
+#define MPU6050_INT_ENABLE 0x38
+#define MPU6050_ACCEL_XOUT_H 0x3B
+#define MPU6050_ACCEL_XOUT_L 0x3C
+#define MPU6050_ACCEL_YOUT_H 0x3D
+#define MPU6050_ACCEL_YOUT_L 0x3E
+#define MPU6050_ACCEL_ZOUT_H 0x3F
+#define MPU6050_ACCEL_ZOUT_L 0x40
+#define MPU6050_TEMP_OUT_H 0x41
+#define MPU6050_TEMP_OUT_L 0x42
+#define MPU6050_GYRO_XOUT_H 0x43
+#define MPU6050_GYRO_XOUT_L 0x44
+#define MPU6050_GYRO_YOUT_H 0x45
+#define MPU6050_GYRO_YOUT_L 0x46
+#define MPU6050_GYRO_ZOUT_H 0x47
+#define MPU6050_GYRO_ZOUT_L 0x48
+#define MPU6050_EXT_SENS_DATA_00 0x49
+#define MPU6050_EXT_SENS_DATA_01 0x4A
+#define MPU6050_EXT_SENS_DATA_02 0x4B
+#define MPU6050_EXT_SENS_DATA_03 0x4C
+#define MPU6050_EXT_SENS_DATA_04 0x4D
+#define MPU6050_EXT_SENS_DATA_05 0x4E
+#define MPU6050_EXT_SENS_DATA_06 0x4F
+#define MPU6050_EXT_SENS_DATA_07 0x50
+#define MPU6050_EXT_SENS_DATA_08 0x51
+#define MPU6050_EXT_SENS_DATA_09 0x52
+#define MPU6050_EXT_SENS_DATA_10 0x53
+#define MPU6050_EXT_SENS_DATA_11 0x54
+#define MPU6050_EXT_SENS_DATA_12 0x55
+#define MPU6050_EXT_SENS_DATA_13 0x56
+#define MPU6050_EXT_SENS_DATA_14 0x57
+#define MPU6050_EXT_SENS_DATA_15 0x58
+#define MPU6050_EXT_SENS_DATA_16 0x59
+#define MPU6050_EXT_SENS_DATA_17 0x5A
+#define MPU6050_EXT_SENS_DATA_18 0x5B
+#define MPU6050_EXT_SENS_DATA_19 0x5C
+#define MPU6050_EXT_SENS_DATA_20 0x5D
+#define MPU6050_EXT_SENS_DATA_21 0x5E
+#define MPU6050_EXT_SENS_DATA_22 0x5F
+#define MPU6050_EXT_SENS_DATA_23 0x60
+#define MPU6050_I2C_SLV0_DO 0x63
+#define MPU6050_I2C_SLV1_DO 0x64
+#define MPU6050_I2C_SLV2_DO 0x65
+#define MPU6050_I2C_SLV3_DO 0x66
+#define MPU6050_I2C_MST_DELAY_CTRL 0x67
+#define MPU6050_SIGNAL_PATH_RESET 0x68
+#define MPU6050_MOT_DETECT_CTRL 0x69
+#define MPU6050_USER_CTRL 0x6A
+#define MPU6050_PWR_MGMT_1 0x6B
+#define MPU6050_PWR_MGMT_2 0x6C
+#define MPU6050_BANK_SEL 0x6D
+#define MPU6050_MEM_START_ADDR 0x6E
+#define MPU6050_MEM_R_W 0x6F
+#define MPU6050_DMP_CFG_1 0x70
+#define MPU6050_DMP_CFG_2 0x71
+#define MPU6050_FIFO_COUNTH 0x72
+#define MPU6050_FIFO_COUNTL 0x73
+#define MPU6050_FIFO_R_W 0x74
+#define MPU6050_WHOAMI 0x75
+#define MPU6050_XA_OFFSET_H 0x77
+#define MPU6050_XA_OFFSET_L 0x78
+#define MPU6050_YA_OFFSET_H 0x7A
+#define MPU6050_YA_OFFSET_L 0x7B
+#define MPU6050_ZA_OFFSET_H 0x7D
+#define MPU6050_ZA_OFFSET_L 0x7E
+
+#define MPU6050_ID 0x68
+
+class MPU6050 :public SensorBase
+{
+public:
+ MPU6050(int sensor_type, const char* iic_bus, int addr);
+
+ int read_reg(rt_uint8_t reg, rt_uint8_t* value);
+ int write_reg(rt_uint8_t reg, rt_uint8_t value);
+ int read_buffer(rt_uint8_t reg, rt_uint8_t* value, rt_size_t size);
+
+private:
+ struct rt_i2c_bus_device *i2c_bus;
+ int i2c_addr;
+};
+
+class MPU6050_Accelerometer:public MPU6050
+{
+public:
+ MPU6050_Accelerometer(const char* iic_name, int addr);
+
+ virtual int configure(SensorConfig *config);
+ virtual int activate(int enable);
+
+ virtual int poll(sensors_event_t *event);
+ virtual void getSensor(sensor_t *sensor);
+
+private:
+ rt_int16_t x_offset, y_offset, z_offset;
+
+ rt_bool_t enable;
+ float sensitivity;
+};
+
+class MPU6050_Gyroscope:public MPU6050
+{
+public:
+ MPU6050_Gyroscope(const char* iic_name, int addr);
+
+ virtual int configure(SensorConfig *config);
+ virtual int activate(int enable);
+
+ virtual int poll(sensors_event_t *event);
+ virtual void getSensor(sensor_t *sensor);
+
+private:
+ rt_int16_t x_offset, y_offset, z_offset;
+
+ rt_bool_t enable;
+ float sensitivity;
+};
+
+#endif
diff --git a/components/drivers/sensors/sensor.cpp b/components/drivers/sensors/sensor.cpp
index 52718183f3..18eb8eee18 100644
--- a/components/drivers/sensors/sensor.cpp
+++ b/components/drivers/sensors/sensor.cpp
@@ -1,25 +1,64 @@
+/*
+ * File : sensors.cpp
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2014, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2014-08-03 Bernard the first version
+ */
+
#include <stddef.h>
+#include <string.h>
+
#include "sensor.h"
/**
- * Sensor
+ * SensorBase
*/
-Sensor::Sensor()
+SensorBase::SensorBase(int type)
{
+ memset(&(this->config), 0x0, sizeof(SensorConfig));
+
+ this->type = type;
this->next = this->prev = NULL;
- Subscribe(NULL, NULL);
+ subscribe(NULL, NULL);
}
-Sensor::~Sensor()
+SensorBase::~SensorBase()
{
}
-int Sensor::GetType(void)
+int SensorBase::getType(void)
{
return this->type;
}
-int Sensor::Subscribe(SensorEventHandler_t *handler, void *user_data)
+int SensorBase::setConfig(SensorConfig *config)
+{
+ int result;
+
+ /* configure to the low level sensor */
+ result = this->configure(config);
+ if (result == 0)
+ {
+ this->config = *config;
+ }
+
+ return result;
+}
+
+int SensorBase::getConfig(SensorConfig *config)
+{
+ *config = this->config;
+ return 0;
+}
+
+int SensorBase::subscribe(SensorEventHandler_t *handler, void *user_data)
{
this->evtHandler = handler;
this->userData = user_data;
@@ -27,12 +66,12 @@ int Sensor::Subscribe(SensorEventHandler_t *handler, void *user_data)
return 0;
}
-int Sensor::Publish(sensors_event_t *event)
+int SensorBase::publish(sensors_event_t *event)
{
if (this->evtHandler != NULL)
{
/* invoke subscribed handler */
- (*evtHandler)(this, event, this->userData);
+ (*evtHandler)(event, this->userData);
}
return 0;
@@ -41,57 +80,52 @@ int Sensor::Publish(sensors_event_t *event)
/**
* Sensor Manager
*/
-/* sensor manager instance */
-static SensorManager _sensor_manager;
+/* sensors list */
+static SensorBase *sensor_list = NULL;
SensorManager::SensorManager()
{
- sensorList = NULL;
}
SensorManager::~SensorManager()
{
}
-int SensorManager::RegisterSensor(Sensor *sensor)
+int SensorManager::registerSensor(SensorBase *sensor)
{
- SensorManager *self = &_sensor_manager;
-
RT_ASSERT(sensor != RT_NULL);
/* add sensor into the list */
- if (self->sensorList = NULL)
+ if (sensor_list == NULL)
{
sensor->prev = sensor->next = sensor;
}
else
{
- sensor->prev = self->sensorList;
- sensor->next = self->sensorList->next;
+ sensor_list->prev->next = sensor;
+ sensor->prev = sensor_list->prev;
- self->sensorList->next->prev = sensor;
- self->sensorList->next = sensor;
+ sensor_list->prev = sensor;
+ sensor->next = sensor_list;
}
/* point the sensorList to this sensor */
- self->sensorList = sensor;
+ sensor_list = sensor;
return 0;
}
-int SensorManager::DeregisterSensor(Sensor *sensor)
+int SensorManager::unregisterSensor(SensorBase *sensor)
{
- SensorManager *self = &_sensor_manager;
-
/* disconnect sensor list */
sensor->next->prev = sensor->prev;
sensor->prev->next = sensor->next;
/* check the sensorList */
- if (sensor == self->sensorList)
+ if (sensor == sensor_list)
{
- if (sensor->next == sensor) self->sensorList = NULL; /* empty list */
- else self->sensorList = sensor->next;
+ if (sensor->next == sensor) sensor_list = NULL; /* empty list */
+ else sensor_list = sensor->next;
}
/* re-initialize sensor node */
@@ -100,36 +134,99 @@ int SensorManager::DeregisterSensor(Sensor *sensor)
return 0;
}
-Sensor *SensorManager::GetDefaultSensor(int type)
+SensorBase *SensorManager::getDefaultSensor(int type)
{
- SensorManager *self = &_sensor_manager;
- Sensor *sensor = self->sensorList;
+ SensorBase *sensor = sensor_list;
if (sensor == NULL) return NULL;
do
{
/* find the same type */
- if (sensor->GetType() == type) return sensor;
+ if (sensor->getType() == type) return sensor;
sensor = sensor->next;
- }
- while (sensor != self->sensorList);
+ }while (sensor != sensor_list);
return NULL;
}
-int SensorManager::Subscribe(int type, SensorEventHandler_t *handler, void *user_data)
+int SensorManager::subscribe(int type, SensorEventHandler_t *handler, void *user_data)
{
- Sensor *sensor;
+ SensorBase *sensor;
- sensor = SensorManager::GetDefaultSensor(type);
+ sensor = SensorManager::getDefaultSensor(type);
if (sensor != NULL)
{
- sensor->Subscribe(handler, user_data);
+ sensor->subscribe(handler, user_data);
return 0;
}
return -1;
}
+int SensorManager::sensorEventReady(SensorBase *sensor)
+{
+ return 0;
+}
+
+int SensorManager::pollSensor(SensorBase *sensor, sensors_event_t *events, int number, int duration)
+{
+ rt_tick_t tick;
+ int result, index;
+
+ if (sensor == NULL) return -1;
+
+ tick = rt_tick_get();
+ for (index = 0; index < number; index ++)
+ {
+ result = sensor->poll(&events[index]);
+ if (result < 0) break;
+
+ if (rt_tick_get() - tick > duration) break;
+ }
+
+ return index;
+}
+
+rt_sensor_t rt_sensor_get_default(int type)
+{
+ return (rt_sensor_t)SensorManager::getDefaultSensor(type);
+}
+
+int rt_sensor_subscribe(rt_sensor_t sensor, SensorEventHandler_t *handler, void *user_data)
+{
+ SensorBase *sensor_base;
+ if (sensor == NULL) return -1;
+
+ sensor_base = (SensorBase*)sensor;
+
+ return sensor_base->subscribe(handler, user_data);
+}
+
+int rt_sensor_poll(rt_sensor_t sensor, sensors_event_t *event)
+{
+ SensorBase *sensor_base;
+ if (sensor == NULL || event == NULL) return -1;
+
+ sensor_base = (SensorBase*)sensor;
+ return sensor_base->poll(event);
+}
+
+int rt_sensor_configure(rt_sensor_t sensor, SensorConfig *config)
+{
+ SensorBase *sensor_base;
+ if (sensor == NULL || config == NULL) return -1;
+
+ sensor_base = (SensorBase*)sensor;
+ return sensor_base->setConfig(config);
+}
+
+int rt_sensor_activate(rt_sensor_t sensor, int enable)
+{
+ SensorBase *sensor_base;
+ if (sensor == NULL) return -1;
+
+ sensor_base = (SensorBase*)sensor;
+ return sensor_base->activate(enable);
+}
diff --git a/components/drivers/sensors/sensor.h b/components/drivers/sensors/sensor.h
index 09929d1b58..2962b21a80 100644
--- a/components/drivers/sensors/sensor.h
+++ b/components/drivers/sensors/sensor.h
@@ -34,10 +34,11 @@
#define SENSORS_H__
#include <rtdevice.h>
-
#include <stdint.h>
-#include <sys/cdefs.h>
-#include <sys/types.h>
+
+#ifdef __CC_ARM /* skip warning in armcc */
+#pragma anon_unions
+#endif
/**
* Handles must be higher than SENSORS_HANDLE_BASE and must be unique.
@@ -729,14 +730,24 @@ enum
* Values returned by the accelerometer in various locations in the universe.
* all values are in SI units (m/s^2)
*/
-#define GRAVITY_SUN (275.0f)
-#define GRAVITY_EARTH (9.80665f)
+#define SENSORS_GRAVITY_SUN (275.0f)
+#define SENSORS_GRAVITY_MOON (1.6f)
+#define SENSORS_GRAVITY_EARTH (9.80665f)
+#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
/** Maximum magnetic field on Earth's surface */
-#define MAGNETIC_FIELD_EARTH_MAX (60.0f)
+#define MAGNETIC_FIELD_EARTH_MAX (60.0f)
/** Minimum magnetic field on Earth's surface */
-#define MAGNETIC_FIELD_EARTH_MIN (30.0f)
+#define MAGNETIC_FIELD_EARTH_MIN (30.0f)
+
+/** Average sea level pressure is 1013.25 hPa */
+#define SENSORS_PRESSURE_SEALEVELHPA (1013.25F)
+
+/** Degrees/s to rad/s multiplier */
+#define SENSORS_DPS_TO_RADS (0.017453293F)
+/** Gauss to micro-Tesla multiplier */
+#define SENSORS_GAUSS_TO_MICROTESLA (100)
/**
* status of orientation sensor
@@ -772,6 +783,22 @@ typedef struct
} sensors_vec_t;
/**
+ * sensor raw vector data
+ */
+typedef struct
+{
+ struct
+ {
+ int16_t x;
+ int16_t y;
+ int16_t z;
+ };
+
+ int8_t status;
+ uint8_t reserved[1];
+} sensors_raw_vec_t;
+
+/**
* uncalibrated gyroscope and magnetometer event data
*/
typedef struct
@@ -833,15 +860,21 @@ typedef struct sensors_event_t
/* acceleration values are in meter per second per second (m/s^2) */
sensors_vec_t acceleration;
+ /* raw acceleration data */
+ sensors_raw_vec_t raw_acceleration;
/* magnetic vector values are in micro-Tesla (uT) */
sensors_vec_t magnetic;
+ /* raw magnetic data */
+ sensors_raw_vec_t raw_magnetic;
/* orientation values are in degrees */
sensors_vec_t orientation;
/* gyroscope values are in rad/s */
sensors_vec_t gyro;
+ /* raw gyroscope data */
+ sensors_raw_vec_t raw_gyro;
/* temperature is in degrees centigrade (Celsius) */
float temperature;
@@ -887,7 +920,6 @@ typedef sensors_event_t sensors_meta_data_event_t;
typedef struct sensor_t
{
-
/* Name of this sensor.
* All sensors of the same "type" must have a different "name".
*/
@@ -946,41 +978,111 @@ typedef struct sensor_t
void *reserved[6];
} sensor_t;
-class SensorConfigure
+enum SensorMode
+{
+ SENSOR_MODE_RAW,
+ SENSOR_MODE_CALIBRATED,
+ SENSOR_MODE_NORMAL,
+};
+
+enum SensorAccelRange
{
- int32_t delay;
+ SENSOR_ACCEL_RANGE_2G,
+ SENSOR_ACCEL_RANGE_4G,
+ SENSOR_ACCEL_RANGE_8G,
+ SENSOR_ACCEL_RANGE_16G,
};
+#define SENSOR_ACCEL_SENSITIVITY_2G (0.001F)
+#define SENSOR_ACCEL_SENSITIVITY_4G (0.002F)
+#define SENSOR_ACCEL_SENSITIVITY_8G (0.004F)
+#define SENSOR_ACCEL_SENSITIVITY_16G (0.012F)
-class Sensor;
+enum SensorGyroRange
+{
+ SENSOR_GYRO_RANGE_250DPS,
+ SENSOR_GYRO_RANGE_500DPS,
+ SENSOR_GYRO_RANGE_1000DPS,
+ SENSOR_GYRO_RANGE_2000DPS,
+};
+#define SENSOR_GYRO_SENSITIVITY_250DPS (0.00875F)
+#define SENSOR_GYRO_SENSITIVITY_500DPS (0.0175F)
+#define SENSOR_GYRO_SENSITIVITY_1000DPS (0.035F)
+#define SENSOR_GYRO_SENSITIVITY_2000DPS (0.070F)
+
+enum SensorDataRate
+{
+ SENSOR_DATARATE_3200HZ,
+ SENSOR_DATARATE_1600HZ,
+ SENSOR_DATARATE_800HZ,
+ SENSOR_DATARATE_400HZ,
+ SENSOR_DATARATE_200HZ,
+ SENSOR_DATARATE_100HZ,
+ SENSOR_DATARATE_50HZ,
+ SENSOR_DATARATE_25HZ,
+ SENSOR_DATARATE_12_5HZ,
+ SENSOR_DATARATE_6_25HZ,
+ SENSOR_DATARATE_3_13HZ,
+ SENSOR_DATARATE_1_56HZ,
+ SENSOR_DATARATE_0_78HZ,
+ SENSOR_DATARATE_0_39HZ,
+ SENSOR_DATARATE_0_20HZ,
+ SENSOR_DATARATE_0_10HZ,
+};
+
+/**
+ * Sensor Configuration
+ */
+typedef struct SensorConfig
+{
+ int mode;
+
+ enum SensorDataRate data_rate;
+
+ union range
+ {
+ enum SensorAccelRange accel_range;
+ enum SensorGyroRange gyro_range;
+ } range;
+}SensorConfig;
+
+typedef void (*SensorEventHandler_t)(sensors_event_t *event, void *user_data);
+
+#ifdef __cplusplus
+class SensorBase;
class SensorManager;
-typedef void (*SensorEventHandler_t)(Sensor *sensor, sensors_event_t *event, void *user_data);
/**
* Sensor Base Class
*/
-class Sensor
+class SensorBase
{
private:
int type;
public:
- Sensor();
- ~Sensor();
+ SensorBase(int type);
+ ~SensorBase();
- virtual int Configure(SensorConfigure *config) = 0;
- virtual int Activate(int enable) = 0;
+ virtual int configure(SensorConfig *config) = 0;
+ virtual int activate(int enable) = 0;
- virtual int Poll(sensors_event_t *events, int number, int duration) = 0;
- virtual void GetSensor(struct sensor_t *sensor) = 0;
+ virtual int poll(sensors_event_t *events) = 0;
+ virtual void getSensor(struct sensor_t *sensor) = 0;
- int GetType(void);
+ int getType(void);
- int Subscribe(SensorEventHandler_t *handler, void *user_data);
- int Publish(sensors_event_t *event);
+ int setConfig(SensorConfig *config);
+ int getConfig(SensorConfig *config);
+
+ int subscribe(SensorEventHandler_t *handler, void *user_data);
+ int publish(sensors_event_t *event);
protected:
- Sensor *next;
- Sensor *prev;
+ SensorBase *next;
+ SensorBase *prev;
+
+ /* sensor configuration */
+ SensorConfig config;
SensorEventHandler_t *evtHandler;
void *userData;
@@ -997,15 +1099,34 @@ public:
SensorManager();
~SensorManager();
- static int RegisterSensor(Sensor *sensor);
- static int DeregisterSensor(Sensor *sensor);
+ static int registerSensor(SensorBase *sensor);
+ static int unregisterSensor(SensorBase *sensor);
- static Sensor *GetDefaultSensor(int type);
- static int Subscribe(int type, SensorEventHandler_t *handler, void *user_data);
+ static SensorBase *getDefaultSensor(int type);
+ static int subscribe(int type, SensorEventHandler_t *handler, void *user_data);
-private:
- Sensor *sensorList;
+ static int sensorEventReady(SensorBase *sensor);
+ static int pollSensor(SensorBase *sensor, sensors_event_t *events, int number, int duration);
};
+#endif
+
+/* C programming language APIs */
+/* rt_sensor_t is a C typedef for SensorBase */
+typedef void* rt_sensor_t;
+#ifdef __cplusplus
+extern "C" {
#endif
+rt_sensor_t rt_sensor_get_default(int type);
+
+int rt_sensor_subscribe(rt_sensor_t sensor, SensorEventHandler_t *handler, void *user_data);
+int rt_sensor_activate (rt_sensor_t sensor, int enable);
+int rt_sensor_configure(rt_sensor_t sensor, SensorConfig *config);
+int rt_sensor_poll(rt_sensor_t sensor, sensors_event_t *event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/components/drivers/serial/serial.c b/components/drivers/serial/serial.c
index f04b1df4f4..bcdd4db519 100644
--- a/components/drivers/serial/serial.c
+++ b/components/drivers/serial/serial.c
@@ -26,6 +26,7 @@
* 2013-02-20 bernard use RT_SERIAL_RB_BUFSZ to define
* the size of ring buffer.
* 2014-07-10 bernard rewrite serial framework
+ * 2014-12-31 bernard use open_flag for poll_tx stream mode.
*/
#include <rthw.h>
@@ -67,7 +68,7 @@ rt_inline int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t
* to be polite with serial console add a line feed
* to the carriage return character
*/
- if (*data == '\n' && (serial->parent.flag & RT_DEVICE_FLAG_STREAM))
+ if (*data == '\n' && (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM))
{
serial->ops->putc(serial, '\r');
}
diff --git a/components/drivers/src/ringbuffer.c b/components/drivers/src/ringbuffer.c
index 6212b10258..8c2705ceb1 100644
--- a/components/drivers/src/ringbuffer.c
+++ b/components/drivers/src/ringbuffer.c
@@ -100,13 +100,13 @@ rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb,
const rt_uint8_t *ptr,
rt_uint16_t length)
{
- enum rt_ringbuffer_state old_state;
+ rt_uint16_t space_length;
RT_ASSERT(rb != RT_NULL);
- old_state = rt_ringbuffer_status(rb);
+ space_length = rt_ringbuffer_space_len(rb);
- if (length > rb->buffer_size)
+ if (length > space_length)
length = rb->buffer_size;
if (rb->buffer_size - rb->write_index > length)
@@ -117,7 +117,7 @@ rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb,
* length of data in current mirror */
rb->write_index += length;
- if (old_state == RT_RINGBUFFER_FULL)
+ if (length > space_length)
rb->read_index = rb->write_index;
return length;
@@ -134,7 +134,7 @@ rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb,
rb->write_mirror = ~rb->write_mirror;
rb->write_index = length - (rb->buffer_size - rb->write_index);
- if (old_state == RT_RINGBUFFER_FULL)
+ if (length > space_length)
{
rb->read_mirror = ~rb->read_mirror;
rb->read_index = rb->write_index;