Paparazzi UAS  v5.8.2_stable-0-g6260b7c
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
imu_aspirin2.c
Go to the documentation of this file.
1 /*
2  * This file is part of paparazzi.
3  *
4  * paparazzi is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2, or (at your option)
7  * any later version.
8  *
9  * paparazzi is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with paparazzi; see the file COPYING. If not, write to
16  * the Free Software Foundation, 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  */
20 
21 #include <math.h>
22 #include "imu_aspirin2.h"
23 #include "mcu_periph/i2c.h"
24 #include "led.h"
25 #include "subsystems/abi.h"
26 
27 // Downlink
28 #include "mcu_periph/uart.h"
29 #include "messages.h"
31 
32 
33 
34 // Peripherials
35 #include "../../peripherals/mpu60x0.h"
36 // #include "../../peripherals/hmc5843.h"
37 
38 // Communication
40 
41 // Standalone option: run module only
42 #ifndef IMU_TYPE_H
43 struct Imu imu;
44 #endif
45 
46 #ifndef PERIODIC_FREQUENCY
47 #define PERIODIC_FREQUENCY 60
48 #endif
49 
50 void imu_impl_init(void)
51 {
52 
54  // Configure power:
55 
56  // MPU60X0_REG_AUX_VDDIO = 0 (good on startup)
57 
58  // MPU60X0_REG_USER_CTRL:
59  // -Enable Aux I2C Master Mode
60  // -Enable SPI
61 
62  // MPU60X0_REG_PWR_MGMT_1
63  // -switch to gyroX clock
65  aspirin2_mpu60x0.buf[1] = 0x01;
66  i2c_transmit(&PPZUAVIMU_I2C_DEV, &aspirin2_mpu60x0, MPU60X0_ADDR, 2);
68 
69  // MPU60X0_REG_PWR_MGMT_2: Nothing should be in standby: default OK
70 
72  // Measurement Settings
73 
74  // MPU60X0_REG_CONFIG
75  // -ext sync on gyro X (bit 3->6)
76  // -digital low pass filter: 1kHz sampling of gyro/acc with 44Hz bandwidth: since reading is at 100Hz
77 #if PERIODIC_FREQUENCY == 60
78 #else
79 # if PERIODIC_FREQUENCY == 120
80 # else
81 # error PERIODIC_FREQUENCY should be either 60Hz or 120Hz. Otherwise manually fix the sensor rates
82 # endif
83 #endif
85  aspirin2_mpu60x0.buf[1] = (2 << 3) | (3 << 0);
86  i2c_transmit(&PPZUAVIMU_I2C_DEV, &aspirin2_mpu60x0, MPU60X0_ADDR, 2);
88 
89  // MPU60X0_REG_SMPLRT_DIV
90  // -100Hz output = 1kHz / (9 + 1)
92  aspirin2_mpu60x0.buf[1] = 9;
93  i2c_transmit(&PPZUAVIMU_I2C_DEV, &aspirin2_mpu60x0, MPU60X0_ADDR, 2);
95 
96  // MPU60X0_REG_GYRO_CONFIG
97  // -2000deg/sec
99  aspirin2_mpu60x0.buf[1] = (3 << 3);
100  i2c_transmit(&PPZUAVIMU_I2C_DEV, &aspirin2_mpu60x0, MPU60X0_ADDR, 2);
102 
103  // MPU60X0_REG_ACCEL_CONFIG
104  // 16g, no HPFL
106  aspirin2_mpu60x0.buf[1] = (3 << 3);
107  i2c_transmit(&PPZUAVIMU_I2C_DEV, &aspirin2_mpu60x0, MPU60X0_ADDR, 2);
109 
110 
111 
112 
113 
114  /*
115  // no interrupts for now, but set data ready interrupt to enable reading status bits
116  aspirin2_mpu60x0.buf[0] = ITG3200_REG_INT_CFG;
117  aspirin2_mpu60x0.buf[1] = 0x01;
118  i2c_submit(&PPZUAVIMU_I2C_DEV,&aspirin2_mpu60x0);
119  while(aspirin2_mpu60x0.status == I2CTransPending);
120  */
121 
122  /*
124  // HMC5843
125  ppzuavimu_hmc5843.slave_addr = HMC5843_ADDR;
126  ppzuavimu_hmc5843.type = I2CTransTx;
127  ppzuavimu_hmc5843.buf[0] = HMC5843_REG_CFGA; // set to rate to max speed: 50Hz no bias
128  ppzuavimu_hmc5843.buf[1] = 0x00 | (0x06 << 2);
129  ppzuavimu_hmc5843.len_w = 2;
130  i2c_submit(&PPZUAVIMU_I2C_DEV,&ppzuavimu_hmc5843);
131  while(ppzuavimu_hmc5843.status == I2CTransPending);
132 
133  ppzuavimu_hmc5843.type = I2CTransTx;
134  ppzuavimu_hmc5843.buf[0] = HMC5843_REG_CFGB; // set to gain to 1 Gauss
135  ppzuavimu_hmc5843.buf[1] = 0x01<<5;
136  ppzuavimu_hmc5843.len_w = 2;
137  i2c_submit(&PPZUAVIMU_I2C_DEV,&ppzuavimu_hmc5843);
138  while(ppzuavimu_hmc5843.status == I2CTransPending);
139 
140  ppzuavimu_hmc5843.type = I2CTransTx;
141  ppzuavimu_hmc5843.buf[0] = HMC5843_REG_MODE; // set to continuous mode
142  ppzuavimu_hmc5843.buf[1] = 0x00;
143  ppzuavimu_hmc5843.len_w = 2;
144  i2c_submit(&PPZUAVIMU_I2C_DEV,&ppzuavimu_hmc5843);
145  while(ppzuavimu_hmc5843.status == I2CTransPending);
146  */
147 }
148 
149 void imu_periodic(void)
150 {
151  // Start reading the latest gyroscope data
153  i2c_transceive(&PPZUAVIMU_I2C_DEV, &aspirin2_mpu60x0, MPU60X0_ADDR, 1, 21);
154 
155  /*
156  // Start reading the latest accelerometer data
157  ppzuavimu_adxl345.buf[0] = ADXL345_REG_DATA_X0;
158  i2c_transceive(&PPZUAVIMU_I2C_DEV, &ppzuavimu_adxl345, ADXL345_ADDR, 1, 6);
159  */
160  // Start reading the latest magnetometer data
161 #if PERIODIC_FREQUENCY > 60
162  RunOnceEvery(2, {
163 #endif
164  /* ppzuavimu_hmc5843.type = I2CTransTxRx;
165  ppzuavimu_hmc5843.len_r = 6;
166  ppzuavimu_hmc5843.len_w = 1;
167  ppzuavimu_hmc5843.buf[0] = HMC5843_REG_DATXM;
168  i2c_submit(&PPZUAVIMU_I2C_DEV, &ppzuavimu_hmc5843);
169  */
170 #if PERIODIC_FREQUENCY > 60
171  });
172 #endif
173  //RunOnceEvery(10,aspirin2_subsystem_downlink_raw());
174 }
175 
177 {
178  DOWNLINK_SEND_IMU_GYRO_RAW(DefaultChannel, DefaultDevice, &imu.gyro_unscaled.p, &imu.gyro_unscaled.q,
179  &imu.gyro_unscaled.r);
180  DOWNLINK_SEND_IMU_ACCEL_RAW(DefaultChannel, DefaultDevice, &imu.accel_unscaled.x, &imu.accel_unscaled.y,
181  &imu.accel_unscaled.z);
182  DOWNLINK_SEND_IMU_MAG_RAW(DefaultChannel, DefaultDevice, &imu.mag_unscaled.x, &imu.mag_unscaled.y, &imu.mag_unscaled.z);
183 }
184 
186 {
187  int32_t x, y, z;
188  uint32_t now_ts = get_sys_time_usec();
189 
190  // If the itg3200 I2C transaction has succeeded: convert the data
192 #define MPU_OFFSET_GYRO 9
196 
197  RATES_ASSIGN(imu.gyro_unscaled, x, y, z);
198 
199 #define MPU_OFFSET_ACC 1
203 
204  VECT3_ASSIGN(imu.accel_unscaled, x, y, z);
205 
206  // Is this is new data
207  if (aspirin2_mpu60x0.buf[0] & 0x01) {
210  AbiSendMsgIMU_GYRO_INT32(IMU_PPZUAV_ID, now_ts, &imu.gyro);
211  AbiSendMsgIMU_ACCEL_INT32(IMU_PPZUAV_ID, now_ts, &imu.accel);
212  }
213 
215  I2CTransDone; // remove the I2CTransSuccess status, otherwise data ready will be triggered again without new data
216  }
217  /*
218  // If the adxl345 I2C transaction has succeeded: convert the data
219  if (ppzuavimu_adxl345.status == I2CTransSuccess)
220  {
221  x = (int16_t) ((ppzuavimu_adxl345.buf[1] << 8) | ppzuavimu_adxl345.buf[0]);
222  y = (int16_t) ((ppzuavimu_adxl345.buf[3] << 8) | ppzuavimu_adxl345.buf[2]);
223  z = (int16_t) ((ppzuavimu_adxl345.buf[5] << 8) | ppzuavimu_adxl345.buf[4]);
224 
225  #ifdef ASPIRIN_IMU
226  VECT3_ASSIGN(imu.accel_unscaled, x, -y, -z);
227  #else // PPZIMU
228  VECT3_ASSIGN(imu.accel_unscaled, -x, y, -z);
229  #endif
230 
231  acc_valid = TRUE;
232  ppzuavimu_adxl345.status = I2CTransDone;
233  }
234 
235  // If the hmc5843 I2C transaction has succeeded: convert the data
236  if (ppzuavimu_hmc5843.status == I2CTransSuccess)
237  {
238  x = (int16_t) ((ppzuavimu_hmc5843.buf[0] << 8) | ppzuavimu_hmc5843.buf[1]);
239  y = (int16_t) ((ppzuavimu_hmc5843.buf[2] << 8) | ppzuavimu_hmc5843.buf[3]);
240  z = (int16_t) ((ppzuavimu_hmc5843.buf[4] << 8) | ppzuavimu_hmc5843.buf[5]);
241 
242  #ifdef ASPIRIN_IMU
243  VECT3_ASSIGN(imu.mag_unscaled, x, -y, -z);
244  #else // PPZIMU
245  VECT3_ASSIGN(imu.mag_unscaled, -y, -x, -z);
246  #endif
247 
248  mag_valid = TRUE;
249  ppzuavimu_hmc5843.status = I2CTransDone;
250  }
251  */
252 }
253 
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
void imu_impl_init(void)
must be defined by underlying hardware
Definition: imu_aspirin2.c:50
#define MPU60X0_REG_PWR_MGMT_1
Definition: mpu60x0_regs.h:40
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
void imu_scale_gyro(struct Imu *_imu)
Definition: ahrs_gx3.c:349
transaction successfully finished by I2C driver
Definition: i2c.h:57
void imu_scale_accel(struct Imu *_imu)
Definition: ahrs_gx3.c:350
#define VECT3_ASSIGN(_a, _x, _y, _z)
Definition: pprz_algebra.h:124
#define RATES_ASSIGN(_ra, _p, _q, _r)
Definition: pprz_algebra.h:329
Main include for ABI (AirBorneInterface).
#define MPU60X0_REG_SMPLRT_DIV
Definition: mpu60x0_regs.h:50
void aspirin2_subsystem_event(void)
Definition: imu_aspirin2.c:185
#define MPU60X0_REG_CONFIG
Definition: mpu60x0_regs.h:51
bool_t i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition: i2c.c:278
void aspirin2_subsystem_downlink_raw(void)
Definition: imu_aspirin2.c:176
static uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.h:39
struct Int32Vect3 mag_unscaled
unscaled magnetometer measurements
Definition: imu.h:52
int32_t r
in rad/s with INT32_RATE_FRAC
struct Int32Rates gyro_unscaled
unscaled gyroscope measurements
Definition: imu.h:50
struct Int32Vect3 accel
accelerometer measurements in m/s^2 in BFP with INT32_ACCEL_FRAC
Definition: imu.h:43
transaction set to done by user level
Definition: i2c.h:59
struct Imu imu
global IMU state
Definition: imu_aspirin2.c:43
#define MPU_OFFSET_ACC
bool_t i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition: i2c.c:258
unsigned long uint32_t
Definition: types.h:18
signed short int16_t
Definition: types.h:17
I2C transaction structure.
Definition: i2c.h:93
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
#define MPU60X0_ADDR
Definition: mpu60x0_regs.h:32
signed long int32_t
Definition: types.h:19
#define MPU60X0_REG_INT_STATUS
Definition: mpu60x0_regs.h:89
#define IMU_PPZUAV_ID
#define MPU_OFFSET_GYRO
struct i2c_transaction aspirin2_mpu60x0
Definition: imu_aspirin2.c:39
int32_t p
in rad/s with INT32_RATE_FRAC
arch independent LED (Light Emitting Diodes) API
struct Int32Vect3 accel_unscaled
unscaled accelerometer measurements
Definition: imu.h:51
void imu_periodic(void)
optional.
Definition: imu_aspirin2.c:149
abstract IMU interface providing fixed point interface
Definition: imu.h:41
int32_t q
in rad/s with INT32_RATE_FRAC
#define MPU60X0_REG_GYRO_CONFIG
Definition: mpu60x0_regs.h:52
transaction is pending in queue
Definition: i2c.h:55
#define MPU60X0_REG_ACCEL_CONFIG
Definition: mpu60x0_regs.h:53
struct Int32Rates gyro
gyroscope measurements in rad/s in BFP with INT32_RATE_FRAC
Definition: imu.h:42
Architecture independent I2C (Inter-Integrated Circuit Bus) API.