-
Notifications
You must be signed in to change notification settings - Fork 18
/
sensor.c
136 lines (105 loc) · 3.19 KB
/
sensor.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "i2c-dev.h"
#include "L3G.h"
#include "LSM303.h"
//#include "gyro.h"
int file;
void readBlock(uint8_t command, uint8_t size, uint8_t *data)
{
int result = i2c_smbus_read_i2c_block_data(file, command, size, data);
if (result != size)
{
printf("Failed to read block from I2C.");
exit(1);
}
}
void selectDevice(int file, int addr)
{
char device[3];
if (addr == 1)
device == "L3G";
else
device == "LSM";
if (ioctl(file, I2C_SLAVE, addr) < 0) {
fprintf(stderr,
"Error: Could not select device 0x%02x: %s\n",
device, strerror(errno));
}
}
void readACC(int *a)
{
uint8_t block[6];
selectDevice(file,ACC_ADDRESS);
readBlock(0x80 | LSM303_OUT_X_L_A, sizeof(block), block);
*a = (int16_t)(block[0] | block[1] << 8) >> 4;
*(a+1) = (int16_t)(block[2] | block[3] << 8) >> 4;
*(a+2) = (int16_t)(block[4] | block[5] << 8) >> 4;
}
void readMAG(int *m)
{
uint8_t block[6];
selectDevice(file,MAG_ADDRESS);
// DLHC: register address order is X,Z,Y with high bytes first
readBlock(0x80 | LSM303_OUT_X_H_M, sizeof(block), block);
*m = (int16_t)(block[1] | block[0] << 8);
*(m+1) = (int16_t)(block[5] | block[4] << 8) ;
*(m+2) = (int16_t)(block[3] | block[2] << 8) ;
}
void readGYR(int *g)
{
uint8_t block[6];
selectDevice(file,GYR_ADDRESS);
readBlock(0x80 | L3G_OUT_X_L, sizeof(block), block);
*g = (int16_t)(block[1] << 8 | block[0]);
*(g+1) = (int16_t)(block[3] << 8 | block[2]);
*(g+2) = (int16_t)(block[5] << 8 | block[4]);
}
void writeAccReg(uint8_t reg, uint8_t value)
{
selectDevice(file,ACC_ADDRESS);
int result = i2c_smbus_write_byte_data(file, reg, value);
if (result == -1)
{
printf ("Failed to write byte to I2C Acc.");
exit(1);
}
}
void writeMagReg(uint8_t reg, uint8_t value)
{
selectDevice(file,MAG_ADDRESS);
int result = i2c_smbus_write_byte_data(file, reg, value);
if (result == -1)
{
printf("Failed to write byte to I2C Mag.");
exit(1);
}
}
void writeGyrReg(uint8_t reg, uint8_t value)
{
selectDevice(file,GYR_ADDRESS);
int result = i2c_smbus_write_byte_data(file, reg, value);
if (result == -1)
{
printf("Failed to write byte to I2C Gyr.");
exit(1);
}
}
void enableIMU()
{
__u16 block[I2C_SMBUS_BLOCK_MAX];
int res, bus, size;
char filename[20];
sprintf(filename, "/dev/i2c-%d", 1);
file = open(filename, O_RDWR);
if (file<0) {
printf("Unable to open I2C bus!");
exit(1);
}
// Enable accelerometer.
writeAccReg(LSM303_CTRL_REG1_A, 0b01010111); // z,y,x axis enabled , 100Hz data rate
writeAccReg(LSM303_CTRL_REG4_A, 0b00101000); // +/- 8G full scale: FS = 10 on DLHC, high resolution output mode
// Enable magnetometer
writeMagReg(LSM303_MR_REG_M, 0x00); // enable magnometer
// Enable Gyro
writeGyrReg(L3G_CTRL_REG1, 0b00001111); // Normal power mode, all axes enabled
writeGyrReg(L3G_CTRL_REG4, 0b00110000); // Continuos update, 2000 dps full scale
}