summaryrefslogtreecommitdiff
path: root/components/drivers
diff options
context:
space:
mode:
author陈豪 | Jacob Chen <[email protected]>2015-03-29 18:35:44 +0800
committer陈豪 | Jacob Chen <[email protected]>2015-03-29 18:35:44 +0800
commit9a4dacaad743801c9be2dbae49251c4e1b8f99a9 (patch)
tree34def3bef5c5fc4a9b7594eba5a2729f8c86aab0 /components/drivers
parentdaac5388afe5a18d51e9839719de8423b62b00c1 (diff)
parent5af7abd8c2e8b8a39c0bf096bdf9b5cb08f266fa (diff)
Merge pull request #3 from RT-Thread/master
111
Diffstat (limited to 'components/drivers')
-rw-r--r--components/drivers/i2c/i2c_core.c11
-rw-r--r--components/drivers/include/drivers/pin.h79
-rw-r--r--components/drivers/include/drivers/serial.h5
-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/SConscript17
-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.cpp232
-rw-r--r--components/drivers/sensors/sensor.h1132
-rw-r--r--components/drivers/serial/serial.c5
-rw-r--r--components/drivers/spi/spi_wifi_rw009.c611
-rw-r--r--components/drivers/spi/spi_wifi_rw009.h171
-rw-r--r--components/drivers/src/completion.c4
-rw-r--r--components/drivers/src/ringbuffer.c10
-rw-r--r--components/drivers/usb/usbhost/class/adk.c6
-rw-r--r--components/drivers/usb/usbhost/core/core.c10
-rw-r--r--components/drivers/usb/usbhost/core/hub.c10
21 files changed, 3632 insertions, 255 deletions
diff --git a/components/drivers/i2c/i2c_core.c b/components/drivers/i2c/i2c_core.c
index f274f70fcd..09616235d1 100644
--- a/components/drivers/i2c/i2c_core.c
+++ b/components/drivers/i2c/i2c_core.c
@@ -24,8 +24,6 @@
#include <rtdevice.h>
-static struct rt_mutex i2c_core_lock;
-
rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
const char *bus_name)
{
@@ -33,17 +31,12 @@ rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
rt_mutex_init(&bus->lock, "i2c_bus_lock", RT_IPC_FLAG_FIFO);
- rt_mutex_take(&i2c_core_lock, RT_WAITING_FOREVER);
-
- if (bus->timeout == 0)
- bus->timeout = RT_TICK_PER_SECOND;
+ if (bus->timeout == 0) bus->timeout = RT_TICK_PER_SECOND;
res = rt_i2c_bus_device_device_init(bus, bus_name);
i2c_dbg("I2C bus [%s] registered\n", bus_name);
- rt_mutex_release(&i2c_core_lock);
-
return res;
}
@@ -136,6 +129,6 @@ rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus,
int rt_i2c_core_init(void)
{
- return rt_mutex_init(&i2c_core_lock, "i2c_core_lock", RT_IPC_FLAG_FIFO);
+ return 0;
}
INIT_COMPONENT_EXPORT(rt_i2c_core_init);
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/drivers/serial.h b/components/drivers/include/drivers/serial.h
index bf2a25ae1e..3b0a009072 100644
--- a/components/drivers/include/drivers/serial.h
+++ b/components/drivers/include/drivers/serial.h
@@ -65,11 +65,6 @@
#define RT_SERIAL_RB_BUFSZ 64
#endif
-#define RT_DEVICE_CTRL_CONFIG 0x03 /* configure device */
-#define RT_DEVICE_CTRL_SET_INT 0x10 /* enable receive irq */
-#define RT_DEVICE_CTRL_CLR_INT 0x11 /* disable receive irq */
-#define RT_DEVICE_CTRL_GET_INT 0x12
-
#define RT_SERIAL_EVENT_RX_IND 0x01 /* Rx indication */
#define RT_SERIAL_EVENT_TX_DONE 0x02 /* Tx complete */
#define RT_SERIAL_EVENT_RX_DMADONE 0x03 /* Rx DMA transfer done */
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..f3577a11d5
--- /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, name, 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
new file mode 100644
index 0000000000..db409cfd2b
--- /dev/null
+++ b/components/drivers/sensors/SConscript
@@ -0,0 +1,17 @@
+# SConscript for sensor framework
+
+from building import *
+
+cwd = GetCurrentDir()
+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
new file mode 100644
index 0000000000..18eb8eee18
--- /dev/null
+++ b/components/drivers/sensors/sensor.cpp
@@ -0,0 +1,232 @@
+/*
+ * 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"
+
+/**
+ * SensorBase
+ */
+SensorBase::SensorBase(int type)
+{
+ memset(&(this->config), 0x0, sizeof(SensorConfig));
+
+ this->type = type;
+ this->next = this->prev = NULL;
+ subscribe(NULL, NULL);
+}
+
+SensorBase::~SensorBase()
+{
+}
+
+int SensorBase::getType(void)
+{
+ return this->type;
+}
+
+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;
+
+ return 0;
+}
+
+int SensorBase::publish(sensors_event_t *event)
+{
+ if (this->evtHandler != NULL)
+ {
+ /* invoke subscribed handler */
+ (*evtHandler)(event, this->userData);
+ }
+
+ return 0;
+}
+
+/**
+ * Sensor Manager
+ */
+/* sensors list */
+static SensorBase *sensor_list = NULL;
+
+SensorManager::SensorManager()
+{
+}
+
+SensorManager::~SensorManager()
+{
+}
+
+int SensorManager::registerSensor(SensorBase *sensor)
+{
+ RT_ASSERT(sensor != RT_NULL);
+
+ /* add sensor into the list */
+ if (sensor_list == NULL)
+ {
+ sensor->prev = sensor->next = sensor;
+ }
+ else
+ {
+ sensor_list->prev->next = sensor;
+ sensor->prev = sensor_list->prev;
+
+ sensor_list->prev = sensor;
+ sensor->next = sensor_list;
+ }
+
+ /* point the sensorList to this sensor */
+ sensor_list = sensor;
+
+ return 0;
+}
+
+int SensorManager::unregisterSensor(SensorBase *sensor)
+{
+ /* disconnect sensor list */
+ sensor->next->prev = sensor->prev;
+ sensor->prev->next = sensor->next;
+
+ /* check the sensorList */
+ if (sensor == sensor_list)
+ {
+ if (sensor->next == sensor) sensor_list = NULL; /* empty list */
+ else sensor_list = sensor->next;
+ }
+
+ /* re-initialize sensor node */
+ sensor->next = sensor->prev = sensor;
+
+ return 0;
+}
+
+SensorBase *SensorManager::getDefaultSensor(int type)
+{
+ SensorBase *sensor = sensor_list;
+
+ if (sensor == NULL) return NULL;
+
+ do
+ {
+ /* find the same type */
+ if (sensor->getType() == type) return sensor;
+
+ sensor = sensor->next;
+ }while (sensor != sensor_list);
+
+ return NULL;
+}
+
+int SensorManager::subscribe(int type, SensorEventHandler_t *handler, void *user_data)
+{
+ SensorBase *sensor;
+
+ sensor = SensorManager::getDefaultSensor(type);
+ if (sensor != NULL)
+ {
+ 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
new file mode 100644
index 0000000000..2962b21a80
--- /dev/null
+++ b/components/drivers/sensors/sensor.h
@@ -0,0 +1,1132 @@
+/*
+ * File : sensors.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-08-03 Bernard the first version
+ */
+
+/* Modified from: https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h */
+
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef SENSORS_H__
+#define SENSORS_H__
+
+#include <rtdevice.h>
+#include <stdint.h>
+
+#ifdef __CC_ARM /* skip warning in armcc */
+#pragma anon_unions
+#endif
+
+/**
+ * Handles must be higher than SENSORS_HANDLE_BASE and must be unique.
+ * A Handle identifies a given sensors. The handle is used to activate
+ * and/or deactivate sensors.
+ * In this version of the API there can only be 256 handles.
+ */
+#define SENSORS_HANDLE_BASE 0
+#define SENSORS_HANDLE_BITS 8
+#define SENSORS_HANDLE_COUNT (1<<SENSORS_HANDLE_BITS)
+
+
+/*
+ * flags for (*batch)()
+ * Availability: SENSORS_DEVICE_API_VERSION_1_0
+ * see (*batch)() documentation for details
+ */
+enum
+{
+ SENSORS_BATCH_DRY_RUN = 0x00000001,
+ SENSORS_BATCH_WAKE_UPON_FIFO_FULL = 0x00000002
+};
+
+/*
+ * what field for meta_data_event_t
+ */
+enum
+{
+ /* a previous flush operation has completed */
+ META_DATA_FLUSH_COMPLETE = 1,
+ META_DATA_VERSION /* always last, leave auto-assigned */
+};
+
+/**
+ * Definition of the axis used by the sensor HAL API
+ *
+ * This API is relative to the screen of the device in its default orientation,
+ * that is, if the device can be used in portrait or landscape, this API
+ * is only relative to the NATURAL orientation of the screen. In other words,
+ * the axis are not swapped when the device's screen orientation changes.
+ * Higher level services /may/ perform this transformation.
+ *
+ * x<0 x>0
+ * ^
+ * |
+ * +-----------+--> y>0
+ * | |
+ * | |
+ * | |
+ * | | / z<0
+ * | | /
+ * | | /
+ * O-----------+/
+ * |[] [ ] []/
+ * +----------/+ y<0
+ * /
+ * /
+ * |/ z>0 (toward the sky)
+ *
+ * O: Origin (x=0,y=0,z=0)
+ *
+ */
+
+/*
+ * Interaction with suspend mode
+ *
+ * Unless otherwise noted, an enabled sensor shall not prevent the
+ * SoC to go into suspend mode. It is the responsibility of applications
+ * to keep a partial wake-lock should they wish to receive sensor
+ * events while the screen is off. While in suspend mode, and unless
+ * otherwise noted (batch mode, sensor particularities, ...), enabled sensors'
+ * events are lost.
+ *
+ * Note that conceptually, the sensor itself is not de-activated while in
+ * suspend mode -- it's just that the data it returns are lost. As soon as
+ * the SoC gets out of suspend mode, operations resume as usual. Of course,
+ * in practice sensors shall be disabled while in suspend mode to
+ * save power, unless batch mode is active, in which case they must
+ * continue fill their internal FIFO (see the documentation of batch() to
+ * learn how suspend interacts with batch mode).
+ *
+ * In batch mode, and only when the flag SENSORS_BATCH_WAKE_UPON_FIFO_FULL is
+ * set and supported, the specified sensor must be able to wake-up the SoC and
+ * be able to buffer at least 10 seconds worth of the requested sensor events.
+ *
+ * There are notable exceptions to this behavior, which are sensor-dependent
+ * (see sensor types definitions below)
+ *
+ *
+ * The sensor type documentation below specifies the wake-up behavior of
+ * each sensor:
+ * wake-up: yes this sensor must wake-up the SoC to deliver events
+ * wake-up: no this sensor shall not wake-up the SoC, events are dropped
+ *
+ */
+
+/*
+ * Sensor type
+ *
+ * Each sensor has a type which defines what this sensor measures and how
+ * measures are reported. All types are defined below.
+ *
+ * Device manufacturers (OEMs) can define their own sensor types, for
+ * their private use by applications or services provided by them. Such
+ * sensor types are specific to an OEM and can't be exposed in the SDK.
+ * These types must start at SENSOR_TYPE_DEVICE_PRIVATE_BASE.
+ */
+
+/*
+ * Base for device manufacturers private sensor types.
+ * These sensor types can't be exposed in the SDK.
+ */
+#define SENSOR_TYPE_DEVICE_PRIVATE_BASE 0x10000
+
+/*
+ * Sensor fusion and virtual sensors
+ *
+ * Many sensor types are or can be implemented as virtual sensors from
+ * physical sensors on the device. For instance the rotation vector sensor,
+ * orientation sensor, step-detector, step-counter, etc...
+ *
+ * From the point of view of this API these virtual sensors MUST appear as
+ * real, individual sensors. It is the responsibility of the driver and HAL
+ * to make sure this is the case.
+ *
+ * In particular, all sensors must be able to function concurrently.
+ * For example, if defining both an accelerometer and a step counter,
+ * then both must be able to work concurrently.
+ */
+
+/*
+ * Trigger modes
+ *
+ * Sensors can report events in different ways called trigger modes,
+ * each sensor type has one and only one trigger mode associated to it.
+ * Currently there are four trigger modes defined:
+ *
+ * continuous: events are reported at a constant rate defined by setDelay().
+ * eg: accelerometers, gyroscopes.
+ * on-change: events are reported only if the sensor's value has changed.
+ * setDelay() is used to set a lower limit to the reporting
+ * period (minimum time between two events).
+ * The HAL must return an event immediately when an on-change
+ * sensor is activated.
+ * eg: proximity, light sensors
+ * one-shot: upon detection of an event, the sensor deactivates itself and
+ * then sends a single event. Order matters to avoid race
+ * conditions. No other event is sent until the sensor get
+ * reactivated. setDelay() is ignored.
+ * eg: significant motion sensor
+ * special: see details in the sensor type specification below
+ *
+ */
+
+/*
+ * SENSOR_TYPE_META_DATA
+ * trigger-mode: n/a
+ * wake-up sensor: n/a
+ *
+ * NO SENSOR OF THAT TYPE MUST BE RETURNED (*get_sensors_list)()
+ *
+ * SENSOR_TYPE_META_DATA is a special token used to populate the
+ * sensors_meta_data_event structure. It doesn't correspond to a physical
+ * sensor. sensors_meta_data_event are special, they exist only inside
+ * the HAL and are generated spontaneously, as opposed to be related to
+ * a physical sensor.
+ *
+ * sensors_meta_data_event_t.version must be META_DATA_VERSION
+ * sensors_meta_data_event_t.sensor must be 0
+ * sensors_meta_data_event_t.type must be SENSOR_TYPE_META_DATA
+ * sensors_meta_data_event_t.reserved must be 0
+ * sensors_meta_data_event_t.timestamp must be 0
+ *
+ * The payload is a meta_data_event_t, where:
+ * meta_data_event_t.what can take the following values:
+ *
+ * META_DATA_FLUSH_COMPLETE
+ * This event indicates that a previous (*flush)() call has completed for the sensor
+ * handle specified in meta_data_event_t.sensor.
+ * see (*flush)() for more details
+ *
+ * All other values for meta_data_event_t.what are reserved and
+ * must not be used.
+ *
+ */
+#define SENSOR_TYPE_META_DATA (0)
+
+/*
+ * SENSOR_TYPE_ACCELEROMETER
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * All values are in SI units (m/s^2) and measure the acceleration of the
+ * device minus the force of gravity.
+ *
+ * Acceleration sensors return sensor events for all 3 axes at a constant
+ * rate defined by setDelay().
+ *
+ * x: Acceleration on the x-axis
+ * y: Acceleration on the y-axis
+ * z: Acceleration on the z-axis
+ *
+ * Note that the readings from the accelerometer include the acceleration
+ * due to gravity (which is opposite to the direction of the gravity vector).
+ *
+ * Examples:
+ * The norm of <x, y, z> should be close to 0 when in free fall.
+ *
+ * When the device lies flat on a table and is pushed on its left side
+ * toward the right, the x acceleration value is positive.
+ *
+ * When the device lies flat on a table, the acceleration value is +9.81,
+ * which correspond to the acceleration of the device (0 m/s^2) minus the
+ * force of gravity (-9.81 m/s^2).
+ *
+ * When the device lies flat on a table and is pushed toward the sky, the
+ * acceleration value is greater than +9.81, which correspond to the
+ * acceleration of the device (+A m/s^2) minus the force of
+ * gravity (-9.81 m/s^2).
+ */
+#define SENSOR_TYPE_ACCELEROMETER (1)
+
+/*
+ * SENSOR_TYPE_GEOMAGNETIC_FIELD
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * All values are in micro-Tesla (uT) and measure the geomagnetic
+ * field in the X, Y and Z axis.
+ *
+ * Returned values include calibration mechanisms such that the vector is
+ * aligned with the magnetic declination and heading of the earth's
+ * geomagnetic field.
+ *
+ * Magnetic Field sensors return sensor events for all 3 axes at a constant
+ * rate defined by setDelay().
+ */
+#define SENSOR_TYPE_GEOMAGNETIC_FIELD (2)
+#define SENSOR_TYPE_MAGNETIC_FIELD SENSOR_TYPE_GEOMAGNETIC_FIELD
+
+/*
+ * SENSOR_TYPE_ORIENTATION
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * All values are angles in degrees.
+ *
+ * Orientation sensors return sensor events for all 3 axes at a constant
+ * rate defined by setDelay().
+ *
+ * azimuth: angle between the magnetic north direction and the Y axis, around
+ * the Z axis (0<=azimuth<360).
+ * 0=North, 90=East, 180=South, 270=West
+ *
+ * pitch: Rotation around X axis (-180<=pitch<=180), with positive values when
+ * the z-axis moves toward the y-axis.
+ *
+ * roll: Rotation around Y axis (-90<=roll<=90), with positive values when
+ * the x-axis moves towards the z-axis.
+ *
+ * Note: For historical reasons the roll angle is positive in the clockwise
+ * direction (mathematically speaking, it should be positive in the
+ * counter-clockwise direction):
+ *
+ * Z
+ * ^
+ * (+roll) .--> |
+ * / |
+ * | | roll: rotation around Y axis
+ * X <-------(.)
+ * Y
+ * note that +Y == -roll
+ *
+ *
+ *
+ * Note: This definition is different from yaw, pitch and roll used in aviation
+ * where the X axis is along the long side of the plane (tail to nose).
+ */
+#define SENSOR_TYPE_ORIENTATION (3)
+
+/*
+ * SENSOR_TYPE_GYROSCOPE
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * All values are in radians/second and measure the rate of rotation
+ * around the X, Y and Z axis. The coordinate system is the same as is
+ * used for the acceleration sensor. Rotation is positive in the
+ * counter-clockwise direction (right-hand rule). That is, an observer
+ * looking from some positive location on the x, y or z axis at a device
+ * positioned on the origin would report positive rotation if the device
+ * appeared to be rotating counter clockwise. Note that this is the
+ * standard mathematical definition of positive rotation and does not agree
+ * with the definition of roll given earlier.
+ * The range should at least be 17.45 rad/s (ie: ~1000 deg/s).
+ *
+ * automatic gyro-drift compensation is allowed but not required.
+ */
+#define SENSOR_TYPE_GYROSCOPE (4)
+
+/*
+ * SENSOR_TYPE_LIGHT
+ * trigger-mode: on-change
+ * wake-up sensor: no
+ *
+ * The light sensor value is returned in SI lux units.
+ */
+#define SENSOR_TYPE_LIGHT (5)
+
+/*
+ * SENSOR_TYPE_PRESSURE
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * The pressure sensor return the athmospheric pressure in hectopascal (hPa)
+ */
+#define SENSOR_TYPE_PRESSURE (6)
+
+/* SENSOR_TYPE_TEMPERATURE is deprecated in the HAL */
+#define SENSOR_TYPE_TEMPERATURE (7)
+
+/*
+ * SENSOR_TYPE_PROXIMITY
+ * trigger-mode: on-change
+ * wake-up sensor: yes
+ *
+ * The distance value is measured in centimeters. Note that some proximity
+ * sensors only support a binary "close" or "far" measurement. In this case,
+ * the sensor should report its maxRange value in the "far" state and a value
+ * less than maxRange in the "near" state.
+ */
+#define SENSOR_TYPE_PROXIMITY (8)
+
+/*
+ * SENSOR_TYPE_GRAVITY
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * A gravity output indicates the direction of and magnitude of gravity in
+ * the devices's coordinates. On Earth, the magnitude is 9.8 m/s^2.
+ * Units are m/s^2. The coordinate system is the same as is used for the
+ * acceleration sensor. When the device is at rest, the output of the
+ * gravity sensor should be identical to that of the accelerometer.
+ */
+#define SENSOR_TYPE_GRAVITY (9)
+
+/*
+ * SENSOR_TYPE_LINEAR_ACCELERATION
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * Indicates the linear acceleration of the device in device coordinates,
+ * not including gravity.
+ *
+ * The output is conceptually:
+ * output of TYPE_ACCELERATION - output of TYPE_GRAVITY
+ *
+ * Readings on all axes should be close to 0 when device lies on a table.
+ * Units are m/s^2.
+ * The coordinate system is the same as is used for the acceleration sensor.
+ */
+#define SENSOR_TYPE_LINEAR_ACCELERATION (10)
+
+/*
+ * SENSOR_TYPE_ROTATION_VECTOR
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * The rotation vector symbolizes the orientation of the device relative to the
+ * East-North-Up coordinates frame. It is usually obtained by integration of
+ * accelerometer, gyroscope and magnetometer readings.
+ *
+ * The East-North-Up coordinate system is defined as a direct orthonormal basis
+ * where:
+ * - X points east and is tangential to the ground.
+ * - Y points north and is tangential to the ground.
+ * - Z points towards the sky and is perpendicular to the ground.
+ *
+ * The orientation of the phone is represented by the rotation necessary to
+ * align the East-North-Up coordinates with the phone's coordinates. That is,
+ * applying the rotation to the world frame (X,Y,Z) would align them with the
+ * phone coordinates (x,y,z).
+ *
+ * The rotation can be seen as rotating the phone by an angle theta around
+ * an axis rot_axis to go from the reference (East-North-Up aligned) device
+ * orientation to the current device orientation.
+ *
+ * The rotation is encoded as the 4 (reordered) components of a unit quaternion:
+ * sensors_event_t.data[0] = rot_axis.x*sin(theta/2)
+ * sensors_event_t.data[1] = rot_axis.y*sin(theta/2)
+ * sensors_event_t.data[2] = rot_axis.z*sin(theta/2)
+ * sensors_event_t.data[3] = cos(theta/2)
+ * where
+ * - rot_axis.x,y,z are the North-East-Up coordinates of a unit length vector
+ * representing the rotation axis
+ * - theta is the rotation angle
+ *
+ * The quaternion must be of norm 1 (it is a unit quaternion). Failure to ensure
+ * this will cause erratic client behaviour.
+ *
+ * In addition, this sensor reports an estimated heading accuracy.
+ * sensors_event_t.data[4] = estimated_accuracy (in radians)
+ * The heading error must be less than estimated_accuracy 95% of the time
+ *
+ * This sensor must use a gyroscope and an accelerometer as main orientation
+ * change input.
+ *
+ * This sensor can also include magnetometer input to make up for gyro drift,
+ * but it cannot be implemented using only a magnetometer.
+ */
+#define SENSOR_TYPE_ROTATION_VECTOR (11)
+
+/*
+ * SENSOR_TYPE_RELATIVE_HUMIDITY
+ * trigger-mode: on-change
+ * wake-up sensor: no
+ *
+ * A relative humidity sensor measures relative ambient air humidity and
+ * returns a value in percent.
+ */
+#define SENSOR_TYPE_RELATIVE_HUMIDITY (12)
+
+/*
+ * SENSOR_TYPE_AMBIENT_TEMPERATURE
+ * trigger-mode: on-change
+ * wake-up sensor: no
+ *
+ * The ambient (room) temperature in degree Celsius.
+ */
+#define SENSOR_TYPE_AMBIENT_TEMPERATURE (13)
+
+/*
+ * SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * Similar to SENSOR_TYPE_MAGNETIC_FIELD, but the hard iron calibration is
+ * reported separately instead of being included in the measurement.
+ * Factory calibration and temperature compensation should still be applied to
+ * the "uncalibrated" measurement.
+ * Separating away the hard iron calibration estimation allows the system to
+ * better recover from bad hard iron estimation.
+ *
+ * All values are in micro-Tesla (uT) and measure the ambient magnetic
+ * field in the X, Y and Z axis. Assumptions that the the magnetic field
+ * is due to the Earth's poles should be avoided.
+ *
+ * The uncalibrated_magnetic event contains
+ * - 3 fields for uncalibrated measurement: x_uncalib, y_uncalib, z_uncalib.
+ * Each is a component of the measured magnetic field, with soft iron
+ * and temperature compensation applied, but not hard iron calibration.
+ * These values should be continuous (no re-calibration should cause a jump).
+ * - 3 fields for hard iron bias estimates: x_bias, y_bias, z_bias.
+ * Each field is a component of the estimated hard iron calibration.
+ * They represent the offsets to apply to the calibrated readings to obtain
+ * uncalibrated readings (x_uncalib ~= x_calibrated + x_bias)
+ * These values are expected to jump as soon as the estimate of the hard iron
+ * changes, and they should be stable the rest of the time.
+ *
+ * If this sensor is present, then the corresponding
+ * SENSOR_TYPE_MAGNETIC_FIELD must be present and both must return the
+ * same sensor_t::name and sensor_t::vendor.
+ *
+ * Minimum filtering should be applied to this sensor. In particular, low pass
+ * filters should be avoided.
+ *
+ * See SENSOR_TYPE_MAGNETIC_FIELD for more information
+ */
+#define SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED (14)
+
+/*
+ * SENSOR_TYPE_GAME_ROTATION_VECTOR
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * Similar to SENSOR_TYPE_ROTATION_VECTOR, but not using the geomagnetic
+ * field. Therefore the Y axis doesn't point north, but instead to some other
+ * reference. That reference is allowed to drift by the same order of
+ * magnitude than the gyroscope drift around the Z axis.
+ *
+ * This sensor does not report an estimated heading accuracy:
+ * sensors_event_t.data[4] is reserved and should be set to 0
+ *
+ * In the ideal case, a phone rotated and returning to the same real-world
+ * orientation should report the same game rotation vector
+ * (without using the earth's geomagnetic field).
+ *
+ * This sensor must be based on a gyroscope. It cannot be implemented using
+ * a magnetometer.
+ *
+ * see SENSOR_TYPE_ROTATION_VECTOR for more details
+ */
+#define SENSOR_TYPE_GAME_ROTATION_VECTOR (15)
+
+/*
+ * SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * All values are in radians/second and measure the rate of rotation
+ * around the X, Y and Z axis. An estimation of the drift on each axis is
+ * reported as well.
+ *
+ * No gyro-drift compensation shall be performed.
+ * Factory calibration and temperature compensation should still be applied
+ * to the rate of rotation (angular speeds).
+ *
+ * The coordinate system is the same as is
+ * used for the acceleration sensor. Rotation is positive in the
+ * counter-clockwise direction (right-hand rule). That is, an observer
+ * looking from some positive location on the x, y or z axis at a device
+ * positioned on the origin would report positive rotation if the device
+ * appeared to be rotating counter clockwise. Note that this is the
+ * standard mathematical definition of positive rotation and does not agree
+ * with the definition of roll given earlier.
+ * The range should at least be 17.45 rad/s (ie: ~1000 deg/s).
+ *
+ * Content of an uncalibrated_gyro event: (units are rad/sec)
+ * x_uncalib : angular speed (w/o drift compensation) around the X axis
+ * y_uncalib : angular speed (w/o drift compensation) around the Y axis
+ * z_uncalib : angular speed (w/o drift compensation) around the Z axis
+ * x_bias : estimated drift around X axis in rad/s
+ * y_bias : estimated drift around Y axis in rad/s
+ * z_bias : estimated drift around Z axis in rad/s
+ *
+ * IMPLEMENTATION NOTES:
+ *
+ * If the implementation is not able to estimate the drift, then this
+ * sensor MUST NOT be reported by this HAL. Instead, the regular
+ * SENSOR_TYPE_GYROSCOPE is used without drift compensation.
+ *
+ * If this sensor is present, then the corresponding
+ * SENSOR_TYPE_GYROSCOPE must be present and both must return the
+ * same sensor_t::name and sensor_t::vendor.
+ */
+#define SENSOR_TYPE_GYROSCOPE_UNCALIBRATED (16)
+
+/*
+ * SENSOR_TYPE_SIGNIFICANT_MOTION
+ * trigger-mode: one-shot
+ * wake-up sensor: yes
+ *
+ * A sensor of this type triggers an event each time significant motion
+ * is detected and automatically disables itself.
+ * The only allowed value to return is 1.0.
+ *
+ * A significant motion is a motion that might lead to a change in the user
+ * location.
+ * Examples of such motions are:
+ * walking, biking, sitting in a moving car, coach or train.
+ * Examples of situations that should not trigger significant motion:
+ * - phone in pocket and person is not moving
+ * - phone is on a table, even if the table shakes a bit due to nearby traffic
+ * or washing machine
+ *
+ * A note on false positive / false negative / power consumption tradeoff
+ * - The goal of this sensor is to save power.
+ * - Triggering an event when the user is not moving (false positive) is costly
+ * in terms of power, so it should be avoided.
+ * - Not triggering an event when the user is moving (false negative) is
+ * acceptable as long as it is not done repeatedly. If the user has been
+ * walking for 10 seconds, not triggering an event within those 10 seconds
+ * is not acceptable.
+ *
+ * IMPORTANT NOTE: this sensor type is very different from other types
+ * in that it must work when the screen is off without the need of
+ * holding a partial wake-lock and MUST allow the SoC to go into suspend.
+ * When significant motion is detected, the sensor must awaken the SoC and
+ * the event be reported.
+ *
+ * If a particular hardware cannot support this mode of operation then this
+ * sensor type MUST NOT be reported by the HAL. ie: it is not acceptable
+ * to "emulate" this sensor in the HAL.
+ *
+ * The whole point of this sensor type is to save power by keeping the
+ * SoC in suspend mode when the device is at rest.
+ *
+ * When the sensor is not activated, it must also be deactivated in the
+ * hardware: it must not wake up the SoC anymore, even in case of
+ * significant motion.
+ *
+ * setDelay() has no effect and is ignored.
+ * Once a "significant motion" event is returned, a sensor of this type
+ * must disables itself automatically, as if activate(..., 0) had been called.
+ */
+
+#define SENSOR_TYPE_SIGNIFICANT_MOTION (17)
+
+/*
+ * SENSOR_TYPE_STEP_DETECTOR
+ * trigger-mode: special
+ * wake-up sensor: no
+ *
+ * A sensor of this type triggers an event each time a step is taken
+ * by the user. The only allowed value to return is 1.0 and an event is
+ * generated for each step. Like with any other event, the timestamp
+ * indicates when the event (here the step) occurred, this corresponds to when
+ * the foot hit the ground, generating a high variation in acceleration.
+ *
+ * While this sensor operates, it shall not disrupt any other sensors, in
+ * particular, but not limited to, the accelerometer; which might very well
+ * be in use as well.
+ *
+ * This sensor must be low power. That is, if the step detection cannot be
+ * done in hardware, this sensor should not be defined. Also, when the
+ * step detector is activated and the accelerometer is not, only steps should
+ * trigger interrupts (not accelerometer data).
+ *
+ * setDelay() has no impact on this sensor type
+ */
+
+#define SENSOR_TYPE_STEP_DETECTOR (18)
+
+/*
+ * SENSOR_TYPE_STEP_COUNTER
+ * trigger-mode: on-change
+ * wake-up sensor: no
+ *
+ * A sensor of this type returns the number of steps taken by the user since
+ * the last reboot while activated. The value is returned as a uint64_t and is
+ * reset to zero only on a system / android reboot.
+ *
+ * The timestamp of the event is set to the time when the first step
+ * for that event was taken.
+ * See SENSOR_TYPE_STEP_DETECTOR for the signification of the time of a step.
+ *
+ * The minimum size of the hardware's internal counter shall be 16 bits
+ * (this restriction is here to avoid too frequent wake-ups when the
+ * delay is very large).
+ *
+ * IMPORTANT NOTE: this sensor type is different from other types
+ * in that it must work when the screen is off without the need of
+ * holding a partial wake-lock and MUST allow the SoC to go into suspend.
+ * Unlike other sensors, while in suspend mode this sensor must stay active,
+ * no events are reported during that time but, steps continue to be
+ * accounted for; an event will be reported as soon as the SoC resumes if
+ * the timeout has expired.
+ *
+ * In other words, when the screen is off and the device allowed to
+ * go into suspend mode, we don't want to be woken up, regardless of the
+ * setDelay() value, but the steps shall continue to be counted.
+ *
+ * The driver must however ensure that the internal step count never
+ * overflows. It is allowed in this situation to wake the SoC up so the
+ * driver can do the counter maintenance.
+ *
+ * While this sensor operates, it shall not disrupt any other sensors, in
+ * particular, but not limited to, the accelerometer; which might very well
+ * be in use as well.
+ *
+ * If a particular hardware cannot support these modes of operation then this
+ * sensor type MUST NOT be reported by the HAL. ie: it is not acceptable
+ * to "emulate" this sensor in the HAL.
+ *
+ * This sensor must be low power. That is, if the step detection cannot be
+ * done in hardware, this sensor should not be defined. Also, when the
+ * step counter is activated and the accelerometer is not, only steps should
+ * trigger interrupts (not accelerometer data).
+ *
+ * The whole point of this sensor type is to save power by keeping the
+ * SoC in suspend mode when the device is at rest.
+ */
+
+#define SENSOR_TYPE_STEP_COUNTER (19)
+
+/*
+ * SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR
+ * trigger-mode: continuous
+ * wake-up sensor: no
+ *
+ * Similar to SENSOR_TYPE_ROTATION_VECTOR, but using a magnetometer instead
+ * of using a gyroscope.
+ *
+ * This sensor must be based on a magnetometer. It cannot be implemented using
+ * a gyroscope, and gyroscope input cannot be used by this sensor, as the
+ * goal of this sensor is to be low power.
+ * The accelerometer can be (and usually is) used.
+ *
+ * Just like SENSOR_TYPE_ROTATION_VECTOR, this sensor reports an estimated
+ * heading accuracy:
+ * sensors_event_t.data[4] = estimated_accuracy (in radians)
+ * The heading error must be less than estimated_accuracy 95% of the time
+ *
+ * see SENSOR_TYPE_ROTATION_VECTOR for more details
+ */
+#define SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR (20)
+
+/**
+ * Values returned by the accelerometer in various locations in the universe.
+ * all values are in SI units (m/s^2)
+ */
+#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)
+
+/** Minimum magnetic field on Earth's surface */
+#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
+ */
+#define SENSOR_STATUS_UNRELIABLE 0
+#define SENSOR_STATUS_ACCURACY_LOW 1
+#define SENSOR_STATUS_ACCURACY_MEDIUM 2
+#define SENSOR_STATUS_ACCURACY_HIGH 3
+
+/**
+ * sensor event data
+ */
+typedef struct
+{
+ union
+ {
+ float v[3];
+ struct
+ {
+ float x;
+ float y;
+ float z;
+ };
+ struct
+ {
+ float azimuth;
+ float pitch;
+ float roll;
+ };
+ };
+ int8_t status;
+ uint8_t reserved[3];
+} 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
+{
+ union
+ {
+ float uncalib[3];
+ struct
+ {
+ float x_uncalib;
+ float y_uncalib;
+ float z_uncalib;
+ };
+ };
+ union
+ {
+ float bias[3];
+ struct
+ {
+ float x_bias;
+ float y_bias;
+ float z_bias;
+ };
+ };
+} uncalibrated_event_t;
+
+typedef struct meta_data_event
+{
+ int32_t what;
+ int32_t sensor;
+} meta_data_event_t;
+
+/**
+ * Union of the various types of sensor data
+ * that can be returned.
+ */
+typedef struct sensors_event_t
+{
+ /* must be sizeof(struct sensors_event_t) */
+ int32_t version;
+
+ /* sensor identifier */
+ int32_t sensor;
+
+ /* sensor type */
+ int32_t type;
+
+ /* reserved */
+ int32_t reserved0;
+
+ /* time is in nanosecond */
+ int64_t timestamp;
+
+ union
+ {
+ union
+ {
+ float data[16];
+
+ /* 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;
+
+ /* distance in centimeters */
+ float distance;
+
+ /* light in SI lux units */
+ float light;
+
+ /* pressure in hectopascal (hPa) */
+ float pressure;
+
+ /* relative humidity in percent */
+ float relative_humidity;
+
+ /* uncalibrated gyroscope values are in rad/s */
+ uncalibrated_event_t uncalibrated_gyro;
+
+ /* uncalibrated magnetometer values are in micro-Teslas */
+ uncalibrated_event_t uncalibrated_magnetic;
+
+ /* this is a special event. see SENSOR_TYPE_META_DATA above.
+ * sensors_meta_data_event_t events are all reported with a type of
+ * SENSOR_TYPE_META_DATA. The handle is ignored and must be zero.
+ */
+ meta_data_event_t meta_data;
+ };
+
+ union
+ {
+ uint64_t data[8];
+
+ /* step-counter */
+ uint64_t step_counter;
+ } u64;
+ };
+ uint32_t reserved1[4];
+} sensors_event_t;
+
+/* see SENSOR_TYPE_META_DATA */
+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".
+ */
+ const char *name;
+
+ /* vendor of the hardware part */
+ const char *vendor;
+
+ /* version of the hardware part + driver. The value of this field
+ * must increase when the driver is updated in a way that changes the
+ * output of this sensor. This is important for fused sensors when the
+ * fusion algorithm is updated.
+ */
+ int version;
+
+ /* handle that identifies this sensors. This handle is used to reference
+ * this sensor throughout the HAL API.
+ */
+ int handle;
+
+ /* this sensor's type. */
+ int type;
+
+ /* maximum range of this sensor's value in SI units */
+ float maxRange;
+
+ /* smallest difference between two values reported by this sensor */
+ float resolution;
+
+ /* rough estimate of this sensor's power consumption in mA */
+ float power;
+
+ /* this value depends on the trigger mode:
+ *
+ * continuous: minimum sample period allowed in microseconds
+ * on-change : 0
+ * one-shot :-1
+ * special : 0, unless otherwise noted
+ */
+ int32_t minDelay;
+
+ /* number of events reserved for this sensor in the batch mode FIFO.
+ * If there is a dedicated FIFO for this sensor, then this is the
+ * size of this FIFO. If the FIFO is shared with other sensors,
+ * this is the size reserved for that sensor and it can be zero.
+ */
+ uint32_t fifoReservedEventCount;
+
+ /* maximum number of events of this sensor that could be batched.
+ * This is especially relevant when the FIFO is shared between
+ * several sensors; this value is then set to the size of that FIFO.
+ */
+ uint32_t fifoMaxEventCount;
+
+ /* reserved fields, must be zero */
+ void *reserved[6];
+} sensor_t;
+
+enum SensorMode
+{
+ SENSOR_MODE_RAW,
+ SENSOR_MODE_CALIBRATED,
+ SENSOR_MODE_NORMAL,
+};
+
+enum SensorAccelRange
+{
+ 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)
+
+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;
+
+/**
+ * Sensor Base Class
+ */
+class SensorBase
+{
+private:
+ int type;
+
+public:
+ SensorBase(int type);
+ ~SensorBase();
+
+ virtual int configure(SensorConfig *config) = 0;
+ virtual int activate(int enable) = 0;
+
+ virtual int poll(sensors_event_t *events) = 0;
+ virtual void getSensor(struct sensor_t *sensor) = 0;
+
+ int getType(void);
+
+ int setConfig(SensorConfig *config);
+ int getConfig(SensorConfig *config);
+
+ int subscribe(SensorEventHandler_t *handler, void *user_data);
+ int publish(sensors_event_t *event);
+
+protected:
+ SensorBase *next;
+ SensorBase *prev;
+
+ /* sensor configuration */
+ SensorConfig config;
+
+ SensorEventHandler_t *evtHandler;
+ void *userData;
+
+ friend class SensorManager;
+};
+
+/**
+ * Sensor Manager
+ */
+class SensorManager
+{
+public:
+ SensorManager();
+ ~SensorManager();
+
+ static int registerSensor(SensorBase *sensor);
+ static int unregisterSensor(SensorBase *sensor);
+
+ static SensorBase *getDefaultSensor(int type);
+ static int subscribe(int type, SensorEventHandler_t *handler, void *user_data);
+
+ 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..8744aa4657 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');
}
@@ -278,7 +279,7 @@ static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)
serial->config.bufsz);
RT_ASSERT(rx_fifo != RT_NULL);
rx_fifo->buffer = (rt_uint8_t*) (rx_fifo + 1);
- rt_memset(rx_fifo->buffer, 0, RT_SERIAL_RB_BUFSZ);
+ rt_memset(rx_fifo->buffer, 0, serial->config.bufsz);
rx_fifo->put_index = 0;
rx_fifo->get_index = 0;
diff --git a/components/drivers/spi/spi_wifi_rw009.c b/components/drivers/spi/spi_wifi_rw009.c
index 4906a97712..9f5601bf26 100644
--- a/components/drivers/spi/spi_wifi_rw009.c
+++ b/components/drivers/spi/spi_wifi_rw009.c
@@ -20,6 +20,7 @@
* Change Logs:
* Date Author Notes
* 2014-07-31 aozima the first version
+ * 2014-09-18 aozima update command & response.
*/
#include <rtthread.h>
@@ -30,24 +31,33 @@
#include <lwip/icmp.h>
#include "lwipopts.h"
-#include "spi_wifi_rw009.h"
-
-#define SSID_NAME "AP_SSID"
-#define SSID_PASSWORD "AP_passwd"
-
-// #define WIFI_DEBUG_ON
+#define WIFI_DEBUG_ON
// #define ETH_RX_DUMP
// #define ETH_TX_DUMP
#ifdef WIFI_DEBUG_ON
-#define WIFI_DEBUG rt_kprintf("[WIFI] ");rt_kprintf
+#define WIFI_DEBUG rt_kprintf("[RW009] ");rt_kprintf
+//#define SPI_DEBUG rt_kprintf("[SPI] ");rt_kprintf
+#define SPI_DEBUG(...)
#else
#define WIFI_DEBUG(...)
+#define SPI_DEBUG(...)
#endif /* #ifdef WIFI_DEBUG_ON */
-#define MAX_BUFFER_SIZE (sizeof(struct response) + MAX_DATA_LEN)
+/********************************* RW009 **************************************/
+#include "spi_wifi_rw009.h"
+
+/* tools */
+#define node_entry(node, type, member) \
+ ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
+#define member_offset(type, member) \
+ ((unsigned long)(&((type *)0)->member))
+
+#define MAX_SPI_PACKET_SIZE (member_offset(struct spi_data_packet, buffer) + SPI_MAX_DATA_LEN)
+#define MAX_SPI_BUFFER_SIZE (sizeof(struct spi_response) + MAX_SPI_PACKET_SIZE)
#define MAX_ADDR_LEN 6
-struct spi_wifi_eth
+
+struct rw009_wifi
{
/* inherit from ethernet device */
struct eth_device parent;
@@ -67,8 +77,9 @@ struct spi_wifi_eth
int spi_tx_mb_pool[SPI_TX_POOL_SIZE + 1];
int eth_rx_mb_pool[SPI_RX_POOL_SIZE + 1];
- int spi_wifi_cmd_mb_pool[3];
- struct rt_mailbox spi_wifi_cmd_mb;
+ int rw009_cmd_mb_pool[3];
+ struct rt_mailbox rw009_cmd_mb;
+ uint32_t last_cmd;
ALIGN(4)
rt_uint8_t spi_tx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE];
@@ -76,58 +87,257 @@ struct spi_wifi_eth
rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_RX_POOL_SIZE];
ALIGN(4)
- uint8_t spi_hw_rx_buffer[MAX_BUFFER_SIZE];
+ uint8_t spi_hw_rx_buffer[MAX_SPI_BUFFER_SIZE];
+
+ /* status for RW009 */
+ rw009_ap_info ap_info; /* AP info for conn. */
+ rw009_ap_info *ap_scan; /* AP list for SCAN. */
+ uint32_t ap_scan_count;
};
-static struct spi_wifi_eth spi_wifi_device;
+static struct rw009_wifi rw009_wifi_device;
static struct rt_event spi_wifi_data_event;
-static void resp_handler(struct spi_wifi_eth *wifi_device, struct spi_wifi_resp *resp)
+static void resp_handler(struct rw009_wifi *wifi_device, struct rw009_resp *resp)
{
- struct spi_wifi_resp *resp_return;
+ struct rw009_resp *resp_return = RT_NULL;
switch (resp->cmd)
{
- case SPI_WIFI_CMD_INIT:
- WIFI_DEBUG("resp_handler SPI_WIFI_CMD_INIT\n");
- resp_return = (struct spi_wifi_resp *)rt_malloc(sizeof(struct spi_wifi_resp)); //TODO:
- memcpy(resp_return, resp, 10);
- rt_mb_send(&wifi_device->spi_wifi_cmd_mb, (rt_uint32_t)resp_return);
+ case RW009_CMD_INIT:
+ WIFI_DEBUG("resp_handler RW009_CMD_INIT\n");
+ resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init)); //TODO:
+ if(resp_return == RT_NULL) break;
+ memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init));
+
+ WIFI_DEBUG("sn:%-*.*s\n", sizeof(resp->resp.init.sn), sizeof(resp->resp.init.sn), resp->resp.init.sn);
+ WIFI_DEBUG("version:%-*.*s\n", sizeof(resp->resp.init.version), sizeof(resp->resp.init.version), resp->resp.init.version);
+
+ rt_memcpy(wifi_device->dev_addr, resp->resp.init.mac, 6);
break;
- case SPI_WIFI_CMD_SCAN:
- WIFI_DEBUG("resp_handler SPI_WIFI_CMD_SCAN\n");
+ case RW009_CMD_SCAN:
+ if( resp->len == sizeof(rw009_ap_info) )
+ {
+ rw009_ap_info *ap_scan = rt_realloc(wifi_device->ap_scan, sizeof(rw009_ap_info) * (wifi_device->ap_scan_count + 1) );
+ if(ap_scan != RT_NULL)
+ {
+ memcpy( &ap_scan[wifi_device->ap_scan_count], &resp->resp.ap_info, sizeof(rw009_ap_info) );
+
+ //dump
+ if(1)
+ {
+#ifdef WIFI_DEBUG_ON
+ rw009_ap_info *ap_info = &resp->resp.ap_info;
+ WIFI_DEBUG("SCAN SSID:%-32.32s\n", ap_info->ssid);
+ WIFI_DEBUG("SCAN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n",
+ ap_info->bssid[0],
+ ap_info->bssid[1],
+ ap_info->bssid[2],
+ ap_info->bssid[3],
+ ap_info->bssid[4],
+ ap_info->bssid[5]);
+ WIFI_DEBUG("SCAN rssi:%ddBm\n", ap_info->rssi);
+ WIFI_DEBUG("SCAN rate:%dMbps\n", ap_info->max_data_rate/1000);
+ WIFI_DEBUG("SCAN channel:%d\n", ap_info->channel);
+ WIFI_DEBUG("SCAN security:%08X\n\n", ap_info->security);
+#endif /* WIFI_DEBUG_ON */
+ }
+
+ wifi_device->ap_scan_count++;
+ wifi_device->ap_scan = ap_scan;
+ }
+
+ return; /* wait for next ap */
+ }
break;
+ case RW009_CMD_JOIN:
+ case RW009_CMD_EASY_JOIN:
+ WIFI_DEBUG("resp_handler RW009_CMD_EASY_JOIN\n");
+ resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join)); //TODO:
+ if(resp_return == RT_NULL) break;
+ memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join));
+
+ if( resp->result == 0 )
+ {
+ memcpy(&wifi_device->ap_info, &resp_return->resp.ap_info, sizeof(rw009_resp_join));
+ wifi_device->active = 1;
+ eth_device_linkchange(&wifi_device->parent, RT_TRUE);
+ }
+ else
+ {
+ WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result );
+ }
- case SPI_WIFI_CMD_JOIN:
- WIFI_DEBUG("resp_handler SPI_WIFI_CMD_JOIN\n");
- wifi_device->active = 1;
- eth_device_linkchange(&wifi_device->parent, RT_TRUE);
+ //dupm
+ if(1)
+ {
+#ifdef WIFI_DEBUG_ON
+ rw009_ap_info *ap_info = &resp->resp.ap_info;
+ WIFI_DEBUG("JOIN SSID:%-32.32s\n", ap_info->ssid);
+ WIFI_DEBUG("JOIN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n",
+ ap_info->bssid[0],
+ ap_info->bssid[1],
+ ap_info->bssid[2],
+ ap_info->bssid[3],
+ ap_info->bssid[4],
+ ap_info->bssid[5]);
+ WIFI_DEBUG("JOIN rssi:%ddBm\n", ap_info->rssi);
+ WIFI_DEBUG("JOIN rate:%dMbps\n", ap_info->max_data_rate/1000);
+ WIFI_DEBUG("JOIN channel:%d\n", ap_info->channel);
+ WIFI_DEBUG("JOIN security:%08X\n\n", ap_info->security);
+#endif /* WIFI_DEBUG_ON */
+ }
break;
+ case RW009_CMD_RSSI:
+ // TODO: client RSSI.
+ {
+ rw009_ap_info *ap_info = &resp->resp.ap_info;
+ wifi_device->ap_info.rssi = ap_info->rssi;
+ WIFI_DEBUG("current RSSI: %d\n", wifi_device->ap_info.rssi);
+ }
+ break;
+
+ case RW009_CMD_SOFTAP:
+ {
+ if( resp->result == 0 )
+ {
+ ;
+ wifi_device->active = 1;
+ eth_device_linkchange(&wifi_device->parent, RT_TRUE);
+ }
+ else
+ {
+ WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result );
+ }
+
+ }
+ break;
+
default:
WIFI_DEBUG("resp_handler %d\n", resp->cmd);
break;
}
+
+ if(resp->cmd == wifi_device->last_cmd)
+ {
+ rt_mb_send(&wifi_device->rw009_cmd_mb, (rt_uint32_t)resp_return);
+ return;
+ }
+ else
+ {
+ rt_free(resp_return);
+ }
+}
+
+static rt_err_t rw009_cmd(struct rw009_wifi *wifi_device, uint32_t cmd, void *args)
+{
+ rt_err_t result = RT_EOK;
+ rt_int32_t timeout = RW009_CMD_TIMEOUT;
+
+ struct spi_data_packet *data_packet;
+ struct rw009_cmd *wifi_cmd = RT_NULL;
+ struct rw009_resp *resp = RT_NULL;
+
+ wifi_device->last_cmd = cmd;
+
+ data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
+ wifi_cmd = (struct rw009_cmd *)data_packet->buffer;
+
+ wifi_cmd->cmd = cmd;
+ wifi_cmd->len = 0;
+
+ if( cmd == RW009_CMD_INIT )
+ {
+ wifi_cmd->len = sizeof(rw009_cmd_init);
+ }
+ else if( cmd == RW009_CMD_SCAN )
+ {
+ wifi_cmd->len = 0;
+ timeout += RT_TICK_PER_SECOND*10;
+
+ if(wifi_device->ap_scan)
+ {
+ rt_free(wifi_device->ap_scan);
+ wifi_device->ap_scan = RT_NULL;
+ wifi_device->ap_scan_count = 0;
+ }
+ }
+ else if( cmd == RW009_CMD_JOIN )
+ {
+ wifi_cmd->len = sizeof(rw009_cmd_join);
+ }
+ else if( cmd == RW009_CMD_EASY_JOIN )
+ {
+ wifi_cmd->len = sizeof(rw009_cmd_easy_join);
+ timeout += RT_TICK_PER_SECOND*5;
+ }
+ else if( cmd == RW009_CMD_RSSI )
+ {
+ wifi_cmd->len = sizeof(rw009_cmd_rssi);
+ }
+ else if( cmd == RW009_CMD_SOFTAP )
+ {
+ wifi_cmd->len = sizeof(rw009_cmd_softap);
+ }
+ else
+ {
+ WIFI_DEBUG("unkown RW009 CMD %d\n", cmd);
+ result = -RT_ENOSYS;
+ rt_mp_free(data_packet);
+ data_packet = RT_NULL;
+ }
+
+ if(data_packet == RT_NULL)
+ {
+ goto _exit;
+ }
+
+ if(wifi_cmd->len)
+ memcpy(&wifi_cmd->params, args, wifi_cmd->len);
+
+ data_packet->data_type = data_type_cmd;
+ data_packet->data_len = member_offset(struct rw009_cmd, params) + wifi_cmd->len;
+
+ rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
+ rt_event_send(&spi_wifi_data_event, 1);
+
+ result = rt_mb_recv(&wifi_device->rw009_cmd_mb,
+ (rt_uint32_t *)&resp,
+ timeout);
+
+ if ( result != RT_EOK )
+ {
+ WIFI_DEBUG("CMD %d error, resultL %d\n", cmd, result );
+ }
+
+ if(resp != RT_NULL)
+ result = resp->result;
+
+_exit:
+ wifi_device->last_cmd = 0;
+ if(resp) rt_free(resp);
+ return result;
}
-static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
+static rt_err_t spi_wifi_transfer(struct rw009_wifi *dev)
{
struct pbuf *p = RT_NULL;
- struct cmd_request cmd;
- struct response resp;
+ struct spi_cmd_request cmd;
+ struct spi_response resp;
rt_err_t result;
const struct spi_data_packet *data_packet = RT_NULL;
- struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
+ struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
struct rt_spi_device *rt_spi_device = wifi_device->rt_spi_device;
spi_wifi_int_cmd(0);
while (spi_wifi_is_busy());
- WIFI_DEBUG("sequence start!\n");
+ SPI_DEBUG("sequence start!\n");
- memset(&cmd, 0, sizeof(struct cmd_request));
+ memset(&cmd, 0, sizeof(struct spi_cmd_request));
cmd.magic1 = CMD_MAGIC1;
cmd.magic2 = CMD_MAGIC2;
@@ -139,7 +349,7 @@ static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
if ((result == RT_EOK) && (data_packet != RT_NULL) && (data_packet->data_len > 0))
{
cmd.M2S_len = data_packet->data_len + member_offset(struct spi_data_packet, buffer);
- //WIFI_DEBUG("cmd.M2S_len = %d\n", cmd.M2S_len);
+ //SPI_DEBUG("cmd.M2S_len = %d\n", cmd.M2S_len);
}
rt_spi_send(rt_spi_device, &cmd, sizeof(cmd));
@@ -163,22 +373,22 @@ static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
if ((resp.magic1 != RESP_MAGIC1) || (resp.magic2 != RESP_MAGIC2))
{
- WIFI_DEBUG("bad resp magic, abort!\n");
+ SPI_DEBUG("bad resp magic, abort!\n");
goto _bad_resp_magic;
}
if (resp.flag & RESP_FLAG_SRDY)
{
- WIFI_DEBUG("RESP_FLAG_SRDY\n");
+ SPI_DEBUG("RESP_FLAG_SRDY\n");
max_data_len = cmd.M2S_len;
}
if (resp.S2M_len)
{
- WIFI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len);
+ SPI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len);
if (resp.S2M_len > MAX_SPI_PACKET_SIZE)
{
- WIFI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE);
+ SPI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE);
resp.S2M_len = 0;//drop
}
@@ -188,10 +398,10 @@ static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
if (max_data_len == 0)
{
- WIFI_DEBUG("no rx or tx data!\n");
+ SPI_DEBUG("no rx or tx data!\n");
}
- //WIFI_DEBUG("max_data_len = %d\n", max_data_len);
+ //SPI_DEBUG("max_data_len = %d\n", max_data_len);
_bad_resp_magic:
/* setup message */
@@ -227,25 +437,25 @@ _bad_resp_magic:
}
else
{
- WIFI_DEBUG("!active, RX drop.\n");
+ SPI_DEBUG("!active, RX drop.\n");
}
}
else if (data_packet->data_type == data_type_resp)
{
- WIFI_DEBUG("data_type_resp\n");
- resp_handler(dev, (struct spi_wifi_resp *)data_packet->buffer);
+ SPI_DEBUG("data_type_resp\n");
+ resp_handler(dev, (struct rw009_resp *)data_packet->buffer);
}
else
{
- WIFI_DEBUG("data_type: %d, %dbyte\n",
- data_packet->data_type,
- data_packet->data_len);
+ SPI_DEBUG("data_type: %d, %dbyte\n",
+ data_packet->data_type,
+ data_packet->data_len);
}
}
}
spi_wifi_int_cmd(1);
- WIFI_DEBUG("sequence finish!\n\n");
+ SPI_DEBUG("sequence finish!\n\n");
if ((cmd.M2S_len == 0) && (resp.S2M_len == 0))
{
@@ -289,127 +499,57 @@ static void packet_dump(const char *msg, const struct pbuf *p)
}
#endif /* dump */
-/* initialize the interface */
-static rt_err_t spi_wifi_eth_init(rt_device_t dev)
+/********************************* RT-Thread Ethernet interface begin **************************************/
+static rt_err_t rw009_wifi_init(rt_device_t dev)
{
return RT_EOK;
}
-static rt_err_t spi_wifi_eth_open(rt_device_t dev, rt_uint16_t oflag)
+static rt_err_t rw009_wifi_open(rt_device_t dev, rt_uint16_t oflag)
{
return RT_EOK;
}
-static rt_err_t spi_wifi_eth_close(rt_device_t dev)
+static rt_err_t rw009_wifi_close(rt_device_t dev)
{
return RT_EOK;
}
-static rt_size_t spi_wifi_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+static rt_size_t rw009_wifi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
-static rt_size_t spi_wifi_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+static rt_size_t rw009_wifi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
rt_set_errno(-RT_ENOSYS);
return 0;
}
-
-static rt_err_t spi_wifi_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+static rt_err_t rw009_wifi_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
- struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
- struct spi_data_packet *data_packet;
- struct spi_wifi_cmd *wifi_cmd;
- struct spi_wifi_resp *resp;
+ struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
+ rt_err_t result = RT_EOK;
- switch (cmd)
+ if (cmd == NIOCTL_GADDR)
{
- case NIOCTL_GADDR:
memcpy(args, wifi_device->dev_addr, 6);
- break;
-
- case SPI_WIFI_CMD_INIT:
- /* get mac address */
- if (args)
- {
- rt_err_t result;
-
- data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
- // TODO: check result.
-
- wifi_cmd = (struct spi_wifi_cmd *)data_packet->buffer;
- wifi_cmd->cmd = SPI_WIFI_CMD_INIT;
-
- data_packet->data_type = data_type_cmd;
- data_packet->data_len = member_offset(struct spi_wifi_cmd, buffer) + 0;
-
- rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
- rt_event_send(&spi_wifi_data_event, 1);
-
- result = rt_mb_recv(&wifi_device->spi_wifi_cmd_mb,
- (rt_uint32_t *)&resp,
- RT_WAITING_FOREVER);
-
- if ((result == RT_EOK) && (resp != RT_NULL))
- {
- WIFI_DEBUG("resp cmd: %d\n", resp->cmd);
-
- rt_memcpy(args, resp->buffer, 6);
- }
- }
- else return -RT_ERROR;
- break;
-
-
- case SPI_WIFI_CMD_SCAN:
-
- case SPI_WIFI_CMD_JOIN:
- if (args)
- {
- struct cmd_join *cmd_join;
-
- data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
-
- wifi_cmd = (struct spi_wifi_cmd *)data_packet->buffer;
- wifi_cmd->cmd = SPI_WIFI_CMD_JOIN;
- cmd_join = (struct cmd_join *)wifi_cmd->buffer;
-
-#define WPA_SECURITY 0x00200000
-#define WPA2_SECURITY 0x00400000
-
-#define TKIP_ENABLED 0x0002
-#define AES_ENABLED 0x0004
-
-
- strncpy(cmd_join->ssid, SSID_NAME, SSID_NAME_LENGTH_MAX);
- strncpy(cmd_join->passwd, SSID_PASSWORD, PASSWORD_LENGTH_MAX);
- cmd_join->security = WPA_SECURITY | TKIP_ENABLED | AES_ENABLED;
- // cmd_join->security = WPA_SECURITY | TKIP_ENABLED;
- data_packet->data_type = data_type_cmd;
- data_packet->data_len = sizeof(struct cmd_join) + member_offset(struct spi_wifi_cmd, buffer);
-
- rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
- rt_event_send(&spi_wifi_data_event, 1);
- }
- else return -RT_ERROR;
- break;
-
- default :
- break;
+ }
+ else
+ {
+ result = rw009_cmd(wifi_device, cmd, args);
}
- return RT_EOK;
+ return result;
}
/* transmit packet. */
-rt_err_t spi_wifi_eth_tx(rt_device_t dev, struct pbuf *p)
+rt_err_t rw009_wifi_tx(rt_device_t dev, struct pbuf *p)
{
rt_err_t result = RT_EOK;
struct spi_data_packet *data_packet;
- struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
+ struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
if (!wifi_device->active)
{
@@ -441,10 +581,10 @@ rt_err_t spi_wifi_eth_tx(rt_device_t dev, struct pbuf *p)
}
/* reception packet. */
-struct pbuf *spi_wifi_eth_rx(rt_device_t dev)
+struct pbuf *rw009_wifi_rx(rt_device_t dev)
{
struct pbuf *p = RT_NULL;
- struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
+ struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
if (rt_mb_recv(&wifi_device->eth_rx_mb, (rt_uint32_t *)&p, 0) != RT_EOK)
{
@@ -452,12 +592,13 @@ struct pbuf *spi_wifi_eth_rx(rt_device_t dev)
}
#ifdef ETH_RX_DUMP
- if(p)
- packet_dump("RX dump", p);
+ if(p)
+ packet_dump("RX dump", p);
#endif /* ETH_RX_DUMP */
return p;
}
+/********************************* RT-Thread Ethernet interface end **************************************/
static void spi_wifi_data_thread_entry(void *parameter)
{
@@ -476,7 +617,7 @@ static void spi_wifi_data_thread_entry(void *parameter)
continue;
}
- result = spi_wifi_transfer(&spi_wifi_device);
+ result = spi_wifi_transfer(&rw009_wifi_device);
if (result == RT_EOK)
{
@@ -485,15 +626,19 @@ static void spi_wifi_data_thread_entry(void *parameter)
}
}
-rt_err_t rt_hw_wifi_init(const char *spi_device_name)
+rt_err_t rt_hw_wifi_init(const char *spi_device_name, wifi_mode_t mode)
{
- memset(&spi_wifi_device, 0, sizeof(struct spi_wifi_eth));
+ /* align and struct size check. */
+ RT_ASSERT( (SPI_MAX_DATA_LEN & 0x03) == 0);
+ RT_ASSERT( sizeof(struct rw009_resp) <= SPI_MAX_DATA_LEN);
- spi_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
+ memset(&rw009_wifi_device, 0, sizeof(struct rw009_wifi));
- if (spi_wifi_device.rt_spi_device == RT_NULL)
+ rw009_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
+
+ if (rw009_wifi_device.rt_spi_device == RT_NULL)
{
- WIFI_DEBUG("spi device %s not found!\r\n", spi_device_name);
+ SPI_DEBUG("spi device %s not found!\r\n", spi_device_name);
return -RT_ENOSYS;
}
@@ -502,49 +647,49 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name)
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
- cfg.max_hz = 15 * 1000000; /* 30M */
- rt_spi_configure(spi_wifi_device.rt_spi_device, &cfg);
+ cfg.max_hz = 15 * 1000000; /* 10M */
+ rt_spi_configure(rw009_wifi_device.rt_spi_device, &cfg);
}
- spi_wifi_device.parent.parent.init = spi_wifi_eth_init;
- spi_wifi_device.parent.parent.open = spi_wifi_eth_open;
- spi_wifi_device.parent.parent.close = spi_wifi_eth_close;
- spi_wifi_device.parent.parent.read = spi_wifi_eth_read;
- spi_wifi_device.parent.parent.write = spi_wifi_eth_write;
- spi_wifi_device.parent.parent.control = spi_wifi_eth_control;
- spi_wifi_device.parent.parent.user_data = RT_NULL;
+ rw009_wifi_device.parent.parent.init = rw009_wifi_init;
+ rw009_wifi_device.parent.parent.open = rw009_wifi_open;
+ rw009_wifi_device.parent.parent.close = rw009_wifi_close;
+ rw009_wifi_device.parent.parent.read = rw009_wifi_read;
+ rw009_wifi_device.parent.parent.write = rw009_wifi_write;
+ rw009_wifi_device.parent.parent.control = rw009_wifi_control;
+ rw009_wifi_device.parent.parent.user_data = RT_NULL;
- spi_wifi_device.parent.eth_rx = spi_wifi_eth_rx;
- spi_wifi_device.parent.eth_tx = spi_wifi_eth_tx;
+ rw009_wifi_device.parent.eth_rx = rw009_wifi_rx;
+ rw009_wifi_device.parent.eth_tx = rw009_wifi_tx;
- rt_mp_init(&spi_wifi_device.spi_tx_mp,
+ rt_mp_init(&rw009_wifi_device.spi_tx_mp,
"spi_tx",
- &spi_wifi_device.spi_tx_mempool[0],
- sizeof(spi_wifi_device.spi_tx_mempool),
+ &rw009_wifi_device.spi_tx_mempool[0],
+ sizeof(rw009_wifi_device.spi_tx_mempool),
sizeof(struct spi_data_packet));
- rt_mp_init(&spi_wifi_device.spi_rx_mp,
+ rt_mp_init(&rw009_wifi_device.spi_rx_mp,
"spi_rx",
- &spi_wifi_device.spi_rx_mempool[0],
- sizeof(spi_wifi_device.spi_rx_mempool),
+ &rw009_wifi_device.spi_rx_mempool[0],
+ sizeof(rw009_wifi_device.spi_rx_mempool),
sizeof(struct spi_data_packet));
- rt_mb_init(&spi_wifi_device.spi_tx_mb,
+ rt_mb_init(&rw009_wifi_device.spi_tx_mb,
"spi_tx",
- &spi_wifi_device.spi_tx_mb_pool[0],
+ &rw009_wifi_device.spi_tx_mb_pool[0],
SPI_TX_POOL_SIZE,
RT_IPC_FLAG_PRIO);
- rt_mb_init(&spi_wifi_device.eth_rx_mb,
+ rt_mb_init(&rw009_wifi_device.eth_rx_mb,
"eth_rx",
- &spi_wifi_device.eth_rx_mb_pool[0],
+ &rw009_wifi_device.eth_rx_mb_pool[0],
SPI_TX_POOL_SIZE,
RT_IPC_FLAG_PRIO);
- rt_mb_init(&spi_wifi_device.spi_wifi_cmd_mb,
+ rt_mb_init(&rw009_wifi_device.rw009_cmd_mb,
"wifi_cmd",
- &spi_wifi_device.spi_wifi_cmd_mb_pool[0],
- sizeof(spi_wifi_device.spi_wifi_cmd_mb_pool) / 4,
+ &rw009_wifi_device.rw009_cmd_mb_pool[0],
+ sizeof(rw009_wifi_device.rw009_cmd_mb_pool) / 4,
RT_IPC_FLAG_PRIO);
rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO);
@@ -567,24 +712,18 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name)
/* init: get mac address */
{
- WIFI_DEBUG("wifi_control SPI_WIFI_CMD_INIT\n");
- spi_wifi_eth_control((rt_device_t)&spi_wifi_device,
- SPI_WIFI_CMD_INIT,
- (void *)&spi_wifi_device.dev_addr[0]);
+ rw009_cmd_init init;
+ init.mode = mode;
+ WIFI_DEBUG("wifi_control RW009_CMD_INIT\n");
+ rw009_wifi_control((rt_device_t)&rw009_wifi_device,
+ RW009_CMD_INIT,
+ (void *)&init); // 0: firmware, 1: STA, 2:AP
}
- /* register eth device */
- eth_device_init(&(spi_wifi_device.parent), "w0");
- eth_device_linkchange(&spi_wifi_device.parent, RT_FALSE);
-
- {
- WIFI_DEBUG("wifi_control SPI_WIFI_CMD_JOIN\n");
- spi_wifi_eth_control((rt_device_t)&spi_wifi_device,
- SPI_WIFI_CMD_JOIN,
- (void *)&spi_wifi_device.dev_addr[0]);
- WIFI_DEBUG("wifi_control exit\n");
- }
+ /* register eth device */
+ eth_device_init(&(rw009_wifi_device.parent), "w0");
+ eth_device_linkchange(&rw009_wifi_device.parent, RT_FALSE);
return RT_EOK;
}
@@ -594,9 +733,115 @@ void spi_wifi_isr(int vector)
/* enter interrupt */
rt_interrupt_enter();
- WIFI_DEBUG("spi_wifi_isr\n");
+ SPI_DEBUG("spi_wifi_isr\n");
rt_event_send(&spi_wifi_data_event, 1);
/* leave interrupt */
rt_interrupt_leave();
}
+
+/********************************* RW009 tools **************************************/
+rt_err_t rw009_join(const char * SSID, const char * passwd)
+{
+ rt_err_t result;
+ rt_device_t wifi_device;
+ rw009_cmd_easy_join easy_join;
+
+ wifi_device = rt_device_find("w0");
+ if(wifi_device == RT_NULL)
+ return -RT_ENOSYS;
+
+ strncpy( easy_join.ssid, SSID, sizeof(easy_join.ssid) );
+ strncpy( easy_join.passwd, passwd, sizeof(easy_join.passwd) );
+
+ result = rt_device_control(wifi_device,
+ RW009_CMD_EASY_JOIN,
+ (void *)&easy_join);
+
+ return result;
+}
+
+rt_err_t rw009_softap(const char * SSID, const char * passwd,uint32_t security,uint32_t channel)
+{
+ rt_err_t result;
+ rt_device_t wifi_device;
+ rw009_cmd_softap softap;
+
+ wifi_device = rt_device_find("w0");
+ if(wifi_device == RT_NULL)
+ return -RT_ENOSYS;
+
+ strncpy( softap.ssid, SSID, sizeof(softap.ssid) );
+ strncpy( softap.passwd, passwd, sizeof(softap.passwd) );
+
+ softap.security = security;
+ softap.channel = channel;
+ result = rt_device_control(wifi_device,
+ RW009_CMD_SOFTAP,
+ (void *)&softap);
+
+ return result;
+}
+
+int32_t rw009_rssi(void)
+{
+ rt_err_t result;
+ struct rw009_wifi * wifi_device;
+
+ wifi_device = (struct rw009_wifi *)rt_device_find("w0");
+
+ if(wifi_device == RT_NULL)
+ return 0;
+
+ if(wifi_device->active == 0)
+ return 0;
+
+ // SCAN
+ result = rt_device_control((rt_device_t)wifi_device,
+ RW009_CMD_RSSI,
+ RT_NULL);
+
+ if(result == RT_EOK)
+ {
+ return wifi_device->ap_info.rssi;
+ }
+
+ return 0;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+
+static rt_err_t rw009_scan(void)
+{
+ rt_err_t result;
+ struct rw009_wifi * wifi_device;
+
+ wifi_device = (struct rw009_wifi *)rt_device_find("w0");
+
+ rt_kprintf("\nCMD RW009_CMD_SCAN \n");
+ result = rt_device_control((rt_device_t)wifi_device,
+ RW009_CMD_SCAN,
+ RT_NULL);
+
+ rt_kprintf("CMD RW009_CMD_SCAN result:%d\n", result);
+
+ if(result == RT_EOK)
+ {
+ uint32_t i;
+ rw009_ap_info *ap_info;
+
+ for(i=0; i<wifi_device->ap_scan_count; i++)
+ {
+ ap_info = &wifi_device->ap_scan[i];
+ rt_kprintf("AP #%02d SSID: %-32.32s\n", i, ap_info->ssid );
+ }
+ }
+
+ return result;
+}
+FINSH_FUNCTION_EXPORT(rw009_scan, SACN and list AP.);
+FINSH_FUNCTION_EXPORT(rw009_join, RW009 join to AP.);
+FINSH_FUNCTION_EXPORT(rw009_rssi, get RW009 current AP rssi.);
+
+#endif // RT_USING_FINSH
diff --git a/components/drivers/spi/spi_wifi_rw009.h b/components/drivers/spi/spi_wifi_rw009.h
index bb6fea5b01..4b684b9b24 100644
--- a/components/drivers/spi/spi_wifi_rw009.h
+++ b/components/drivers/spi/spi_wifi_rw009.h
@@ -20,6 +20,7 @@
* Change Logs:
* Date Author Notes
* 2014-07-31 aozima the first version
+ * 2014-09-18 aozima update command & response.
*/
#ifndef SPI_WIFI_H_INCLUDED
@@ -28,7 +29,7 @@
#include <stdint.h>
// little-endian
-struct cmd_request
+struct spi_cmd_request
{
uint32_t flag;
uint32_t M2S_len; // master to slave data len.
@@ -42,7 +43,7 @@ struct cmd_request
#define CMD_FLAG_MRDY (0x01)
// little-endian
-struct response
+struct spi_response
{
uint32_t flag;
uint32_t S2M_len; // slave to master data len.
@@ -55,20 +56,16 @@ struct response
#define RESP_MAGIC2 (0x10325476)
/* spi slave configure. */
-#define MAX_DATA_LEN 1520
+#define SPI_MAX_DATA_LEN 1520
#define SPI_TX_POOL_SIZE 2
#define SPI_RX_POOL_SIZE 2
-// align check
-#if (MAX_DATA_LEN & 0x03) != 0
-#error MAX_DATA_LEN must ALIGN to 4byte!
-#endif
-
typedef enum
{
data_type_eth_data = 0,
data_type_cmd,
data_type_resp,
+ data_type_status,
}
app_data_type_typedef;
@@ -76,52 +73,154 @@ struct spi_data_packet
{
uint32_t data_len;
uint32_t data_type;
- char buffer[MAX_DATA_LEN];
+ char buffer[SPI_MAX_DATA_LEN];
};
-/* tools */
-#define node_entry(node, type, member) \
- ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
-#define member_offset(type, member) \
- ((unsigned long)(&((type *)0)->member))
+/********************************* RW009 **************************************/
-#define MAX_SPI_PACKET_SIZE (member_offset(struct spi_data_packet, buffer) + MAX_DATA_LEN)
+/* option */
+#define RW009_CMD_TIMEOUT (RT_TICK_PER_SECOND*3)
+#define SSID_NAME_LENGTH_MAX (32)
+#define PASSWORD_LENGTH_MAX (64)
-/********************************* RW009 **************************************/
+typedef enum
+{
+ MODE_STATION=0,
+ MODE_SOFTAP=1,
+} wifi_mode_t;
-struct spi_wifi_cmd
+typedef struct _rw009_ap_info
+{
+ char ssid[SSID_NAME_LENGTH_MAX];
+ uint8_t bssid[8]; // 6byte + 2byte PAD.
+ int rssi; /* Receive Signal Strength Indication in dBm. */
+ uint32_t max_data_rate; /* Maximum data rate in kilobits/s */
+ uint32_t security; /* Security type */
+ uint32_t channel; /* Radio channel that the AP beacon was received on */
+} rw009_ap_info;
+
+typedef struct _rw009_cmd_init
+{
+ uint32_t mode;
+} rw009_cmd_init;
+
+typedef struct _rw009_resp_init
+{
+ uint8_t mac[8]; // 6byte + 2byte PAD.
+ uint8_t sn[24]; // serial.
+ char version[16]; // firmware version.
+} rw009_resp_init;
+
+typedef struct _rw009_cmd_easy_join
+{
+ char ssid[SSID_NAME_LENGTH_MAX];
+ char passwd[PASSWORD_LENGTH_MAX];
+} rw009_cmd_easy_join;
+
+typedef struct _rw009_cmd_join
+{
+ uint8_t bssid[8]; // 6byte + 2byte PAD.
+ char passwd[PASSWORD_LENGTH_MAX];
+} rw009_cmd_join;
+
+typedef struct _rw009_cmd_rssi
+{
+ uint8_t bssid[8]; // 6byte + 2byte PAD.
+} rw009_cmd_rssi;
+
+typedef struct _rw009_cmd_softap
+{
+ char ssid[SSID_NAME_LENGTH_MAX];
+ char passwd[PASSWORD_LENGTH_MAX];
+
+ uint32_t security; /* Security type. */
+ uint32_t channel; /* Radio channel that the AP beacon was received on */
+} rw009_cmd_softap;
+
+typedef struct _rw009_resp_join
+{
+ rw009_ap_info ap_info;
+} rw009_resp_join;
+
+struct rw009_cmd
{
uint32_t cmd;
- char buffer[128];
+ uint32_t len;
+
+ /** command body */
+ union
+ {
+ rw009_cmd_init init;
+ rw009_cmd_easy_join easy_join;
+ rw009_cmd_join join;
+ rw009_cmd_rssi rssi;
+ rw009_cmd_softap softap;
+ } params;
};
-struct spi_wifi_resp
+struct rw009_resp
{
uint32_t cmd;
- char buffer[128];
+ uint32_t len;
+
+ int32_t result; // result for CMD.
+
+ /** resp Body */
+ union
+ {
+ rw009_resp_init init;
+ rw009_ap_info ap_info;
+ } resp;
};
-#define SPI_WIFI_CMD_INIT 128 //wait
-#define SPI_WIFI_CMD_SCAN 129 //no wait
-#define SPI_WIFI_CMD_JOIN 130 //no wait
+#define RW009_CMD_INIT 128
+#define RW009_CMD_SCAN 129
+#define RW009_CMD_JOIN 130
+#define RW009_CMD_EASY_JOIN 131
+#define RW009_CMD_RSSI 132
+#define RW009_CMD_SOFTAP 133
+
+/** cond !ADDTHIS*/
+#define SHARED_ENABLED 0x00008000
+#define WPA_SECURITY 0x00200000
+#define WPA2_SECURITY 0x00400000
+#define WPS_ENABLED 0x10000000
+#define WEP_ENABLED 0x0001
+#define TKIP_ENABLED 0x0002
+#define AES_ENABLED 0x0004
+#define WSEC_SWFLAG 0x0008
+/** endcond */
+/**
+ * Enumeration of Wi-Fi security modes
+ */
+typedef enum
+{
+ SECURITY_OPEN = 0, /**< Open security */
+ SECURITY_WEP_PSK = WEP_ENABLED, /**< WEP Security with open authentication */
+ SECURITY_WEP_SHARED = ( WEP_ENABLED | SHARED_ENABLED ), /**< WEP Security with shared authentication */
+ SECURITY_WPA_TKIP_PSK = ( WPA_SECURITY | TKIP_ENABLED ), /**< WPA Security with TKIP */
+ SECURITY_WPA_AES_PSK = ( WPA_SECURITY | AES_ENABLED ), /**< WPA Security with AES */
+ SECURITY_WPA2_AES_PSK = ( WPA2_SECURITY | AES_ENABLED ), /**< WPA2 Security with AES */
+ SECURITY_WPA2_TKIP_PSK = ( WPA2_SECURITY | TKIP_ENABLED ), /**< WPA2 Security with TKIP */
+ SECURITY_WPA2_MIXED_PSK = ( WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED ), /**< WPA2 Security with AES & TKIP */
+
+ SECURITY_WPS_OPEN = WPS_ENABLED, /**< WPS with open security */
+ SECURITY_WPS_SECURE = (WPS_ENABLED | AES_ENABLED), /**< WPS with AES security */
+
+ SECURITY_UNKNOWN = -1, /**< May be returned by scan function if security is unknown. Do not pass this to the join function! */
+
+ SECURITY_FORCE_32_BIT = 0x7fffffff /**< Exists only to force wiced_security_t type to 32 bits */
+} security_t;
/* porting */
extern void spi_wifi_hw_init(void);
extern void spi_wifi_int_cmd(rt_bool_t cmd);
extern rt_bool_t spi_wifi_is_busy(void);
-#define SSID_NAME_LENGTH_MAX (32)
-#define PASSWORD_LENGTH_MAX (32)
-
-struct cmd_join
-{
- char ssid[SSID_NAME_LENGTH_MAX];
- char passwd[PASSWORD_LENGTH_MAX];
-
- uint8_t bssid[8]; // 6byte + 2byte PAD.
-
- uint32_t channel;
- uint32_t security;
-};
+/* export API. */
+extern rt_err_t rt_hw_wifi_init(const char *spi_device_name,wifi_mode_t mode);
+extern int32_t rw009_rssi(void);
+extern rt_err_t rw009_join(const char * SSID, const char * passwd);
+extern rt_err_t rw009_softap(const char * SSID, const char * passwd,uint32_t security,uint32_t channel);
#endif // SPI_WIFI_H_INCLUDED
diff --git a/components/drivers/src/completion.c b/components/drivers/src/completion.c
index f49e44c48f..48afc2ee34 100644
--- a/components/drivers/src/completion.c
+++ b/components/drivers/src/completion.c
@@ -95,10 +95,10 @@ rt_err_t rt_completion_wait(struct rt_completion *completion,
result = thread->error;
level = rt_hw_interrupt_disable();
- /* clean completed flag */
- completion->flag = RT_UNCOMPLETED;
}
}
+ /* clean completed flag */
+ completion->flag = RT_UNCOMPLETED;
__exit:
rt_hw_interrupt_enable(level);
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;
diff --git a/components/drivers/usb/usbhost/class/adk.c b/components/drivers/usb/usbhost/class/adk.c
index fd6619599c..1481d27ea6 100644
--- a/components/drivers/usb/usbhost/class/adk.c
+++ b/components/drivers/usb/usbhost/class/adk.c
@@ -67,7 +67,7 @@ RTM_EXPORT(rt_usbh_adk_set_string);
*/
static rt_err_t rt_usbh_adk_get_protocol(struct uintf* intf, rt_uint16_t *protocol)
{
- struct ureqest setup;
+ struct urequest setup;
uinst_t device;
int timeout = 100;
@@ -101,7 +101,7 @@ static rt_err_t rt_usbh_adk_get_protocol(struct uintf* intf, rt_uint16_t *protoc
static rt_err_t rt_usbh_adk_send_string(struct uintf* intf, rt_uint16_t index,
const char* str)
{
- struct ureqest setup;
+ struct urequest setup;
uinst_t device;
int timeout = 100;
@@ -134,7 +134,7 @@ static rt_err_t rt_usbh_adk_send_string(struct uintf* intf, rt_uint16_t index,
*/
static rt_err_t rt_usbh_adk_start(struct uintf* intf)
{
- struct ureqest setup;
+ struct urequest setup;
uinst_t device;
int timeout = 100;
diff --git a/components/drivers/usb/usbhost/core/core.c b/components/drivers/usb/usbhost/core/core.c
index af53370f4b..144358a4d3 100644
--- a/components/drivers/usb/usbhost/core/core.c
+++ b/components/drivers/usb/usbhost/core/core.c
@@ -246,7 +246,7 @@ rt_err_t rt_usbh_detach_instance(uinst_t device)
rt_err_t rt_usbh_get_descriptor(uinst_t device, rt_uint8_t type, void* buffer,
int nbytes)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
RT_ASSERT(device != RT_NULL);
@@ -272,7 +272,7 @@ rt_err_t rt_usbh_get_descriptor(uinst_t device, rt_uint8_t type, void* buffer,
*/
rt_err_t rt_usbh_set_address(uinst_t device)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
RT_ASSERT(device != RT_NULL);
@@ -306,7 +306,7 @@ rt_err_t rt_usbh_set_address(uinst_t device)
*/
rt_err_t rt_usbh_set_configure(uinst_t device, int config)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
/* check parameter */
@@ -335,7 +335,7 @@ rt_err_t rt_usbh_set_configure(uinst_t device, int config)
*/
rt_err_t rt_usbh_set_interface(uinst_t device, int intf)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
/* check parameter */
@@ -364,7 +364,7 @@ rt_err_t rt_usbh_set_interface(uinst_t device, int intf)
*/
rt_err_t rt_usbh_clear_feature(uinst_t device, int endpoint, int feature)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
/* check parameter */
diff --git a/components/drivers/usb/usbhost/core/hub.c b/components/drivers/usb/usbhost/core/hub.c
index a71aa4f89c..bde316ae77 100644
--- a/components/drivers/usb/usbhost/core/hub.c
+++ b/components/drivers/usb/usbhost/core/hub.c
@@ -43,7 +43,7 @@ static struct uclass_driver hub_driver;
rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer,
rt_size_t nbytes)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
/* parameter check */
@@ -72,7 +72,7 @@ rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer
*/
rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint8_t* buffer)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
int length = 4;
@@ -104,7 +104,7 @@ rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint8_t* buffer)
rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port,
rt_uint8_t* buffer)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
int length = 4;
@@ -144,7 +144,7 @@ rt_err_t rt_usbh_hub_get_port_status(uhub_t hub, rt_uint16_t port,
rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port,
rt_uint16_t feature)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
/* parameter check */
@@ -183,7 +183,7 @@ rt_err_t rt_usbh_hub_clear_port_feature(uhub_t hub, rt_uint16_t port,
rt_err_t rt_usbh_hub_set_port_feature(uhub_t hub, rt_uint16_t port,
rt_uint16_t feature)
{
- struct ureqest setup;
+ struct urequest setup;
int timeout = 100;
/* parameter check */