-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbmp280.c
More file actions
82 lines (68 loc) · 2.85 KB
/
bmp280.c
File metadata and controls
82 lines (68 loc) · 2.85 KB
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
#include "bmp280.h"
#include "pico/stdlib.h"
#define REG_CALIB_START 0x88
#define REG_CTRL_MEAS 0xF4
#define REG_PRESS_MSB 0xF7
static bmp280_calib_param calib;
static uint8_t read8(i2c_inst_t *i2c, uint8_t addr, uint8_t reg)
{
i2c_write_blocking(i2c, addr, ®, 1, true);
uint8_t val;
i2c_read_blocking(i2c, addr, &val, 1, false);
return val;
}
static void read_buf(i2c_inst_t *i2c, uint8_t addr, uint8_t reg, uint8_t *buf, size_t len)
{
i2c_write_blocking(i2c, addr, ®, 1, true);
i2c_read_blocking(i2c, addr, buf, len, false);
}
void bmp280_read_calib_params(i2c_inst_t *i2c, uint8_t addr, bmp280_calib_param *params)
{
uint8_t buf[24];
read_buf(i2c, addr, REG_CALIB_START, buf, 24);
params->dig_T1 = (buf[1] << 8) | buf[0];
params->dig_T2 = (buf[3] << 8) | buf[2];
params->dig_T3 = (buf[5] << 8) | buf[4];
params->dig_P1 = (buf[7] << 8) | buf[6];
params->dig_P2 = (buf[9] << 8) | buf[8];
params->dig_P3 = (buf[11] << 8) | buf[10];
params->dig_P4 = (buf[13] << 8) | buf[12];
params->dig_P5 = (buf[15] << 8) | buf[14];
params->dig_P6 = (buf[17] << 8) | buf[16];
params->dig_P7 = (buf[19] << 8) | buf[18];
params->dig_P8 = (buf[21] << 8) | buf[20];
params->dig_P9 = (buf[23] << 8) | buf[22];
}
void bmp280_init(i2c_inst_t *i2c, uint8_t addr)
{
bmp280_read_calib_params(i2c, addr, &calib);
uint8_t config[2] = {REG_CTRL_MEAS, 0x27}; // Temp + Pressure, normal mode
i2c_write_blocking(i2c, addr, config, 2, false);
}
int32_t bmp280_read_pressure(i2c_inst_t *i2c, uint8_t addr)
{
uint8_t data[6];
read_buf(i2c, addr, REG_PRESS_MSB, data, 6);
int32_t adc_T = (int32_t)(((uint32_t)data[3] << 12) | ((uint32_t)data[4] << 4) | (data[5] >> 4));
int32_t adc_P = (int32_t)(((uint32_t)data[0] << 12) | ((uint32_t)data[1] << 4) | (data[2] >> 4));
// Temp compensation
int32_t var1 = ((((adc_T >> 3) - ((int32_t)calib.dig_T1 << 1))) * ((int32_t)calib.dig_T2)) >> 11;
int32_t var2 = (((((adc_T >> 4) - ((int32_t)calib.dig_T1)) * ((adc_T >> 4) - ((int32_t)calib.dig_T1))) >> 12) *
((int32_t)calib.dig_T3)) >>
14;
calib.t_fine = var1 + var2;
// Pressure compensation
int64_t varp1 = ((int64_t)calib.t_fine) - 128000;
int64_t varp2 = varp1 * varp1 * (int64_t)calib.dig_P6;
varp2 = varp2 + ((varp1 * (int64_t)calib.dig_P5) << 17);
varp2 = varp2 + (((int64_t)calib.dig_P4) << 35);
varp1 = ((varp1 * varp1 * (int64_t)calib.dig_P3) >> 8) + ((varp1 * (int64_t)calib.dig_P2) << 12);
varp1 = (((((int64_t)1) << 47) + varp1)) * ((int64_t)calib.dig_P1) >> 33;
if (varp1 == 0)
return 0;
int64_t p = 1048576 - adc_P;
p = (((p << 31) - varp2) * 3125) / varp1;
varp1 = (((int64_t)calib.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
varp2 = (((int64_t)calib.dig_P8) * p) >> 19;
return ((p + varp1 + varp2) >> 8);
}