diff --git a/conf/airframes/CDW/LisaAspirin2.xml b/conf/airframes/CDW/LisaAspirin2.xml
index 3d0c1d0090..8abd75ab7a 100644
--- a/conf/airframes/CDW/LisaAspirin2.xml
+++ b/conf/airframes/CDW/LisaAspirin2.xml
@@ -230,7 +230,7 @@
-
+
diff --git a/sw/airborne/arch/stm32/mcu_periph/spi_arch.c b/sw/airborne/arch/stm32/mcu_periph/spi_arch.c
index 027969af79..72a76cecf9 100644
--- a/sw/airborne/arch/stm32/mcu_periph/spi_arch.c
+++ b/sw/airborne/arch/stm32/mcu_periph/spi_arch.c
@@ -184,6 +184,7 @@ void dma1_c4_irq_handler(void)
DMA_Cmd(DMA1_Channel5, DISABLE);
slave0->status = SPITransSuccess;
+ *(slave0->ready) = 1;
}
diff --git a/sw/airborne/mcu_periph/spi.h b/sw/airborne/mcu_periph/spi.h
index ca296502d2..a118cc493a 100644
--- a/sw/airborne/mcu_periph/spi.h
+++ b/sw/airborne/mcu_periph/spi.h
@@ -43,6 +43,7 @@ enum SPITransactionStatus {
struct spi_transaction {
volatile uint8_t* mosi_buf;
volatile uint8_t* miso_buf;
+ volatile uint8_t* ready;
uint8_t length;
volatile enum SPITransactionStatus status;
};
diff --git a/sw/airborne/peripherals/mpu60X0.h b/sw/airborne/peripherals/mpu60X0.h
index 2f186875b4..384b92a726 100644
--- a/sw/airborne/peripherals/mpu60X0.h
+++ b/sw/airborne/peripherals/mpu60X0.h
@@ -5,6 +5,8 @@
#define MPU60X0_ADDR 0xD0
#define MPU60X0_ADDR_ALT 0xD2
+#define MPU60X0_SPI_READ 0x80
+
// Power and Interface
#define MPU60X0_REG_AUX_VDDIO 0x01 // Must be set to 0 on MPU6000
#define MPU60X0_REG_USER_CTRL 0x6A
diff --git a/sw/airborne/subsystems/imu/imu_aspirin2.c b/sw/airborne/subsystems/imu/imu_aspirin2.c
index 70ff314be1..0da0ed9d31 100644
--- a/sw/airborne/subsystems/imu/imu_aspirin2.c
+++ b/sw/airborne/subsystems/imu/imu_aspirin2.c
@@ -12,10 +12,11 @@ struct ImuAspirin2 imu_aspirin2;
struct spi_transaction aspirin2_mpu60x0;
-/*
+
// initialize peripherals
-static void configure_gyro(void);
+static void configure(void);
+/*
static void configure_accel(void);
//static void configure_mag(void);
@@ -28,10 +29,10 @@ void imu_impl_init(void) {
aspirin2_mpu60x0.mosi_buf = imu_aspirin2.imu_tx_buf;
aspirin2_mpu60x0.miso_buf = imu_aspirin2.imu_rx_buf;
+ aspirin2_mpu60x0.ready = &(imu_aspirin2.imu_available);
aspirin2_mpu60x0.length = 2;
// imu_aspirin2_arch_init();
-// spi_arch_int_enable();
}
@@ -39,61 +40,128 @@ void imu_impl_init(void) {
void imu_periodic(void)
{
- imu_aspirin2.imu_tx_buf[0] = MPU60X0_REG_WHO_AM_I + 0x80;
- imu_aspirin2.imu_tx_buf[1] = 0x00;
+ if (imu_aspirin2.status == Aspirin2StatusUninit)
+ {
+ configure();
+ // imu_aspirin_arch_int_enable();
+ imu_aspirin2.status = Aspirin2StatusIdle;
- spi_rw(&aspirin2_mpu60x0);
+ aspirin2_mpu60x0.length = 22;
+ aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_INT_STATUS + MPU60X0_SPI_READ;
+ {
+ for (int i=1;i ASPIRIN_ACCEL_TIMEOUT) {
+ if (imu_aspirin.time_since_last_accel_reading > ASPIRIN_ACCEL_TIMEOUT)
+ {
configure_accel();
imu_aspirin.time_since_last_accel_reading=0;
}
+*/
}
+}
+
+static void configure(void)
+{
+ aspirin2_mpu60x0.length = 2;
+
+ ///////////////////
+ // Configure power:
+
+ // MPU60X0_REG_AUX_VDDIO = 0 (good on startup)
+
+ // MPU60X0_REG_USER_CTRL:
+ // -Enable Aux I2C Master Mode
+ // -Enable SPI
+
+ // MPU60X0_REG_PWR_MGMT_1
+ // -switch to gyroX clock
+ aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_PWR_MGMT_1;
+ aspirin2_mpu60x0.mosi_buf[1] = 0x01;
+ spi_rw(&aspirin2_mpu60x0);
+ while(aspirin2_mpu60x0.status != SPITransSuccess);
+
+ // MPU60X0_REG_PWR_MGMT_2: Nothing should be in standby: default OK
+
+ /////////////////////////
+ // Measurement Settings
+
+ // MPU60X0_REG_CONFIG
+ // -ext sync on gyro X (bit 3->6)
+ // -digital low pass filter: 1kHz sampling of gyro/acc with 44Hz bandwidth: since reading is at 100Hz
+#if PERIODIC_FREQUENCY == 60
+#else
+# if PERIODIC_FREQUENCY == 120
+# else
+# error PERIODIC_FREQUENCY should be either 60Hz or 120Hz. Otherwise manually fix the sensor rates
+# endif
+#endif
+ aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_CONFIG;
+ aspirin2_mpu60x0.mosi_buf[1] = (2 << 3) | (3 << 0);
+ spi_rw(&aspirin2_mpu60x0);
+ while(aspirin2_mpu60x0.status != SPITransSuccess);
+
+ // MPU60X0_REG_SMPLRT_DIV
+ // -100Hz output = 1kHz / (9 + 1)
+ aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_SMPLRT_DIV;
+ aspirin2_mpu60x0.mosi_buf[1] = 9;
+ spi_rw(&aspirin2_mpu60x0);
+ while(aspirin2_mpu60x0.status != SPITransSuccess);
+
+ // MPU60X0_REG_GYRO_CONFIG
+ // -2000deg/sec
+ aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_GYRO_CONFIG;
+ aspirin2_mpu60x0.mosi_buf[1] = (3<<3);
+ spi_rw(&aspirin2_mpu60x0);
+ while(aspirin2_mpu60x0.status != SPITransSuccess);
+
+ // MPU60X0_REG_ACCEL_CONFIG
+ // 16g, no HPFL
+ aspirin2_mpu60x0.mosi_buf[0] = MPU60X0_REG_ACCEL_CONFIG;
+ aspirin2_mpu60x0.mosi_buf[1] = (3<<3);
+ spi_rw(&aspirin2_mpu60x0);
+ while(aspirin2_mpu60x0.status != SPITransSuccess);
+
+/*
+ struct i2c_transaction t;
+ t.type = I2CTransTx;
+ t.slave_addr = ITG3200_ADDR;
+ // set gyro range to 2000deg/s and low pass at 256Hz
+ t.mosi_buf[0] = ITG3200_REG_DLPF_FS;
+ t.mosi_buf[1] = (0x03<<3);
+ t.len_w = 2;
+ send_i2c_msg_with_retry(&t);
+ // set sample rate to 533Hz
+ t.mosi_buf[0] = ITG3200_REG_SMPLRT_DIV;
+ t.mosi_buf[1] = 0x0E;
+ send_i2c_msg_with_retry(&t);
+ // switch to gyroX clock
+ t.mosi_buf[0] = ITG3200_REG_PWR_MGM;
+ t.mosi_buf[1] = 0x01;
+ send_i2c_msg_with_retry(&t);
+ // enable interrupt on data ready, idle high, latch until read any register
+ t.mosi_buf[0] = ITG3200_REG_INT_CFG;
+ t.mosi_buf[1] = (0x01 | (0x1<<4) | (0x1<<5) | 0x01<<7);
+ send_i2c_msg_with_retry(&t);
*/
}
/*
-// sends a serie of I2C commands to configure the ITG3200 gyro
-static void configure_gyro(void) {
- struct i2c_transaction t;
- t.type = I2CTransTx;
- t.slave_addr = ITG3200_ADDR;
- // set gyro range to 2000deg/s and low pass at 256Hz
- t.buf[0] = ITG3200_REG_DLPF_FS;
- t.buf[1] = (0x03<<3);
- t.len_w = 2;
- send_i2c_msg_with_retry(&t);
- // set sample rate to 533Hz
- t.buf[0] = ITG3200_REG_SMPLRT_DIV;
- t.buf[1] = 0x0E;
- send_i2c_msg_with_retry(&t);
- // switch to gyroX clock
- t.buf[0] = ITG3200_REG_PWR_MGM;
- t.buf[1] = 0x01;
- send_i2c_msg_with_retry(&t);
- // enable interrupt on data ready, idle high, latch until read any register
- t.buf[0] = ITG3200_REG_INT_CFG;
- t.buf[1] = (0x01 | (0x1<<4) | (0x1<<5) | 0x01<<7);
- send_i2c_msg_with_retry(&t);
-
-}
-
-
-
-static void configure_accel(void) {
-
+static void configure_accel(void)
+{
// set data rate to 800Hz
adxl345_write_to_reg(ADXL345_REG_BW_RATE, 0x0D);
// switch to measurememnt mode
@@ -108,7 +176,6 @@ static void configure_accel(void) {
adxl345_start_reading_data();
}
-
*/
diff --git a/sw/airborne/subsystems/imu/imu_aspirin2.h b/sw/airborne/subsystems/imu/imu_aspirin2.h
index 928817166c..f934e46512 100644
--- a/sw/airborne/subsystems/imu/imu_aspirin2.h
+++ b/sw/airborne/subsystems/imu/imu_aspirin2.h
@@ -26,11 +26,7 @@
#include "generated/airframe.h"
#include "subsystems/imu.h"
-
-#include "mcu_periph/i2c.h"
-#include "peripherals/itg3200.h"
-#include "peripherals/hmc5843.h"
-#include "peripherals/adxl345.h"
+#include "led.h"
#ifdef IMU_ASPIRIN_VERSION_2_0
@@ -95,53 +91,69 @@ extern struct ImuAspirin2 imu_aspirin2;
/* must be implemented by underlying architecture */
extern void imu_aspirin2_arch_init(void);
-/*
-static inline void gyro_copy_i2c(void)
+
+static inline void imu_from_buff(void)
{
- int16_t gp = imu_aspirin.i2c_trans_gyro.buf[0]<<8 | imu_aspirin.i2c_trans_gyro.buf[1];
- int16_t gq = imu_aspirin.i2c_trans_gyro.buf[2]<<8 | imu_aspirin.i2c_trans_gyro.buf[3];
- int16_t gr = imu_aspirin.i2c_trans_gyro.buf[4]<<8 | imu_aspirin.i2c_trans_gyro.buf[5];
- RATES_ASSIGN(imu.gyro_unscaled, gp, gq, gr);
+ int32_t x, y, z;
+
+
+ // If the itg3200 I2C transaction has succeeded: convert the data
+#define MPU_OFFSET_GYRO 10
+ x = (int16_t) ((imu_aspirin2.imu_rx_buf[0+MPU_OFFSET_GYRO] << 8) | imu_aspirin2.imu_rx_buf[1+MPU_OFFSET_GYRO]);
+ y = (int16_t) ((imu_aspirin2.imu_rx_buf[2+MPU_OFFSET_GYRO] << 8) | imu_aspirin2.imu_rx_buf[3+MPU_OFFSET_GYRO]);
+ z = (int16_t) ((imu_aspirin2.imu_rx_buf[4+MPU_OFFSET_GYRO] << 8) | imu_aspirin2.imu_rx_buf[5+MPU_OFFSET_GYRO]);
+
+ RATES_ASSIGN(imu.gyro_unscaled, x, y, z);
+
+#define MPU_OFFSET_ACC 2
+ x = (int16_t) ((imu_aspirin2.imu_rx_buf[0+MPU_OFFSET_ACC] << 8) | imu_aspirin2.imu_rx_buf[1+MPU_OFFSET_ACC]);
+ y = (int16_t) ((imu_aspirin2.imu_rx_buf[2+MPU_OFFSET_ACC] << 8) | imu_aspirin2.imu_rx_buf[3+MPU_OFFSET_ACC]);
+ z = (int16_t) ((imu_aspirin2.imu_rx_buf[4+MPU_OFFSET_ACC] << 8) | imu_aspirin2.imu_rx_buf[5+MPU_OFFSET_ACC]);
+
+ VECT3_ASSIGN(imu.accel_unscaled, x, y, z);
+
+ // Is this is new data
+#define MPU_OFFSET_STATUS 1
+ if (imu_aspirin2.imu_rx_buf[MPU_OFFSET_STATUS] & 0x01)
+ {
+ //gyr_valid = TRUE;
+ //acc_valid = TRUE;
+ }
+ else
+ {
+ }
}
-static inline void accel_copy_spi(void)
-{
- const int16_t ax = imu_aspirin.accel_rx_buf[1] | (imu_aspirin.accel_rx_buf[2]<<8);
- const int16_t ay = imu_aspirin.accel_rx_buf[3] | (imu_aspirin.accel_rx_buf[4]<<8);
- const int16_t az = imu_aspirin.accel_rx_buf[5] | (imu_aspirin.accel_rx_buf[6]<<8);
- VECT3_ASSIGN(imu.accel_unscaled, ax, ay, az);
-}
-
-
-static inline void imu_gyro_event(void (* _gyro_handler)(void))
-{
-
-}
-*/
static inline void imu_aspirin2_event(void (* _gyro_handler)(void), void (* _accel_handler)(void), void (* _mag_handler)(void))
{
+ LED_TOGGLE(4);
+
if (imu_aspirin2.status == Aspirin2StatusUninit) return;
- imu_aspirin2_arch_int_disable();
- if (imu_aspirin2.imu_available) {
+ // imu_aspirin2_arch_int_disable();
+
+ if (imu_aspirin2.imu_available)
+ {
imu_aspirin2.time_since_last_reading = 0;
imu_aspirin2.imu_available = FALSE;
- //accel_copy_spi();
+ imu_from_buff();
+
+ _gyro_handler();
_accel_handler();
}
- imu_aspirin2_arch_int_enable();
+ // imu_aspirin2_arch_int_enable();
// Reset everything if we've been waiting too long
- if (imu_aspirin2.time_since_last_reading > ASPIRIN2_TIMEOUT) {
- imu_aspirin2.time_since_last_reading = 0;
- return;
- }
+ //if (imu_aspirin2.time_since_last_reading > ASPIRIN2_TIMEOUT) {
+ // imu_aspirin2.time_since_last_reading = 0;
+ // return;
+ //}
}
-#define ImuEvent(_gyro_handler, _accel_handler, _mag_handler) do { \
+#define ImuEvent(_gyro_handler, _accel_handler, _mag_handler) { \
imu_aspirin2_event(_gyro_handler, _accel_handler, _mag_handler); \
-} while(0);
+}
#endif /* IMU_ASPIRIN_H */