UoS³ Flight Computer Firmware
 All Data Structures Files Functions Groups Pages
imu.c
Go to the documentation of this file.
1 
11 #include "board.h"
12 #include "../i2c.h"
13 
14 #include "../imu.h"
15 
16  // the useful hardware constants (only used here so not moved away as yet)
17 
18 #define MPU_I2C_ADDR 0x68 // this is the MPU-9250A i2c address %1011000
19 #define MAG_I2C_ADDR 0x0C // MAG_PASS_THROUGH_I2C_ADDR
20 
21 // MPU 9250 registers
22 
23 #define MPU_CONFIG 26
24 #define MPU_GYRO_CONFIG 27
25 #define MPU_ACCEL_CONFIG 28
26 #define MPU_ACCEL_XOUT 59
27 #define MPU_ACCEL_YOUT 61
28 #define MPU_ACCEL_ZOUT 63
29 #define MPU_TEMP_OUT 65
30 #define MPU_GYRO_XOUT 67
31 #define MPU_GYRO_YOUT 69
32 #define MPU_GYRO_ZOUT 71
33 #define MPU_WHO_AM_I 117
34 #define MPU_INT_BYPASS_ENABLE 55
35 
36 #define MAG_HXL 3
37 #define MAG_HYL 5
38 #define MAG_HZL 7 // offsets in magnetometer, note little endian, so need to be read opposite way round
39 #define MAG_ST2 0x09
40 #define MAG_CNTL1 10 // Magnetometer control register
41 #define MAG_STA1 2 // read only gives flags at 1 for DRDY and 2 for DOR (data ready and overload), used in read cycle
42 
43 void IMU_Init(void)
44 {
45  uint8_t i2cstring[3]; // static buffer for i2c calls here
46 
47  i2cstring[0] = MPU_INT_BYPASS_ENABLE;
48  uint8_t i2cstatus = I2CReceive(I2C_IMU, MPU_I2C_ADDR ,MPU_INT_BYPASS_ENABLE);
49  i2cstring[1] = i2cstatus | MPU_INT_BYPASS_ENABLE; // flag bypass on
50  i2cstring[3] = 0; // null terminated string
51  I2CSendString(I2C_IMU, MPU_I2C_ADDR, i2cstring); // turn on bypass to Magnetometer so visible on I2C
52 
53  // setup magnetometer
54  i2cstring[0] = MAG_CNTL1;
55  i2cstring[2] = 0;
56  i2cstring[1] = 0; // set mode to zero before changing mode
57  I2CSendString(I2C_IMU, MAG_I2C_ADDR, i2cstring); // set Magnetometer to safe mode before mode change
58  i2cstring[1] = 0x12; // continuous (16hz) mode 1 with 16bit range
59  I2CSendString(I2C_IMU, MAG_I2C_ADDR, i2cstring);
60 }
61 
62 void IMU_set_accel_sensitivity(imu_accel_sensitivity_t imu_accel_sensitivity)
63 {
64  switch(imu_accel_sensitivity)
65  {
66  case IMU_ACCEL_2G:
67  break;
68 
69  case IMU_ACCEL_4G:
70  break;
71 
72  case IMU_ACCEL_8G:
73  break;
74 
75  case IMU_ACCEL_16G:
76  break;
77 
78  default:
79  break;
80  }
81 }
82 
83 void IMU_set_accel_bandwidth(imu_bandwidth_t imu_accel_bandwidth)
84 {
85  switch(imu_accel_bandwidth)
86  {
87  case IMU_BW_5HZ:
88  break;
89 
90  case IMU_BW_10HZ:
91  break;
92 
93  case IMU_BW_20HZ:
94  break;
95 
96  case IMU_BW_41HZ:
97  break;
98 
99  case IMU_BW_92HZ:
100  break;
101 
102  case IMU_BW_184HZ:
103  break;
104 
105  case IMU_BW_460HZ:
106  break;
107 
108  default:
109  break;
110  }
111 }
112 
113 void IMU_set_gyro_sensitivity(imu_gyro_sensitivity_t imu_gyro_sensitivity)
114 {
115  switch(imu_gyro_sensitivity)
116  {
117  case IMU_GYRO_250DEG_S:
118  break;
119 
120  case IMU_GYRO_500DEG_S:
121  break;
122 
123  case IMU_GYRO_1000DEG_S:
124  break;
125 
126  case IMU_GYRO_2000DEG_S:
127  break;
128 
129  default:
130  break;
131  }
132 }
133 
134 void IMU_set_gyro_bandwidth(imu_bandwidth_t imu_gyro_bandwidth)
135 {
136  switch(imu_gyro_bandwidth)
137  {
138  case IMU_BW_5HZ:
139  break;
140 
141  case IMU_BW_10HZ:
142  break;
143 
144  case IMU_BW_20HZ:
145  break;
146 
147  case IMU_BW_41HZ:
148  break;
149 
150  case IMU_BW_92HZ:
151  break;
152 
153  case IMU_BW_184HZ:
154  break;
155 
156  case IMU_BW_460HZ:
157  break;
158 
159  default:
160  break;
161  }
162 }
163 
164 bool IMU_selftest(void)
165 {
166  //uint8_t mag_id=I2CReceive(I2C_IMU, MAG_PASS_THROUGH_I2C_ADDR,0); // magnetometer ID (hopefully)
167 
168  return true;
169 }
170 
171 void IMU_read_accel(int16_t *accel_x, int16_t *accel_y, int16_t *accel_z)
172 {
173  *accel_x = (int16_t)I2CReceive16(I2C_IMU, MPU_I2C_ADDR, MPU_ACCEL_XOUT);
174  *accel_y = (int16_t)I2CReceive16(I2C_IMU, MPU_I2C_ADDR, MPU_ACCEL_YOUT);
175  *accel_z = (int16_t)I2CReceive16(I2C_IMU, MPU_I2C_ADDR, MPU_ACCEL_ZOUT);
176 }
177 
178 void IMU_read_gyro(int16_t *gyro_x, int16_t *gyro_y, int16_t *gyro_z)
179 {
180  // TODO: DC Bias must be removed by calibrating regs 19-24
181 
182  *gyro_x = (int16_t)I2CReceive16(I2C_IMU, MPU_I2C_ADDR, MPU_GYRO_XOUT);
183  *gyro_y = (int16_t)I2CReceive16(I2C_IMU, MPU_I2C_ADDR, MPU_GYRO_YOUT);
184  *gyro_z = (int16_t)I2CReceive16(I2C_IMU, MPU_I2C_ADDR, MPU_GYRO_ZOUT);
185 }
186 
187 void IMU_read_magno(int16_t *magno_x, int16_t *magno_y, int16_t *magno_z)
188 {
189  // TODO: Adjust using calibration data from ASAX, ASAY, ASAZ registers.
190 
191  *magno_x = (int16_t)I2CReceive16r(I2C_IMU, MAG_I2C_ADDR, MAG_HXL);
192  *magno_y = (int16_t)I2CReceive16r(I2C_IMU, MAG_I2C_ADDR, MAG_HYL);
193  *magno_z = (int16_t)I2CReceive16r(I2C_IMU, MAG_I2C_ADDR, MAG_HZL);
194  (void)I2CReceive16r(I2C_IMU, MAG_I2C_ADDR, MAG_ST2);
195 }
196 
197 void IMU_read_temp(int16_t *temp_imu)
198 {
199  // TODO: Add adjustments based on calibration data in register reference.
200  // It is currently unclear where to get these values, awaiting reply from the manufacturer before implementing.
201  *temp_imu = (int16_t)I2CReceive16(I2C_IMU, MPU_I2C_ADDR, MPU_TEMP_OUT);
202  //*temp_imu = (int16_t)((*temp_imu - RoomTemp_Offset)/Temp_Sensitivity + 21);
203 }
void IMU_read_temp(int16_t *temp_imu)
Definition: imu.c:197
void IMU_Init(void)
Definition: imu.c:43
bool IMU_selftest(void)
Definition: imu.c:164
void IMU_read_magno(int16_t *magno_x, int16_t *magno_y, int16_t *magno_z)
Definition: imu.c:187
void IMU_read_gyro(int16_t *gyro_x, int16_t *gyro_y, int16_t *gyro_z)
Definition: imu.c:178
void IMU_read_accel(int16_t *accel_x, int16_t *accel_y, int16_t *accel_z)
Definition: imu.c:171