Compare commits
10 Commits
b3783a13da
...
72572e2f9a
Author | SHA1 | Date | |
---|---|---|---|
72572e2f9a | |||
cc3cd94374 | |||
a5a125482c | |||
d942cd8d9e | |||
06baae7e04 | |||
42ab393dce | |||
73b4262ea3 | |||
20b8c8c0f0 | |||
644f99985e | |||
23de126d97 |
BIN
.gitea/gas.png
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 112 KiB |
BIN
.gitea/hum.png
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 148 KiB |
BIN
.gitea/press.png
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 110 KiB |
BIN
.gitea/temp.png
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 152 KiB |
7
.gitignore
vendored
@ -1,2 +1,7 @@
|
||||
*.o
|
||||
bme680
|
||||
bme680
|
||||
bme680_i2c
|
||||
bme680_spi
|
||||
bme680_log*
|
||||
plot/*.png
|
||||
plot/*.txt
|
41
Makefile
@ -1,17 +1,38 @@
|
||||
CC=gcc
|
||||
OPT=-O2 -std=c99 -Wall -Wextra -W -pedantic
|
||||
CFLAGS=-I. $(OPT)
|
||||
CFILES=$(wildcard ./*.c)
|
||||
OBJECTS=$(patsubst %.c,%.o, $(CFILES))
|
||||
BINARY=bme680
|
||||
CFLAGS = -g -O0 -Wall -Wextra -Wpedantic -Wshadow -Wformat=2 -Wfloat-equal \
|
||||
-Wconversion -Wcast-align -Wpointer-arith -Wstrict-overflow=5 \
|
||||
-Wwrite-strings -Wcast-qual -Wswitch-default -Wswitch-enum \
|
||||
-Wunreachable-code -Wstrict-prototypes -Wmissing-prototypes \
|
||||
-Wmissing-declarations -Wredundant-decls -Wold-style-definition \
|
||||
-Winline -Wlogical-op -Wjump-misses-init -Wdouble-promotion \
|
||||
-Wformat-overflow=2 -Wformat-signedness -Wmissing-include-dirs \
|
||||
-Wnull-dereference -Wstack-usage=1024 -Wpacked -Woverlength-strings \
|
||||
-Wvla -Walloc-zero -Wduplicated-cond -Wduplicated-branches -Wrestrict \
|
||||
-fanalyzer -I. -std=c89
|
||||
|
||||
all: $(BINARY)
|
||||
CFILES = $(wildcard *.c)
|
||||
OBJECTS = $(CFILES:.c=.o)
|
||||
BIN = bme680
|
||||
|
||||
$(BINARY): $(OBJECTS)
|
||||
$(CC) $^ -o $@
|
||||
all: spi i2c log
|
||||
|
||||
log: $(OBJECTS)
|
||||
@echo ">>> $(BIN)_log_spi"
|
||||
@$(CC) $(CFLAGS) -DUSE_SPI -std=gnu99 $^ cmd/log.c -o "$(BIN)_log_spi"
|
||||
@echo ">>> $(BIN)_log_i2c"
|
||||
@$(CC) $(CFLAGS) -DUSE_I2C -std=gnu99 $^ cmd/log.c -o "$(BIN)_log_i2c"
|
||||
|
||||
spi: $(OBJECTS)
|
||||
@echo ">>> $(BIN)_spi"
|
||||
@$(CC) $(CFLAGS) -DUSE_SPI $^ cmd/main.c -o "$(BIN)_spi"
|
||||
|
||||
i2c: $(OBJECTS)
|
||||
@echo ">>> $(BIN)_i2c"
|
||||
@$(CC) $(CFLAGS) -DUSE_I2C $^ cmd/main.c -o "$(BIN)_i2c"
|
||||
|
||||
%.o:%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
@echo "cc $<"
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@rm -rf $(OBJECTS) $(BINARY)
|
||||
@rm -rf $(OBJECTS)
|
126
README.md
@ -14,7 +14,21 @@ Connecting the purple BME680 module board to SPI:
|
||||
| SCLK | "SCL" | GPIO 11 (Pin 23) |
|
||||
| CS | "CS" | GPIO 8 (Pin 24) |
|
||||
|
||||
## spi demo
|
||||
### build
|
||||
```sh
|
||||
$ make
|
||||
```
|
||||
This will create demo programs `bme680_i2c` and `bme680_spi`, and logging programs `bme680_log_i2c` and `bme680_log_spi`. They all expect the pin/devices specified in `spi.c` and `i2c.c`.
|
||||
|
||||
The loggers spit out the following every minute:
|
||||
```
|
||||
2024-08-19T18:20:00+0100 22.2358 101068 65.8092 11054.4 1
|
||||
```
|
||||
`Date`, `Temperature °C`, `Pressure Pa`, `% RH`, `Measured Gas resistance Ω`, `Heat stability bit`
|
||||
|
||||
>Note: disregard measured gas resistance if the heat stability bit is not 1.
|
||||
|
||||
## bme680_{i2c,spi} demo output
|
||||
```
|
||||
par_t1: 26203
|
||||
par_t2: 26519
|
||||
@ -53,50 +67,9 @@ gas resistance: 12100.310308 Ohm
|
||||
=== heat_stab_r: 1
|
||||
```
|
||||
|
||||
## i2c demo
|
||||
```
|
||||
par_t1: 26125
|
||||
par_t2: 26370
|
||||
par_t3: 3
|
||||
par_p1: 36262
|
||||
par_p2: -10371
|
||||
par_p3: 88
|
||||
par_p4: 6713
|
||||
par_p5: -103
|
||||
par_p6: 30
|
||||
par_p7: 31
|
||||
par_p8: -251
|
||||
par_p9: -3158
|
||||
par_p10: 30
|
||||
par_h1: 776
|
||||
par_h2: 1010
|
||||
par_h3: 0
|
||||
par_h4: 45
|
||||
par_h5: 20
|
||||
par_h6: 120
|
||||
par_h7: -100
|
||||
par_g1: 183
|
||||
par_g2: 59281
|
||||
par_g3: 18
|
||||
range_switching_error: 19
|
||||
res_heat_range: 1
|
||||
res_heat_val: 39
|
||||
float mode
|
||||
tfine: 97289.819111
|
||||
temp: 19.001918 degC
|
||||
press: 100226.479673 Pa
|
||||
humidity: 67.022216 % RH
|
||||
gas resistance: 14702.868852 Ohm
|
||||
== for heater target=300.0 and ambient temp=19.0 (degC)
|
||||
=== gas_valid_r: 1
|
||||
=== heat_stab_r: 1
|
||||
```
|
||||
|
||||
Note: Do not trust the gas resistance measurement if `heat_stab_r` is not `1`.
|
||||
|
||||
## Burn-in / logging
|
||||
|
||||
See file `example/log.c`
|
||||
See file `cmd/log.c`
|
||||
|
||||

|
||||

|
||||
@ -105,64 +78,11 @@ See file `example/log.c`
|
||||
|
||||
Compile and run
|
||||
```sh
|
||||
stdbuf -o0 ./bme680 2>&1 | tee -a log.txt
|
||||
```
|
||||
|
||||
This will give an output similar to this:
|
||||
```
|
||||
2024-05-14T13:03:02+0100 20.8916 99836.7 68.6594 7180.73 1
|
||||
2024-05-14T13:04:03+0100 20.8658 99840.3 68.7844 7171.53 1
|
||||
2024-05-14T13:05:03+0100 20.8979 99838.6 68.7759 7162.35 1
|
||||
2024-05-14T13:06:03+0100 20.9208 99843.8 68.6436 7166.93 1
|
||||
2024-05-14T13:07:03+0100 20.9303 99845.4 68.747 7144.05 1
|
||||
2024-05-14T13:08:03+0100 20.9249 99846 68.7122 7139.49 0
|
||||
2024-05-14T13:09:04+0100 20.9036 99845.2 68.7224 7157.76 1
|
||||
2024-05-14T13:10:04+0100 20.8737 99850.5 68.575 7144.05 1
|
||||
2024-05-14T13:11:04+0100 20.8753 99850.6 68.8879 7139.49 1
|
||||
2024-05-14T13:12:04+0100 20.9152 99849.3 68.8602 7134.94 1
|
||||
```
|
||||
|
||||
If last field is not 1 then the measurement, at least for gas resistance, cannot be trusted.
|
||||
```sh
|
||||
sed -n '/1$/p' log.txt > test.txt
|
||||
```
|
||||
|
||||
Then graph with gnuplot
|
||||
```
|
||||
# gnuplot
|
||||
reset
|
||||
|
||||
set key autotitle columnhead
|
||||
set terminal pngcairo enhanced size 2*1920/3,2*1080/3
|
||||
set grid
|
||||
set xdata time
|
||||
set timefmt "%Y-%m-%dT%H:%M:%S%z"
|
||||
|
||||
|
||||
|
||||
# gas res vs time
|
||||
set title "[I_{dac}=100, 100ms, target=300 C] GasRes over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Gas Resistance (OHM)"
|
||||
set output "gas.png"
|
||||
plot 'test.txt' u 1:5 w p pt 3 ps 1 t "BME680"
|
||||
|
||||
|
||||
set title "[I_{dac}=100, 100ms, target=300 C] Temperature over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Temperature (C)"
|
||||
set output "temp.png"
|
||||
plot 'test.txt' u 1:2 w p pt 3 ps 1 t "BME680"
|
||||
|
||||
set title "[I_{dac}=100, 100ms, target=300 C] Pressure over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Pressure (Pa)"
|
||||
set output "press.png"
|
||||
plot 'test.txt' u 1:3 w p pt 3 ps 1 t "BME680"
|
||||
|
||||
set title "[I_{dac}=100, 100ms, target=300 C] Humidity over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Humidity (%RH)"
|
||||
set output "hum.png"
|
||||
plot 'test.txt' u 1:4 w p pt 3 ps 1 t "BME680"
|
||||
$ make
|
||||
$ mkdir data
|
||||
$ stdbuf -o0 ./bme680_log_i2c 2>&1 | tee -a data/i2c.txt &
|
||||
$ stdbuf -o0 ./bme680_log_spi 2>&1 | tee -a data/spi.txt &
|
||||
# wait a couple of hours or days ..
|
||||
$ cd plot
|
||||
$ ./plot.sh
|
||||
```
|
||||
|
242
bme680.c
@ -1,8 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bme680.h"
|
||||
#include "registers.h"
|
||||
|
||||
|
||||
static void calc_temp_comp(bme680_t *bme680);
|
||||
static void calc_press_comp(bme680_t *bme680);
|
||||
@ -152,9 +150,9 @@ int bme680_reset(bme680_t *bme680) {
|
||||
/********************************************************************/
|
||||
/* configure device */
|
||||
int bme680_configure(bme680_t *bme680) {
|
||||
uint8_t meas, hum, filter, ctrl_gas1, ctrl_gas0, err;
|
||||
int i;
|
||||
meas = hum = filter = err = 0;
|
||||
uint8_t meas, hum, filter, ctrl_gas1, ctrl_gas0, i;
|
||||
int err = 0;
|
||||
meas = hum = filter = 0;
|
||||
|
||||
/* ctrl_meas. the last 0 is ticked on to enable forced mode,
|
||||
* but the config has to be written first. strange behaviour.
|
||||
@ -281,6 +279,16 @@ int bme680_read(bme680_t *bme680) {
|
||||
/* These arrays are used to compute a sensor heating value `res_heat' */
|
||||
/* for a specified heating target, specified in degree C. */
|
||||
/***********************************************************************/
|
||||
/*
|
||||
* Below functions are out of the datasheet
|
||||
*/
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Woverflow"
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#pragma GCC diagnostic ignored "-Wfloat-conversion"
|
||||
|
||||
static double const_array1[16] = {
|
||||
1, 1, 1, 1, 1, 0.99, 1, 0.992, 1,
|
||||
1, 0.998, 0.995, 1, 0.99, 1, 1
|
||||
@ -299,7 +307,6 @@ static int const_array1_int[16] = {
|
||||
2147483647
|
||||
};
|
||||
|
||||
/* long int maybe */
|
||||
static int const_array2_int[16] = {
|
||||
4096000000, 2048000000, 1024000000, 512000000, 255744255,
|
||||
127110228, 64000000, 32258064, 16016016, 8000000, 4000000,
|
||||
@ -375,7 +382,7 @@ static void calc_press_comp_2 (bme680_t *bme680 ) {
|
||||
((int32_t)bme680->cal.par_p3 << 5)) >> 3) + (((int32_t)bme680->cal.par_p2 * var1) >> 1);
|
||||
var1 = var1 >> 18;
|
||||
var1 = ((32768 + var1) * (int32_t)bme680->cal.par_p1) >> 15;
|
||||
press_comp = 1048576 - bme680->adc.press; // bosch code pg 19 says "press_raw" here ???
|
||||
press_comp = 1048576 - bme680->adc.press; /* bosch code pg 19 says "press_raw" here ??? */
|
||||
press_comp = (uint32_t)((press_comp - (var2 >> 12)) * ((uint32_t)3125));
|
||||
if (press_comp >= (1 << 30))
|
||||
press_comp = ((press_comp / (uint32_t)var1) << 1);
|
||||
@ -444,100 +451,6 @@ static void calc_hum_comp (bme680_t *bme680) {
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
// TODO: read one big contiguous block
|
||||
int bme680_calibrate(bme680_t *bme680) {
|
||||
uint8_t buffer[3] = {0, 0 ,0};
|
||||
int err = 0;
|
||||
|
||||
/* temperature */
|
||||
err |= read_dev(bme680, 0xE9, buffer, 2);
|
||||
bme680->cal.par_t1 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x8A, buffer, 2);
|
||||
bme680->cal.par_t2 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x8C, buffer, 1);
|
||||
bme680->cal.par_t3 = buffer[0];
|
||||
|
||||
|
||||
/* pressure */
|
||||
err |= read_dev(bme680, 0x8E, buffer, 2);
|
||||
bme680->cal.par_p1 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x90, buffer, 2);
|
||||
bme680->cal.par_p2 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x92, buffer, 1);
|
||||
bme680->cal.par_p3 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x94, buffer, 2);
|
||||
bme680->cal.par_p4 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x96, buffer, 2);
|
||||
bme680->cal.par_p5 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x99, buffer, 1);
|
||||
bme680->cal.par_p6 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x98, buffer, 1);
|
||||
bme680->cal.par_p7 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x9C, buffer, 1);
|
||||
bme680->cal.par_p8 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x9E, buffer, 2);
|
||||
bme680->cal.par_p9 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xA0, buffer, 1);
|
||||
bme680->cal.par_p10 = buffer[0];
|
||||
|
||||
|
||||
/* humidity */
|
||||
err |= read_dev(bme680, 0xE2, buffer, 2);
|
||||
bme680->cal.par_h1 = (buffer[1] << 4) | (buffer[0] & 0xF);
|
||||
|
||||
err |= read_dev(bme680, 0xE1, buffer, 2);
|
||||
bme680->cal.par_h2 = (buffer[0] << 4) | ((buffer[1] >> 4) & 0xF);
|
||||
|
||||
err |= read_dev(bme680, 0xE4, buffer, 1);
|
||||
bme680->cal.par_h3 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE5, buffer, 1);
|
||||
bme680->cal.par_h4 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE6, buffer, 1);
|
||||
bme680->cal.par_h5 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE7, buffer, 1);
|
||||
bme680->cal.par_h6 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE8, buffer, 1);
|
||||
bme680->cal.par_h7 = buffer[0];
|
||||
|
||||
|
||||
/* gas */
|
||||
err |= read_dev(bme680, 0xED, buffer, 1);
|
||||
bme680->cal.par_g1 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xEB, buffer, 2);
|
||||
bme680->cal.par_g2 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xEE, buffer, 1);
|
||||
bme680->cal.par_g3 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x04, buffer, 1);
|
||||
bme680->cal.range_switching_error = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x02, buffer, 1);
|
||||
bme680->cal.res_heat_range = (buffer[0] >> 4) & 3;
|
||||
|
||||
err |= read_dev(bme680, 0x00, buffer, 1);
|
||||
bme680->cal.res_heat_val = buffer[0];
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
static void calc_gas_res_1(bme680_t *bme680) {
|
||||
double var1, gas_res;
|
||||
@ -568,36 +481,6 @@ static void calc_gas_res(bme680_t *bme680) {
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
void bme680_print_calibration (bme680_t *bme680) {
|
||||
printf("par_t1: %d\n", bme680->cal.par_t1);
|
||||
printf("par_t2: %d\n", bme680->cal.par_t2);
|
||||
printf("par_t3: %d\n", bme680->cal.par_t3);
|
||||
printf("par_p1: %d\n", bme680->cal.par_p1);
|
||||
printf("par_p2: %d\n", bme680->cal.par_p2);
|
||||
printf("par_p3: %d\n", bme680->cal.par_p3);
|
||||
printf("par_p4: %d\n", bme680->cal.par_p4);
|
||||
printf("par_p5: %d\n", bme680->cal.par_p5);
|
||||
printf("par_p6: %d\n", bme680->cal.par_p6);
|
||||
printf("par_p7: %d\n", bme680->cal.par_p7);
|
||||
printf("par_p8: %d\n", bme680->cal.par_p8);
|
||||
printf("par_p9: %d\n", bme680->cal.par_p9);
|
||||
printf("par_p10: %d\n", bme680->cal.par_p10);
|
||||
printf("par_h1: %d\n", bme680->cal.par_h1);
|
||||
printf("par_h2: %d\n", bme680->cal.par_h2);
|
||||
printf("par_h3: %d\n", bme680->cal.par_h3);
|
||||
printf("par_h4: %d\n", bme680->cal.par_h4);
|
||||
printf("par_h5: %d\n", bme680->cal.par_h5);
|
||||
printf("par_h6: %d\n", bme680->cal.par_h6);
|
||||
printf("par_h7: %d\n", bme680->cal.par_h7);
|
||||
printf("par_g1: %d\n", bme680->cal.par_g1);
|
||||
printf("par_g2: %d\n", bme680->cal.par_g2);
|
||||
printf("par_g3: %d\n", bme680->cal.par_g3);
|
||||
printf("range_switching_error: %d\n", bme680->cal.range_switching_error);
|
||||
printf("res_heat_range: %d\n", bme680->cal.res_heat_range);
|
||||
printf("res_heat_val: %d\n", bme680->cal.res_heat_val);
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
static uint8_t calc_target_1(bme680_t *bme680, double target, double ambient) {
|
||||
double var1, var2, var3, var4, var5;
|
||||
@ -606,7 +489,7 @@ static uint8_t calc_target_1(bme680_t *bme680, double target, double ambient) {
|
||||
var1 = ((double)bme680->cal.par_g1 / 16.0) + 49.0;
|
||||
var2 = (((double)bme680->cal.par_g2 / 32768.0) * 0.0005) + 0.00235;
|
||||
var3 = (double)bme680->cal.par_g3 / 1024.0;
|
||||
var4 = var1 * (1.0 + (var2 * (double)target)); /* */
|
||||
var4 = var1 * (1.0 + (var2 * (double)target));
|
||||
var5 = var4 + (var3 * (double)ambient);
|
||||
res_heat = (uint8_t)(3.4 * ((var5 * (4.0 / (4.0 + (double)bme680->cal.res_heat_range)) *
|
||||
(1.0 / (1.0 + ((double)bme680->cal.res_heat_val * 0.002)))) - 25));
|
||||
@ -638,3 +521,98 @@ uint8_t bme680_calc_target(bme680_t *bme680, double target, double ambient) {
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
/********************************************************************/
|
||||
/* TODO: read one big contiguous block */
|
||||
int bme680_calibrate(bme680_t *bme680) {
|
||||
uint8_t buffer[3] = {0, 0 ,0};
|
||||
int err = 0;
|
||||
|
||||
/* temperature */
|
||||
err |= read_dev(bme680, 0xE9, buffer, 2);
|
||||
bme680->cal.par_t1 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x8A, buffer, 2);
|
||||
bme680->cal.par_t2 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x8C, buffer, 1);
|
||||
bme680->cal.par_t3 = (int8_t)buffer[0];
|
||||
|
||||
|
||||
/* pressure */
|
||||
err |= read_dev(bme680, 0x8E, buffer, 2);
|
||||
bme680->cal.par_p1 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x90, buffer, 2);
|
||||
bme680->cal.par_p2 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x92, buffer, 1);
|
||||
bme680->cal.par_p3 = (int8_t)buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x94, buffer, 2);
|
||||
bme680->cal.par_p4 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x96, buffer, 2);
|
||||
bme680->cal.par_p5 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x99, buffer, 1);
|
||||
bme680->cal.par_p6 = (int8_t)buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x98, buffer, 1);
|
||||
bme680->cal.par_p7 = (int8_t)buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x9C, buffer, 1);
|
||||
bme680->cal.par_p8 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x9E, buffer, 2);
|
||||
bme680->cal.par_p9 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xA0, buffer, 1);
|
||||
bme680->cal.par_p10 = buffer[0];
|
||||
|
||||
|
||||
/* humidity */
|
||||
err |= read_dev(bme680, 0xE2, buffer, 2);
|
||||
bme680->cal.par_h1 = (buffer[1] << 4) | (buffer[0] & 0xF);
|
||||
|
||||
err |= read_dev(bme680, 0xE1, buffer, 2);
|
||||
bme680->cal.par_h2 = (buffer[0] << 4) | ((buffer[1] >> 4) & 0xF);
|
||||
|
||||
err |= read_dev(bme680, 0xE4, buffer, 1);
|
||||
bme680->cal.par_h3 = (int8_t)buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE5, buffer, 1);
|
||||
bme680->cal.par_h4 = (int8_t)buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE6, buffer, 1);
|
||||
bme680->cal.par_h5 = (int8_t)buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE7, buffer, 1);
|
||||
bme680->cal.par_h6 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xE8, buffer, 1);
|
||||
bme680->cal.par_h7 = (int8_t)buffer[0];
|
||||
|
||||
|
||||
/* gas */
|
||||
err |= read_dev(bme680, 0xED, buffer, 1);
|
||||
bme680->cal.par_g1 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xEB, buffer, 2);
|
||||
bme680->cal.par_g2 = (buffer[1] << 8) | buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0xEE, buffer, 1);
|
||||
bme680->cal.par_g3 = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x04, buffer, 1);
|
||||
bme680->cal.range_switching_error = buffer[0];
|
||||
|
||||
err |= read_dev(bme680, 0x02, buffer, 1);
|
||||
bme680->cal.res_heat_range = (buffer[0] >> 4) & 3;
|
||||
|
||||
err |= read_dev(bme680, 0x00, buffer, 1);
|
||||
bme680->cal.res_heat_val = (int8_t)buffer[0];
|
||||
|
||||
return err;
|
||||
}
|
72
bme680.h
@ -3,6 +3,75 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* REGISTERS */
|
||||
|
||||
/* confuses me too ! */
|
||||
/* SPI page number 0 => 0x00 to 0x7F */
|
||||
/* SPI page number 1 => 0x80 to 0xFF */
|
||||
#define REG_SPI_PAGE(v) ((v > 0x7F) ? 0 : 1)
|
||||
#define REG_SPI_PAGE_MAP(v) (v == 0 ? "LOW" : "HIGH")
|
||||
|
||||
#define REG_STATUS 0x73
|
||||
#define REG_RESET 0xE0
|
||||
#define REG_ID 0xD0
|
||||
#define REG_CONFIG 0x75
|
||||
#define REG_CTRL_MEAS 0x74
|
||||
#define REG_CTRL_HUM 0x72
|
||||
|
||||
#define REG_CTRL_GAS_1 0x71
|
||||
#define REG_CTRL_GAS_0 0x70
|
||||
|
||||
#define REG_GAS_WAIT_9 0x6D
|
||||
#define REG_GAS_WAIT_8 0x6C
|
||||
#define REG_GAS_WAIT_7 0x6B
|
||||
#define REG_GAS_WAIT_6 0x6A
|
||||
#define REG_GAS_WAIT_5 0x69
|
||||
#define REG_GAS_WAIT_4 0x68
|
||||
#define REG_GAS_WAIT_3 0x67
|
||||
#define REG_GAS_WAIT_2 0x66
|
||||
#define REG_GAS_WAIT_1 0x65
|
||||
#define REG_GAS_WAIT_0 0x64
|
||||
|
||||
#define REG_RES_HEAT_9 0x63
|
||||
#define REG_RES_HEAT_8 0x62
|
||||
#define REG_RES_HEAT_7 0x61
|
||||
#define REG_RES_HEAT_6 0x60
|
||||
#define REG_RES_HEAT_5 0x5F
|
||||
#define REG_RES_HEAT_4 0x5E
|
||||
#define REG_RES_HEAT_3 0x5D
|
||||
#define REG_RES_HEAT_2 0x5C
|
||||
#define REG_RES_HEAT_1 0x5B
|
||||
#define REG_RES_HEAT_0 0x5A
|
||||
|
||||
#define REG_IDAC_HEAT_9 0x59
|
||||
#define REG_IDAC_HEAT_8 0x58
|
||||
#define REG_IDAC_HEAT_7 0x57
|
||||
#define REG_IDAC_HEAT_6 0x56
|
||||
#define REG_IDAC_HEAT_5 0x55
|
||||
#define REG_IDAC_HEAT_4 0x54
|
||||
#define REG_IDAC_HEAT_3 0x53
|
||||
#define REG_IDAC_HEAT_2 0x52
|
||||
#define REG_IDAC_HEAT_1 0x51
|
||||
#define REG_IDAC_HEAT_0 0x50
|
||||
|
||||
#define REG_GAS_R_LSB 0x2B
|
||||
#define REG_GAS_R_MSB 0x2A
|
||||
|
||||
#define REG_HUM_LSB 0x26
|
||||
#define REG_HUM_MSB 0x25
|
||||
|
||||
#define REG_TEMP_XLSB 0x24
|
||||
#define REG_TEMP_LSB 0x23
|
||||
#define REG_TEMP_MSB 0x22
|
||||
|
||||
#define REG_PRESS_XLSB 0x21
|
||||
#define REG_PRESS_LSB 0x20
|
||||
#define REG_PRESS_MSB 0x1F
|
||||
|
||||
#define REG_MEAS_STATUS 0x1D
|
||||
|
||||
/* END OF REGISTERS */
|
||||
|
||||
#define BME680_IS_SPI(m) ((m & 1) == 1)
|
||||
#define BME680_IS_FLOAT(m) (((m >> 1) & 1) == 0)
|
||||
#define BME680_GAS_ENABLED(m) (((m >> 2) & 1) == 1)
|
||||
@ -142,7 +211,6 @@ struct bme680 {
|
||||
|
||||
typedef struct bme680 bme680_t;
|
||||
|
||||
|
||||
int bme680_init(bme680_t *bme680, uint8_t mode);
|
||||
int bme680_deinit(bme680_t *bme680);
|
||||
int bme680_reset(bme680_t *bme680);
|
||||
@ -156,6 +224,4 @@ int bme680_read_setpoint_index(bme680_t *bme680, uint8_t *index);
|
||||
|
||||
uint8_t bme680_calc_target(bme680_t *bme680, double target, double ambient);
|
||||
|
||||
void bme680_print_calibration(bme680_t *bme680);
|
||||
|
||||
#endif
|
||||
|
31
bme680_util.c
Normal file
@ -0,0 +1,31 @@
|
||||
#include <stdio.h>
|
||||
#include "bme680_util.h"
|
||||
|
||||
void bme680_print_calibration (bme680_t *bme680) {
|
||||
printf("par_t1: %d\n", bme680->cal.par_t1);
|
||||
printf("par_t2: %d\n", bme680->cal.par_t2);
|
||||
printf("par_t3: %d\n", bme680->cal.par_t3);
|
||||
printf("par_p1: %d\n", bme680->cal.par_p1);
|
||||
printf("par_p2: %d\n", bme680->cal.par_p2);
|
||||
printf("par_p3: %d\n", bme680->cal.par_p3);
|
||||
printf("par_p4: %d\n", bme680->cal.par_p4);
|
||||
printf("par_p5: %d\n", bme680->cal.par_p5);
|
||||
printf("par_p6: %d\n", bme680->cal.par_p6);
|
||||
printf("par_p7: %d\n", bme680->cal.par_p7);
|
||||
printf("par_p8: %d\n", bme680->cal.par_p8);
|
||||
printf("par_p9: %d\n", bme680->cal.par_p9);
|
||||
printf("par_p10: %d\n", bme680->cal.par_p10);
|
||||
printf("par_h1: %d\n", bme680->cal.par_h1);
|
||||
printf("par_h2: %d\n", bme680->cal.par_h2);
|
||||
printf("par_h3: %d\n", bme680->cal.par_h3);
|
||||
printf("par_h4: %d\n", bme680->cal.par_h4);
|
||||
printf("par_h5: %d\n", bme680->cal.par_h5);
|
||||
printf("par_h6: %d\n", bme680->cal.par_h6);
|
||||
printf("par_h7: %d\n", bme680->cal.par_h7);
|
||||
printf("par_g1: %d\n", bme680->cal.par_g1);
|
||||
printf("par_g2: %d\n", bme680->cal.par_g2);
|
||||
printf("par_g3: %d\n", bme680->cal.par_g3);
|
||||
printf("range_switching_error: %d\n", bme680->cal.range_switching_error);
|
||||
printf("res_heat_range: %d\n", bme680->cal.res_heat_range);
|
||||
printf("res_heat_val: %d\n", bme680->cal.res_heat_val);
|
||||
}
|
8
bme680_util.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef BME680_UTIL_H
|
||||
#define BME680_UTIL_H
|
||||
|
||||
#include "bme680.h"
|
||||
|
||||
void bme680_print_calibration (bme680_t *bme680);
|
||||
|
||||
#endif
|
@ -7,11 +7,11 @@
|
||||
|
||||
#include "bme680.h"
|
||||
#include "i2c.h"
|
||||
#include "spi.h"
|
||||
|
||||
#define AMBIENT_TEMP_GUESS 19.0
|
||||
#define HEATER_TARGET 300.0
|
||||
|
||||
|
||||
int main(void) {
|
||||
|
||||
bme680_t bme680;
|
||||
@ -20,14 +20,29 @@ int main(void) {
|
||||
time_t curr_time;
|
||||
char date[100];
|
||||
|
||||
#if defined(USE_SPI) && defined(USE_I2C)
|
||||
#error "Both USE_SPI and USE_I2C are defined. Please define only one."
|
||||
#elif !defined(USE_SPI) && !defined(USE_I2C)
|
||||
#error "Neither USE_SPI nor USE_I2C is defined. Please define one."
|
||||
#elif defined(USE_SPI)
|
||||
bme680.dev.init = spi_init;
|
||||
bme680.dev.read = spi_read;
|
||||
bme680.dev.write = spi_write;
|
||||
bme680.dev.deinit = spi_deinit;
|
||||
#elif defined(USE_I2C)
|
||||
bme680.dev.init = i2c_init;
|
||||
bme680.dev.read = i2c_read;
|
||||
bme680.dev.write = i2c_write;
|
||||
bme680.dev.deinit = i2c_deinit;
|
||||
bme680.dev.sleep = usleep;
|
||||
|
||||
mode = BME680_MODE_FLOAT | BME680_I2C | BME680_ENABLE_GAS;
|
||||
#endif
|
||||
bme680.dev.sleep = usleep;
|
||||
|
||||
mode = BME680_MODE_FLOAT | BME680_ENABLE_GAS;
|
||||
#if defined(USE_SPI)
|
||||
mode |= BME680_SPI;
|
||||
#elif defined(USE_I2C)
|
||||
mode |= BME680_I2C;
|
||||
#endif
|
||||
|
||||
if (bme680_init(&bme680, mode) != 0) {
|
||||
fprintf(stderr, "bme680_init()\n");
|
||||
@ -35,7 +50,11 @@ int main(void) {
|
||||
}
|
||||
|
||||
START:
|
||||
bme680_reset(&bme680);
|
||||
if (bme680_reset(&bme680) != 0) {
|
||||
fprintf(stderr, "bme680_reset()\n");
|
||||
bme680_deinit(&bme680);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (bme680_calibrate(&bme680) != 0) {
|
||||
fprintf(stderr, "bme680_calibrate()\n");
|
||||
@ -90,7 +109,7 @@ START:
|
||||
|
||||
temperature = bme680.fcomp.temp;
|
||||
|
||||
// 60 secs
|
||||
/* 60 secs */
|
||||
usleep(1000*1000*60);
|
||||
goto START;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bme680.h"
|
||||
#include "bme680_util.h"
|
||||
#include "i2c.h"
|
||||
#include "spi.h"
|
||||
|
||||
@ -20,21 +21,33 @@ int main(void) {
|
||||
|
||||
/* 1. Assign functions for interacting with the device */
|
||||
|
||||
// bme680.dev.init = i2c_init;
|
||||
// bme680.dev.read = i2c_read;
|
||||
// bme680.dev.write = i2c_write;
|
||||
// bme680.dev.deinit = i2c_deinit;
|
||||
|
||||
bme680.dev.init = spi_init;
|
||||
#if defined(USE_SPI) && defined(USE_I2C)
|
||||
#error "Both USE_SPI and USE_I2C are defined. Please define only one."
|
||||
#elif !defined(USE_SPI) && !defined(USE_I2C)
|
||||
#error "Neither USE_SPI nor USE_I2C is defined. Please define one."
|
||||
#elif defined(USE_SPI)
|
||||
bme680.dev.init = spi_init;
|
||||
bme680.dev.read = spi_read;
|
||||
bme680.dev.write = spi_write;
|
||||
bme680.dev.deinit = spi_deinit;
|
||||
#elif defined(USE_I2C)
|
||||
bme680.dev.init = i2c_init;
|
||||
bme680.dev.read = i2c_read;
|
||||
bme680.dev.write = i2c_write;
|
||||
bme680.dev.deinit = i2c_deinit;
|
||||
#endif
|
||||
|
||||
|
||||
bme680.dev.sleep = usleep;
|
||||
|
||||
/* 2. set the device mode */
|
||||
mode = BME680_MODE_FLOAT | BME680_SPI | BME680_ENABLE_GAS;
|
||||
/* BME680_MODE_INT | BME680_I2C; */
|
||||
mode = BME680_MODE_FLOAT | BME680_ENABLE_GAS;
|
||||
#if defined(USE_SPI)
|
||||
mode |= BME680_SPI;
|
||||
#elif defined(USE_I2C)
|
||||
mode |= BME680_I2C;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* 3. initialise dev func's, and check device id */
|
31
i2c.c
@ -1,8 +1,4 @@
|
||||
/*
|
||||
|
||||
Example I2C use on linux/raspberry pi
|
||||
|
||||
*/
|
||||
/* Raspberry Pi i2c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
@ -24,42 +20,47 @@ int i2c_init(void) {
|
||||
fd = open(I2C_DEVICE, O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "could not open device: %s\n", I2C_DEVICE);
|
||||
return I2C_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, I2C_SLAVE, I2C_BME680_ADDRESS) < 0) {
|
||||
fprintf(stderr, "failed to acquire bus/talk to slave\n");
|
||||
close(fd);
|
||||
return I2C_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return I2C_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i2c_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
||||
uint8_t cmd[2] = {reg, 0x00};
|
||||
uint8_t cmd[2];
|
||||
cmd[0] = reg;
|
||||
cmd[1] = 0x00;
|
||||
|
||||
write(fd, cmd, 2);
|
||||
|
||||
if (read(fd, dst, size) != (ssize_t)size) {
|
||||
fprintf(stderr, "error read()\n");
|
||||
return I2C_ERR;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
return I2C_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int i2c_write(uint8_t reg, uint8_t value) {
|
||||
uint8_t cmd[2] = {reg, value};
|
||||
uint8_t cmd[2];
|
||||
cmd[0] = reg;
|
||||
cmd[1] = value;
|
||||
|
||||
if (write(fd, cmd, 2) != 2) {
|
||||
fprintf(stderr, "error write()\n");
|
||||
return I2C_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return I2C_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_deinit(void) {
|
||||
@ -67,6 +68,6 @@ int i2c_deinit(void) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return I2C_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
3
i2c.h
@ -3,9 +3,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define I2C_OK 0
|
||||
#define I2C_ERR 1
|
||||
|
||||
int i2c_init (void);
|
||||
int i2c_read (uint8_t reg, uint8_t *dst, uint32_t size);
|
||||
int i2c_write (uint8_t reg, uint8_t value);
|
||||
|
38
plot/gnuplot.gpt
Normal file
@ -0,0 +1,38 @@
|
||||
# gnuplot
|
||||
reset
|
||||
|
||||
set key autotitle columnhead top left spacing 2
|
||||
set terminal pngcairo enhanced size 2*1920/3,2*1080/3
|
||||
set grid linewidth 2
|
||||
set xdata time
|
||||
set timefmt "%Y-%m-%dT%H:%M:%S%z"
|
||||
set xtics format "%d/%m\n%H:%M"
|
||||
|
||||
# gas res vs time
|
||||
set title "[I_{dac}=100, 100ms, target=300 C] GasRes over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Gas Resistance (OHM)"
|
||||
set output "gas.png"
|
||||
plot 'i2c.txt' u 1:5 w p pt 3 ps 1 t "bme680-i2c", \
|
||||
'spi.txt' u 1:5 w p pt 3 ps 1 t "bme680-spi"
|
||||
|
||||
set title "Temperature over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Temperature (C)"
|
||||
set output "temp.png"
|
||||
plot '../data/i2c.txt' u 1:2 w p pt 3 ps 1 t "bme680-i2c", \
|
||||
'../data/spi.txt' u 1:2 w p pt 3 ps 1 t "bme680-spi"
|
||||
|
||||
set title "Pressure over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Pressure (Pa)"
|
||||
set output "press.png"
|
||||
plot '../data/i2c.txt' u 1:3 w p pt 3 ps 1 t "bme680-i2c", \
|
||||
'../data/spi.txt' u 1:3 w p pt 3 ps 1 t "bme680-spi"
|
||||
|
||||
set title "Humidity over time"
|
||||
set xlabel "Time"
|
||||
set ylabel "Humidity (%RH)"
|
||||
set output "hum.png"
|
||||
plot '../data/i2c.txt' u 1:4 w p pt 3 ps 1 t "bme680-i2c", \
|
||||
'../data/spi.txt' u 1:4 w p pt 3 ps 1 t "bme680-spi"
|
5
plot/plot.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
sed -n '/1$/p' ../data/spi.txt > spi.txt
|
||||
sed -n '/1$/p' ../data/i2c.txt > i2c.txt
|
||||
gnuplot gnuplot.gpt
|
70
registers.h
@ -1,70 +0,0 @@
|
||||
#ifndef REGISTERS_H
|
||||
#define REGISTERS_H
|
||||
|
||||
/* SPI page number 0 => 0x00 to 0x7F */
|
||||
/* SPI page number 1 => 0x80 to 0xFF */
|
||||
#define REG_SPI_PAGE(v) ((v > 0x7F) ? 0 : 1)
|
||||
#define REG_SPI_PAGE_MAP(v) (v == 0 ? "LOW" : "HIGH")
|
||||
|
||||
#define REG_STATUS 0x73
|
||||
#define REG_RESET 0xE0
|
||||
#define REG_ID 0xD0
|
||||
#define REG_CONFIG 0x75
|
||||
#define REG_CTRL_MEAS 0x74
|
||||
#define REG_CTRL_HUM 0x72
|
||||
|
||||
#define REG_CTRL_GAS_1 0x71
|
||||
#define REG_CTRL_GAS_0 0x70
|
||||
|
||||
#define REG_GAS_WAIT_9 0x6D
|
||||
#define REG_GAS_WAIT_8 0x6C
|
||||
#define REG_GAS_WAIT_7 0x6B
|
||||
#define REG_GAS_WAIT_6 0x6A
|
||||
#define REG_GAS_WAIT_5 0x69
|
||||
#define REG_GAS_WAIT_4 0x68
|
||||
#define REG_GAS_WAIT_3 0x67
|
||||
#define REG_GAS_WAIT_2 0x66
|
||||
#define REG_GAS_WAIT_1 0x65
|
||||
#define REG_GAS_WAIT_0 0x64
|
||||
|
||||
#define REG_RES_HEAT_9 0x63
|
||||
#define REG_RES_HEAT_8 0x62
|
||||
#define REG_RES_HEAT_7 0x61
|
||||
#define REG_RES_HEAT_6 0x60
|
||||
#define REG_RES_HEAT_5 0x5F
|
||||
#define REG_RES_HEAT_4 0x5E
|
||||
#define REG_RES_HEAT_3 0x5D
|
||||
#define REG_RES_HEAT_2 0x5C
|
||||
#define REG_RES_HEAT_1 0x5B
|
||||
#define REG_RES_HEAT_0 0x5A
|
||||
|
||||
#define REG_IDAC_HEAT_9 0x59
|
||||
#define REG_IDAC_HEAT_8 0x58
|
||||
#define REG_IDAC_HEAT_7 0x57
|
||||
#define REG_IDAC_HEAT_6 0x56
|
||||
#define REG_IDAC_HEAT_5 0x55
|
||||
#define REG_IDAC_HEAT_4 0x54
|
||||
#define REG_IDAC_HEAT_3 0x53
|
||||
#define REG_IDAC_HEAT_2 0x52
|
||||
#define REG_IDAC_HEAT_1 0x51
|
||||
#define REG_IDAC_HEAT_0 0x50
|
||||
|
||||
#define REG_GAS_R_LSB 0x2B
|
||||
#define REG_GAS_R_MSB 0x2A
|
||||
|
||||
#define REG_HUM_LSB 0x26
|
||||
#define REG_HUM_MSB 0x25
|
||||
|
||||
#define REG_TEMP_XLSB 0x24
|
||||
#define REG_TEMP_LSB 0x23
|
||||
#define REG_TEMP_MSB 0x22
|
||||
|
||||
#define REG_PRESS_XLSB 0x21
|
||||
#define REG_PRESS_LSB 0x20
|
||||
#define REG_PRESS_MSB 0x1F
|
||||
|
||||
#define REG_MEAS_STATUS 0x1D
|
||||
|
||||
|
||||
|
||||
#endif
|
53
spi.c
@ -1,8 +1,4 @@
|
||||
/*
|
||||
|
||||
Example SPI use on linux/raspberry pi
|
||||
|
||||
*/
|
||||
/* Raspberry Pi SPI */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@ -35,52 +31,48 @@ Example SPI use on linux/raspberry pi
|
||||
|
||||
static int fd;
|
||||
|
||||
//static void print_access(const char *name, uint8_t reg, uint8_t *dst, uint32_t size);
|
||||
|
||||
int spi_init(void) {
|
||||
|
||||
uint8_t mode = SPI_MODE;
|
||||
uint8_t bits = SPI_BITS;
|
||||
uint32_t speed = SPI_SPEED;
|
||||
|
||||
if ((fd = open(SPI_DEVICE, O_RDWR)) < 0) {
|
||||
fprintf(stderr, "spi open(%s)\n", SPI_DEVICE);
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, SPI_IOC_RD_MODE, &mode) == -1) {
|
||||
fprintf(stderr, "SPI_IOC_RD_MODE\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) {
|
||||
fprintf(stderr, "SPI_IOC_WR_MODE\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) {
|
||||
fprintf(stderr, "SPI_IOC_WR_BITS_PER_WORD\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits) == -1) {
|
||||
fprintf(stderr, "SPI_IOC_RD_BITS_PER_WORD\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) {
|
||||
fprintf(stderr, "SPI_IOC_WR_MAX_SPEED_HZ\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1) {
|
||||
fprintf(stderr, "SPI_IOC_RD_MAX_SPEED_HZ\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// puts("spi_init");
|
||||
return SPI_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* bme680 auto-increments for spi reads */
|
||||
@ -101,11 +93,10 @@ int spi_read(uint8_t reg, uint8_t *dst, uint32_t size) {
|
||||
|
||||
if (ioctl(fd, SPI_IOC_MESSAGE(2), tr) < 0) {
|
||||
fprintf(stderr, "spi_read()\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// print_access("spi_read", reg, dst, size);
|
||||
return SPI_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* bme680 does NOT auto-increment for spi writes, so one at a time */
|
||||
@ -126,32 +117,16 @@ int spi_write(uint8_t reg, uint8_t value) {
|
||||
|
||||
if (ioctl(fd, SPI_IOC_MESSAGE(2), tr) < 0) {
|
||||
fprintf(stderr, "spi_write()\n");
|
||||
return SPI_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// print_access("spi_write", reg, &value, 1);
|
||||
return SPI_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_deinit(void) {
|
||||
// puts("spi_deinit");
|
||||
if (fd) {
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return SPI_OK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_access(const char *name, uint8_t reg, uint8_t *dst, uint32_t size) {
|
||||
printf("%s: %.2X (%d) [", name, reg, size);
|
||||
for(uint32_t i=0; i<size; i++) {
|
||||
printf("%.2X", dst[i]);
|
||||
if (i < (size - 1)) {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
*/
|
||||
|
||||
|