aboutsummaryrefslogtreecommitdiff
path: root/apps/drivers/bma180/bma180.cpp
diff options
context:
space:
mode:
authorLorenz Meier <lm@inf.ethz.ch>2012-08-31 14:02:23 +0200
committerLorenz Meier <lm@inf.ethz.ch>2012-08-31 14:02:23 +0200
commit5f131e8c113a8f97814f2d8c93f57641fb2386cd (patch)
tree78742a72a7293ea4e5de038e5c4e38bc2a379089 /apps/drivers/bma180/bma180.cpp
parent63485b91b2aa95cd84ed0f8634a40fe259f2480a (diff)
downloadpx4-firmware-5f131e8c113a8f97814f2d8c93f57641fb2386cd.tar.gz
px4-firmware-5f131e8c113a8f97814f2d8c93f57641fb2386cd.tar.bz2
px4-firmware-5f131e8c113a8f97814f2d8c93f57641fb2386cd.zip
Checkpoint: Operational BMA180 driver
Diffstat (limited to 'apps/drivers/bma180/bma180.cpp')
-rw-r--r--apps/drivers/bma180/bma180.cpp77
1 files changed, 60 insertions, 17 deletions
diff --git a/apps/drivers/bma180/bma180.cpp b/apps/drivers/bma180/bma180.cpp
index 05589fa3f..71bc927d2 100644
--- a/apps/drivers/bma180/bma180.cpp
+++ b/apps/drivers/bma180/bma180.cpp
@@ -32,7 +32,8 @@
****************************************************************************/
/**
- * @file Driver for the Bosch BMA 180 MEMS accelerometer connected via SPI.
+ * @file bma180.cpp
+ * Driver for the Bosch BMA 180 MEMS accelerometer connected via SPI.
*/
#include <nuttx/config.h>
@@ -81,6 +82,9 @@ static const int ERROR = -1;
#define ADDR_ACC_Z_LSB 0x06
#define ADDR_TEMPERATURE 0x08
+#define ADDR_CTRL_REG0 0x0D
+#define REG0_WRITE_ENABLE 0x10
+
#define ADDR_RESET 0x10
#define SOFT_RESET 0xB6
@@ -295,8 +299,11 @@ BMA180::init()
/* perform soft reset (p48) */
write_reg(ADDR_RESET, SOFT_RESET);
- /* wait 10us (p49) */
- usleep(10);
+ /* wait 10 ms (datasheet incorrectly lists 10 us on page 49) */
+ usleep(10000);
+
+ /* enable writing to chip config */
+ modify_reg(ADDR_CTRL_REG0, 0, REG0_WRITE_ENABLE);
/* disable I2C interface */
modify_reg(ADDR_HIGH_DUR, HIGH_DUR_DIS_I2C, 0);
@@ -310,10 +317,17 @@ BMA180::init()
/* disable shadow-disable mode */
modify_reg(ADDR_GAIN_Y, GAIN_Y_SHADOW_DIS, 0);
- set_range(2);
- set_lowpass(75);
+ /* disable writing to chip config */
+ modify_reg(ADDR_CTRL_REG0, REG0_WRITE_ENABLE, 0);
- ret = OK;
+ if (set_range(4)) warnx("Failed setting range");
+ if (set_lowpass(75)) warnx("Failed setting lowpass");
+
+ if (read_reg(ADDR_CHIP_ID) == CHIP_ID) {
+ ret = OK;
+ } else {
+ ret = ERROR;
+ }
out:
return ret;
}
@@ -538,11 +552,11 @@ BMA180::set_range(unsigned max_g)
if (max_g > 16)
return -ERANGE;
- if (max_g <= 1) {
- _current_range = 1;
- rangebits = OFFSET_LSB1_RANGE_2G;
- } else if (max_g <= 2) {
+ if (max_g <= 2) {
_current_range = 2;
+ rangebits = OFFSET_LSB1_RANGE_2G;
+ } else if (max_g <= 3) {
+ _current_range = 3;
rangebits = OFFSET_LSB1_RANGE_3G;
} else if (max_g <= 4) {
_current_range = 4;
@@ -561,10 +575,18 @@ BMA180::set_range(unsigned max_g)
_accel_range_m_s2 = _current_range * 9.80665f;
_accel_range_scale = _accel_range_m_s2 / 8192.0f;
+ /* enable writing to chip config */
+ modify_reg(ADDR_CTRL_REG0, 0, REG0_WRITE_ENABLE);
+
/* adjust sensor configuration */
modify_reg(ADDR_OFFSET_LSB1, OFFSET_LSB1_RANGE_MASK, rangebits);
- return OK;
+ /* block writing to chip config */
+ modify_reg(ADDR_CTRL_REG0, REG0_WRITE_ENABLE, 0);
+
+ /* check if wanted value is now in register */
+ return !((read_reg(ADDR_OFFSET_LSB1) & OFFSET_LSB1_RANGE_MASK) ==
+ (OFFSET_LSB1_RANGE_MASK & rangebits));
}
int
@@ -600,10 +622,18 @@ BMA180::set_lowpass(unsigned frequency)
bwbits = BW_TCS_BW_10HZ;
}
+ /* enable writing to chip config */
+ modify_reg(ADDR_CTRL_REG0, 0, REG0_WRITE_ENABLE);
+
/* adjust sensor configuration */
modify_reg(ADDR_BW_TCS, BW_TCS_BW_MASK, bwbits);
- return OK;
+ /* block writing to chip config */
+ modify_reg(ADDR_CTRL_REG0, REG0_WRITE_ENABLE, 0);
+
+ /* check if wanted value is now in register */
+ return !((read_reg(ADDR_BW_TCS) & BW_TCS_BW_MASK) ==
+ (BW_TCS_BW_MASK & bwbits));
}
void
@@ -657,7 +687,7 @@ BMA180::measure()
* starting from the X LSB.
*/
raw_report.cmd = ADDR_ACC_X_LSB;
- transfer((uint8_t *)&raw_report, (uint8_t *)&raw_report, sizeof(raw_report));
+ // XXX PX4DEV transfer((uint8_t *)&raw_report, (uint8_t *)&raw_report, sizeof(raw_report));
/*
* Adjust and scale results to SI units.
@@ -668,10 +698,23 @@ BMA180::measure()
* measurement flow without using the external interrupt.
*/
_reports[_next_report].timestamp = hrt_absolute_time();
- /* XXX adjust for sensor alignment to board here */
- report->x_raw = raw_report.x;
- report->y_raw = raw_report.y;
- report->z_raw = raw_report.z;
+ /*
+ * y of board is x of sensor and x of board is -y of sensor
+ * perform only the axis assignment here.
+ * The y axis is inverted four lines down from y to -y
+ * Two non-value bits are discarded directly
+ */
+ report->y_raw = (((int16_t)read_reg(ADDR_ACC_X_LSB+1)) << 8) | (read_reg(ADDR_ACC_X_LSB));// XXX PX4DEV raw_report.x;
+ report->x_raw = (((int16_t)read_reg(ADDR_ACC_X_LSB+3)) << 8) | (read_reg(ADDR_ACC_X_LSB+2));// XXX PX4DEV raw_report.y;
+ report->z_raw = (((int16_t)read_reg(ADDR_ACC_X_LSB+5)) << 8) | (read_reg(ADDR_ACC_X_LSB+4));// XXX PX4DEV raw_report.z;
+
+ /* discard two non-value bits in the 16 measurement */
+ report->x_raw = (report->x_raw >> 2);
+ report->y_raw = (report->y_raw >> 2);
+ report->z_raw = (report->z_raw >> 2);
+
+ /* invert y axis, watching the int16 overflow */
+ report->y_raw = (report->y_raw == INT16_MIN) ? INT16_MAX : -report->y_raw;
report->x = ((report->x_raw * _accel_range_scale) - _accel_scale.x_offset) * _accel_scale.x_scale;
report->y = ((report->y_raw * _accel_range_scale) - _accel_scale.y_offset) * _accel_scale.y_scale;