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
134
135
136
137
138
139
140
141
142
143
144
145
|
#include "altimeter.hpp"
#include "hardware/gpio.h"
altimeter::altimeter(i2c_inst_t* inst, uint8_t addr) {
this->inst = inst;
this->addr = addr;
}
void altimeter::initialize() {
// Select control register(0x26)
// Active mode, OSR = 16, altimeter mode(0xB8)
this->buffer[0] = 0x26;
this->buffer[1] = 0x89;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
}
void altimeter::initialize(float threshold_altitude, uint8_t interrupt_pin, gpio_irq_callback_t callback) {
this->initialize();
// Below configures the interrupt for the first transition from PAD to BOOST
// Initial Reading
sleep_ms(1000);
float altitude = 0.0f;
while (altitude == 0.0f) {
altitude = this->get_altitude_converted();
}
threshold_altitude += altitude; // 30 meters above ground
// Select control register 3 (0x28)
// Set bot interrupt pins to active low and enable internal pullups
this->buffer[0] = 0x28;
this->buffer[1] = 0x01;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select pressure target MSB register(0x16)
// Set altitude target to 30 meters above ground altitude
this->buffer[0] = 0x16;
this->buffer[1] = (uint8_t) (((int16_t)(threshold_altitude)) >> 8);
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select pressure target LSB register(0x17)
// Set altitude target to 30 meters above ground altitude
this->buffer[0] = 0x17;
this->buffer[1] = (uint8_t) (((int16_t)(threshold_altitude)));
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select interrupt enable register (0x29)
// Set interrupt enabled for altitude threshold(0x08)
this->buffer[0] = 0x29;
this->buffer[1] = 0x08;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select interrupt this->bufferuration register (0x2A)
// Set interrupt enabled for altitude threshold to route to INT1 pin(0x08)
this->buffer[0] = 0x2A;
this->buffer[1] = 0x08;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
gpio_set_irq_enabled_with_callback(interrupt_pin, GPIO_IRQ_LEVEL_LOW, true, callback);
// End of configuration of interrupt for first transition from PAD to BOOST
}
void altimeter::set_threshold_altitude(float threshold_altitude, uint8_t interrupt_pin, gpio_irq_callback_t callback) {
float altitude = 0.0f;
while (altitude == 0.0f) {
altitude = get_altitude_converted();
}
threshold_altitude += altitude;
// Select control register 3 (0x28)
// Set bot interrupt pins to active low and enable internal pullups
this->buffer[0] = 0x28;
this->buffer[1] = 0x01;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select pressure target MSB register(0x16)
// Set altitude target to 30 meters above ground altitude
this->buffer[0] = 0x16;
this->buffer[1] = (uint8_t) (((int16_t)(threshold_altitude)) >> 8);
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select pressure target LSB register(0x17)
// Set altitude target to provided threshold altitude
this->buffer[0] = 0x17;
this->buffer[1] = (uint8_t) (((int16_t)(threshold_altitude)));
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select interrupt enable register (0x29)
// Set interrupt enabled for altitude threshold(0x08)
this->buffer[0] = 0x29;
this->buffer[1] = 0x08;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select interrupt this->bufferuration register (0x2A)
// Set interrupt enabled for altitude threshold to route to INT1 pin(0x08)
this->buffer[0] = 0x2A;
this->buffer[1] = 0x08;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
gpio_set_irq_enabled_with_callback(interrupt_pin, GPIO_IRQ_LEVEL_LOW, true, callback);
// End of configuration of interrupt for first transition from PAD to BOOST
}
void altimeter::unset_threshold_altitude(uint8_t interrupt_pin) {
gpio_set_irq_enabled_with_callback(interrupt_pin, GPIO_IRQ_LEVEL_LOW, false, NULL);
// Select interrupt enable register (0x29)
// Set interrupt enabled for altitude threshold(0x08)
this->buffer[0] = 0x29;
this->buffer[1] = 0x00;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
// Select interrupt configuration register (0x2A)
// Set interrupt enabled for altitude threshold to route to INT1 pin(0x08)
this->buffer[0] = 0x2A;
this->buffer[1] = 0x00;
i2c_write_blocking(this->inst, this->addr, this->buffer, 2, true);
}
float altimeter::get_altitude_converted() {
uint8_t reg = 0x01;
i2c_write_blocking(this->inst, this->addr, ®, 1, true);
i2c_read_blocking(this->inst, this->addr, this->altitude_buffer, 4, false);
// Exactly how MPL3115A2 datasheet says to retrieve altitude
float altitude = (float) ((int16_t) ((this->altitude_buffer[0] << 8) | this->altitude_buffer[1])) + (float) (this->altitude_buffer[2] >> 4) * 0.0625;
return altitude;
}
void altimeter::get_altitude_raw(uint8_t* buffer) {
uint8_t reg = 0x01;
i2c_write_blocking(this->inst, this->addr, ®, 1, true);
i2c_read_blocking(this->inst, this->addr, buffer, 3, false);
}
uint32_t altimeter::expose_buffer(uint8_t** buffer) {
*buffer = this->altitude_buffer;
return sizeof(this->altitude_buffer);
}
|