#include #include #include #include #include #include #include #include #include #define check(e) ({\ int ec = (e); \ if(ec < 0) {\ perror(#e); \ exit(1);\ }\ ec;\ }) enum BME280Register { ID = 0xd0, CTRL_MEAS = 0xf4, PRESS_MSB = 0xf5, }; typedef struct { int fd; } BME280; int i2c_read_register(int fd, uint8_t reg) { if(write(fd, ®, 1) < 0) return -1; uint8_t byte; if(read(fd, &byte, 1) < 0) return -1; return byte; } int i2c_read_registers(int fd, uint8_t start_addr, uint8_t* values, size_t n_bytes) { if(write(fd, &start_addr, 1) < 0) return -1; return read(fd, values, n_bytes); } int bme280_init(BME280* self, int fd) { self->fd = fd; if(i2c_read_register(fd, 0xd0) != 0x60) return -ENOTSUP; return 0; } int main() { int bus = check(open("/dev/i2c-1", O_RDWR)); check(ioctl(bus, I2C_SLAVE, 0x76)); #if 0 // Check I2C driver compatibility unsigned long adapter_funcs; check(ioctl(bus, I2C_FUNCS, &adapter_funcs)); for(size_t i = 0; i != (sizeof(funcs)/sizeof(*funcs)); ++i) { if(adapter_funcs & funcs[i].bit) puts(funcs[i].name); } #endif BME280 sensor; check(bme280_init(&sensor, bus)); for(size_t j = 0; j != 10; ++j) { uint8_t ctrl_meas = (0b001u << 5) | (0b001 << 2) | 0b11; uint8_t bus_data[] = {CTRL_MEAS, ctrl_meas}; check(write(bus, bus_data, 2)); //TODO: should we sleep here? Maybe poll the busy flag? uint8_t sensor_data[8]; check(i2c_read_registers(bus, PRESS_MSB, sensor_data, 8)); for(size_t i = 0; i != sizeof(sensor_data); ++i) { printf("%02x ", sensor_data[i]); } puts(""); sleep(1); } close(bus); }