Skip to content

Instantly share code, notes, and snippets.

@ymakino
Last active December 1, 2023 05:56
Show Gist options
  • Save ymakino/17e24416c2f5a87f4908 to your computer and use it in GitHub Desktop.
Save ymakino/17e24416c2f5a87f4908 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <linux/i2c-dev.h>
#define I2C_FILE "/dev/i2c-1"
#define BMP180_I2C_ADDR 0x77
#define OSS 3
#define TO_S16(buf, index) ((int16_t)(((0xff00 & ((int16_t)((buf)[(index)])<<8)) | (0x00ff & ((int16_t)(buf)[(index) + 1])))))
#define TO_U16(buf, index) ((uint16_t)(((0xff00 & ((uint16_t)((buf)[(index)])<<8)) | (0x00ff & ((uint16_t)(buf)[(index) + 1])))))
#define TO_S24(buf, index) ((int32_t)((0xffff0000 & ((int32_t)((buf)[(index)])) << 16) \
| (0x00ff00 & ((int32_t)((buf)[(index)+1]) << 8)) \
| (0x0000ff & ((int32_t)((buf)[(index)+2])))))
int main() {
int i;
int ret;
int fd;
char buf[22];
int16_t AC1, AC2, AC3, B1, B2, MB, MC, MD;
uint16_t AC4, AC5, AC6;
int32_t UT, UP;
int32_t X1, X2, X3;
int32_t B3, B5, B6;
uint32_t B4, B7;
int32_t T, p;
int8_t oss;
fd = open(I2C_FILE, O_RDWR);
if (fd < 0) {
perror("open");
return -1;
}
ret = ioctl(fd, I2C_SLAVE, BMP180_I2C_ADDR);
if (ret != 0) {
perror("ioctl");
return -1;
}
ret = i2c_smbus_read_i2c_block_data(fd, 0xAA, 22, buf);
if (ret != 22) {
printf("i2c_smbus_read_i2c_block_data: %d\n", ret);
return -1;
}
AC1 = TO_S16(buf, 0);
AC2 = TO_S16(buf, 2);
AC3 = TO_S16(buf, 4);
AC4 = TO_U16(buf, 6);
AC5 = TO_U16(buf, 8);
AC6 = TO_U16(buf, 10);
B1 = TO_S16(buf, 12);
B2 = TO_S16(buf, 14);
MB = TO_S16(buf, 16);
MC = TO_S16(buf, 18);
MD = TO_S16(buf, 20);
oss = OSS;
ret = i2c_smbus_write_byte_data(fd, 0xF4, 0x2E);
if (ret < 0) {
printf("i2c_smbus_write_byte_data: %d\n", ret);
return -1;
}
usleep(4.5 * 1000);
ret = i2c_smbus_read_i2c_block_data(fd, 0xF6, 2, buf);
if (ret != 2) {
printf("i2c_smbus_read_i2c_block_data: %d\n", ret);
return -1;
}
UT = TO_S16(buf, 0);
printf("UT %d\n", UT);
ret = i2c_smbus_write_byte_data(fd, 0xF4, 0x34 + (oss << 6));
if (ret < 0) {
printf("i2c_smbus_write_byte_data: %d\n", ret);
return -1;
}
usleep(25.5 * 1000);
ret = i2c_smbus_read_i2c_block_data(fd, 0xF6, 3, buf);
if (ret != 3) {
printf("i2c_smbus_read_i2c_block_data: %d\n", ret);
return -1;
}
UP = TO_S24(buf, 0) >> (8-oss);
printf("UP %d\n", UP);
X1 = (UT - AC6) * AC5 / (1<<15);
X2 = MC * (1<<11) / (X1 + MD);
B5 = X1 + X2;
T = (B5 + 8) / (1<<4);
printf("t: %f\n", T/10.0);
B6 = B5 - 4000;
X1 = (B2 * (B6 * B6 / (1<<12))) / (1<<11);
X2 = AC2 * B6 / (1<<11);
X3 = X1 + X2;
B3 = (((AC1 * 4 + X3) << oss) + 2) / 4;
X1 = AC3 * B6 / (1<<13);
X2 = (B1 * (B6 * B6 / (1<<12))) / (1<<16);
X3 = ((X1 + X2) + 2) / (1<<2);
B4 = AC4 * (uint32_t)(X3 + 32768) / (1<<15);
B7 = ((uint32_t)UP - B3) * (50000 >> oss);
if (B7 < 0x80000000) {
p = (B7 * 2) / B4;
} else {
p = (B7 / B4) * 2;
}
X1 = (p / (1<<8)) * (p / (1<<8));
X1 = (X1 * 3038) / (1<<16);
X2 = (-7357 * p) / (1<<16);
p = p + (X1 + X2 + 3791) / (1<<4);
printf("p: %f\n", p/100.0);
close(fd);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment