1
+ #include " bme69x.hpp"
2
+ #include " pico/stdlib.h"
3
+
4
+ namespace pimoroni {
5
+ bool BME69X::init () {
6
+ int8_t result = 0 ;
7
+
8
+ if (interrupt != PIN_UNUSED) {
9
+ gpio_set_function (interrupt, GPIO_FUNC_SIO);
10
+ gpio_set_dir (interrupt, GPIO_IN);
11
+ gpio_pull_up (interrupt);
12
+ }
13
+
14
+ i2c_interface.i2c = i2c;
15
+ i2c_interface.address = address;
16
+
17
+ device.intf_ptr = &i2c_interface;
18
+ device.intf = bme69x_intf::BME69X_I2C_INTF;
19
+ device.read = (bme69x_read_fptr_t )&read_bytes;
20
+ device.write = (bme69x_write_fptr_t )&write_bytes;
21
+ device.delay_us = (bme69x_delay_us_fptr_t )&delay_us;
22
+ device.amb_temp = 20 ;
23
+
24
+ result = bme69x_init (&device);
25
+ bme69x_check_rslt (" bme69x_init" , result);
26
+ if (result != BME69X_OK) return false ;
27
+
28
+ result = bme69x_get_conf (&conf, &device);
29
+ bme69x_check_rslt (" bme69x_get_conf" , result);
30
+ if (result != BME69X_OK) return false ;
31
+
32
+ configure (BME69X_FILTER_OFF, BME69X_ODR_NONE, BME69X_OS_16X, BME69X_OS_1X, BME69X_OS_2X);
33
+
34
+ return true ;
35
+ }
36
+
37
+ bool BME69X::configure (uint8_t filter, uint8_t odr, uint8_t os_humidity, uint8_t os_pressure, uint8_t os_temp) {
38
+ int8_t result = 0 ;
39
+
40
+ conf.filter = filter;
41
+ conf.odr = odr;
42
+ conf.os_hum = os_humidity;
43
+ conf.os_pres = os_pressure;
44
+ conf.os_temp = os_temp;
45
+
46
+ bme69x_set_conf (&conf, &device);
47
+ bme69x_check_rslt (" bme69x_set_conf" , result);
48
+ if (result != BME69X_OK) return false ;
49
+
50
+ return true ;
51
+ }
52
+
53
+ bool BME69X::read_forced (bme69x_data *data, uint16_t heater_temp, uint16_t heater_duration) {
54
+ int8_t result = 0 ;
55
+ uint8_t n_fields;
56
+ uint32_t delay_period;
57
+
58
+ heatr_conf.enable = BME69X_ENABLE;
59
+ heatr_conf.heatr_temp = heater_temp;
60
+ heatr_conf.heatr_dur = heater_duration;
61
+ result = bme69x_set_heatr_conf (BME69X_FORCED_MODE, &heatr_conf, &device);
62
+ bme69x_check_rslt (" bme69x_set_heatr_conf" , result);
63
+ if (result != BME69X_OK) return false ;
64
+
65
+ result = bme69x_set_op_mode (BME69X_FORCED_MODE, &device);
66
+ bme69x_check_rslt (" bme69x_set_op_mode" , result);
67
+ if (result != BME69X_OK) return false ;
68
+
69
+ delay_period = bme69x_get_meas_dur (BME69X_FORCED_MODE, &conf, &device) + (heatr_conf.heatr_dur * 1000 );
70
+ // Could probably just call sleep_us here directly, I guess the API uses this internally
71
+ device.delay_us (delay_period, device.intf_ptr );
72
+
73
+ result = bme69x_get_data (BME69X_FORCED_MODE, data, &n_fields, &device);
74
+ bme69x_check_rslt (" bme69x_get_data" , result);
75
+ if (result != BME69X_OK) return false ;
76
+
77
+ return true ;
78
+ }
79
+
80
+ /*
81
+ Will read profile_length results with the given temperatures and duration multipliers into the results array.
82
+ Blocks until it has a valid result for each temp/duration, and returns the entire set in the given order.
83
+ */
84
+ bool BME69X::read_parallel (bme69x_data *results, uint16_t *profile_temps, uint16_t *profile_durations, size_t profile_length) {
85
+ int8_t result;
86
+ bme69x_data data[3 ]; // Parallel & Sequential mode read 3 simultaneous fields
87
+ uint8_t n_fields;
88
+ uint32_t delay_period;
89
+
90
+ heatr_conf.enable = BME69X_ENABLE;
91
+ heatr_conf.heatr_temp_prof = profile_temps;
92
+ heatr_conf.heatr_dur_prof = profile_durations;
93
+ heatr_conf.profile_len = profile_length;
94
+ heatr_conf.shared_heatr_dur = 140 - (bme69x_get_meas_dur (BME69X_PARALLEL_MODE, &conf, &device) / 1000 );
95
+ result = bme69x_set_heatr_conf (BME69X_PARALLEL_MODE, &heatr_conf, &device);
96
+ bme69x_check_rslt (" bme69x_set_heatr_conf" , result);
97
+ if (result != BME69X_OK) return false ;
98
+
99
+ result = bme69x_set_op_mode (BME69X_PARALLEL_MODE, &device);
100
+ bme69x_check_rslt (" bme69x_set_op_mode" , result);
101
+ if (result != BME69X_OK) return false ;
102
+
103
+ while (1 ) {
104
+ delay_period = bme69x_get_meas_dur (BME69X_PARALLEL_MODE, &conf, &device) + (heatr_conf.shared_heatr_dur * 1000 );
105
+ device.delay_us (delay_period, device.intf_ptr );
106
+
107
+ result = bme69x_get_data (BME69X_PARALLEL_MODE, data, &n_fields, &device);
108
+ if (result == BME69X_W_NO_NEW_DATA) continue ;
109
+ bme69x_check_rslt (" bme69x_get_data" , result);
110
+ if (result != BME69X_OK) return false ;
111
+
112
+ for (auto i = 0u ; i < n_fields; i++) {
113
+ results[data[i].gas_index ] = data[i];
114
+
115
+ if (data[i].gas_index == profile_length - 1 ) return true ;
116
+ }
117
+ }
118
+
119
+ return true ;
120
+ }
121
+ }
0 commit comments