-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBno055Interface.cpp
130 lines (115 loc) · 4.49 KB
/
Bno055Interface.cpp
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
//
// Created by volundr on 7/19/16.
//
#include <vector>
#include <iostream>
#include "Bno055Interface.h"
#define RESPONSE_WAIT_WRITE 2000
#define RESPONSE_WAIT_READ 10000
namespace bno055 {
bool Bno055Interface::init(const char* bno055File) {
bool wasSuccess = true;
if ( ! uart.openPort(bno055File, BNO055_BAUD_RATE) ) {
std::cout << "Could not open serial connection to bno055!\n";
wasSuccess = false;
}
#define TRY_SEND_BYTE(byteSent, value) \
if ( ! writeByte(byteSent, value) ) {\
std::cout << "Did not receive response after sending " #byteSent "\n";\
wasSuccess = false; }
TRY_SEND_BYTE(OPR_MODE, CONFIG)
TRY_SEND_BYTE(PWR_MODE, NORMAL)
TRY_SEND_BYTE(Page_ID, 0)
TRY_SEND_BYTE(SYS_TRIGGER, 0)
TRY_SEND_BYTE(UNIT_SEL, 0x83)
TRY_SEND_BYTE(AXIS_MAP_CONFIG, 0x24)
TRY_SEND_BYTE(AXIS_MAP_SIGN, 0x06)
TRY_SEND_BYTE(OPR_MODE, NDOF)
#undef TRY_SEND_BYTE
hasInit = wasSuccess;
return wasSuccess;
}
bool Bno055Interface::write(uint8_t regAddr, uint8_t length, uint8_t* data) {
RegisterWritePacket packetToSend(regAddr, length, data);
ReceivedAck ack;
int loopCounter = 0;
do {
uart.sendData(packetToSend.bytes(), packetToSend.length);
usleep(RESPONSE_WAIT_WRITE); // 2 ms
if (++loopCounter >= 1000000 / RESPONSE_WAIT_WRITE) {
std::cout << "Write timed out!\n";
return false;
}
} while (ack.readFrom(uart) != RECEIVED_EXPECTED || ack.isErrorStatus());
return true;
}
static bool pullData(RegisterReadPacket& readRequestPacket, ReceivedRead& dataReceived, UartInterface& uart) {
int loopCounter = 0;
do {
uart.sendData(readRequestPacket.bytes(), readRequestPacket.length);
usleep(RESPONSE_WAIT_READ);
if (++loopCounter >= 1000000 / RESPONSE_WAIT_READ) {
std::cout << "Read timed out!\n";
return false;
}
int receivedExpected = dataReceived.readFrom(uart);
if (receivedExpected == RECEIVED_EXPECTED) {
break;
} else if (receivedExpected == RECEIVED_ACK) {
std::cout << "Read request failed: " << dataReceived.getAck() << ": request was: ";
std::cout << readRequestPacket.toString() << std::endl;
} else if (receivedExpected == RECEIVED_WRONG_LENGTH) {
std::cout << "received wrong length." << std::endl;
} else {
std::cout << "received unexpected: " << dataReceived.toString() << std::endl;
}
} while(true);
return true;
}
bool Bno055Interface::queryImuData(ImuData_16* out) {
RegisterReadPacket readRequestPacket(ACC_DATA_X_LSB, 46);
ReceivedRead dataReceived;
if (!pullData(readRequestPacket, dataReceived, uart)) {
return false;
}
*out = *(ImuData_16*)&dataReceived.data;
return true;
}
bool Bno055Interface::queryVec3(Vec3_16* vec3Out, availableVec3sToQuery regBegin) {
RegisterReadPacket readRequestPacket(regBegin, 6);
ReceivedRead dataReceived;
if (!pullData(readRequestPacket, dataReceived, uart)) {
return false;
}
*vec3Out = *(Vec3_16*)&dataReceived.data;
return true;
}
bool Bno055Interface::queryVec4(Vec4_16* vec4Out, availableVec4sToQuery regBegin) {
RegisterReadPacket readRequestPacket(regBegin, 8);
ReceivedRead dataReceived;
if (!pullData(readRequestPacket, dataReceived, uart)) {
return false;
}
*vec4Out = *(Vec4_16*)&dataReceived.data;
return true;
}
bool Bno055Interface::queryChunk_16(int16_t *out, int start, size_t length) {
RegisterReadPacket readRequestPacket((uint8_t) start, (uint8_t)length);
ReceivedRead dataReceived;
if (!pullData(readRequestPacket, dataReceived, uart)) {
return false;
}
int16_t* data_16 = (int16_t*) dataReceived.data;
for (int i = 0; i < length / 2; ++i) {
out[i] = data_16[i];
}
*out = *(int16_t*)&dataReceived.data;
return true;
}
bool Bno055Interface::writeByte(uint8_t regAddr, uint8_t data) {
return write(regAddr, 1, &data);
}
bool Bno055Interface::isLive() {
return hasInit;
}
}