Problem reading BMP388 with BMP3-Sensor-API library on Raspberry Pi

I'm trying to use the BMP3-Sensor-API library from Github to read a BMP388 sensor via I2C, but I always get the same answer of raw values 00 00 80 00 00 80. The hardware is okay, measurements do work with the Adafruit Python library. I have implemented the i2c read and write functions similarly as for the BMP280_driver library, which does work. What am I missing? Here is my code that works with BMP280 but not with BMP388:

#ifdef BMP280
#include "bmp280.h"
#else
#include "bmp3.h"
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <stdbool.h>

#define DEVICE "/dev/i2c-1" // bus 1 on gpio 23 = sda, gpio 24 = scl

int fd_i2c; // file descriptor for i2c

bool i2c_interface_init(const char* device, const uint8_t address);
bool i2c_read(const uint8_t reg_addr, uint8_t *reg_data, const uint16_t length);
bool i2c_write(const uint8_t reg_addr, const uint8_t *reg_data, const uint16_t length);

/* Functions needed by the BMP library */
#ifdef BMP280
void delay_ms(uint32_t period_ms);
int8_t i2c_reg_write(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
int8_t i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length);
void print_rslt(const char api_name[], int8_t rslt);
#else
void bmp3_delay_us(uint32_t period, void *intf_ptr);
BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr);
BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr);
void bmp3_check_rslt(const char api_name[], int8_t rslt);
#endif


int main(int argc, char** argv)
{
    /* Initialize bmp object. */
    int8_t rslt;
    #ifdef BMP280
    struct bmp280_dev bmp;
    bmp.dev_id = BMP280_I2C_ADDR_SEC; /* Assign device I2C address based on the status of SDO pin (GND for PRIMARY(0x76) & VDD for SECONDARY(0x77)) */
    bmp.intf = BMP280_I2C_INTF; /* Select the interface mode as I2C */
    /* Map the I2C read & write function pointer with the functions responsible for I2C bus transfer */
    bmp.read = i2c_reg_read;
    bmp.write = i2c_reg_write;
    bmp.delay_ms = delay_ms; /* Map the delay function pointer with the function responsible for implementing the delay */
    if (i2c_interface_init(DEVICE, bmp.dev_id) == false)
        return EXIT_FAILURE;
    rslt = bmp280_init(&bmp);
    print_rslt(" bmp_init status", rslt);
    #else
    struct bmp3_dev dev;
    dev.intf = BMP3_I2C_INTF;
    uint8_t dev_addr = BMP3_ADDR_I2C_SEC;
    dev.intf_ptr = &dev_addr;
    dev.read = bmp3_i2c_read;
    dev.write = bmp3_i2c_write;
    dev.delay_us = bmp3_delay_us;
    if (i2c_interface_init(DEVICE, dev_addr) == false)
        return EXIT_FAILURE;
    rslt = bmp3_init(&dev);
    bmp3_check_rslt("bmp3_init", rslt);
    #endif

    /* Configure sensor settings. */
    #ifdef BMP280
    struct bmp280_config conf;
    rslt = bmp280_get_config(&conf, &bmp); /* Always read the current settings before writing, especially when not all the configuration is modified */
    print_rslt(" bmp280_get_config status", rslt);
    conf.filter = BMP280_FILTER_COEFF_4; /* IIR filter coeff */
    conf.os_pres = BMP280_OS_4X; /* Pressure oversampling set at 4x */
    conf.os_temp = BMP280_OS_1X; /* Temperature oversampling set at 1x */
    conf.odr = BMP280_ODR_125_MS; /* Setting the output data rate as 1Hz (1000ms) */
    rslt = bmp280_set_config(&conf, &bmp);
    print_rslt(" bmp280_set_config status", rslt);
    rslt = bmp280_set_power_mode(BMP280_NORMAL_MODE, &bmp); /* Always set the power mode after setting the configuration. */
    print_rslt(" bmp280_set_power_mode status", rslt);
    #else
    struct bmp3_settings settings = { 0 };
    settings.int_settings.drdy_en = BMP3_ENABLE;
    settings.press_en = BMP3_ENABLE;
    settings.temp_en = BMP3_ENABLE;
    settings.odr_filter.press_os = BMP3_OVERSAMPLING_2X;
    settings.odr_filter.temp_os = BMP3_OVERSAMPLING_2X;
    settings.odr_filter.odr = BMP3_ODR_12_5_HZ;
    uint8_t settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR |
                   BMP3_SEL_DRDY_EN;
    rslt = bmp3_set_sensor_settings(settings_sel, &dev);
    bmp3_check_rslt("bmp3_set_sensor_settings", rslt);
    settings.op_mode = BMP3_MODE_NORMAL;
    rslt = bmp3_set_op_mode(&dev);
    bmp3_check_rslt("bmp3_set_op_mode", rslt);
    #endif

    /* Main loop. */
    while (1)
    {
        /* Make a pressure reading. */
        double temp = 0.;
        double pres = 0.;
        #ifdef BMP280
        struct bmp280_uncomp_data ucomp_data;
        rslt = bmp280_get_uncomp_data(&ucomp_data, &bmp); /* Read the raw data from sensor. */
        print_rslt(" bmp280_get_uncomp_data status", rslt);
        rslt = bmp280_get_comp_temp_double(&temp, ucomp_data.uncomp_temp, &bmp); /* Get the compensated temperature as floating point value */
        print_rslt(" bmp280_get_comp_temp_double status", rslt);
        rslt = bmp280_get_comp_pres_double(&pres, ucomp_data.uncomp_press, &bmp); /* Get the compensated pressure as floating point value */
        print_rslt(" bmp280_get_comp_pres_double status", rslt);
        #else
        struct bmp3_data data = { 0 };
        rslt = bmp3_get_sensor_data(BMP3_ALL, &data, &dev);
        bmp3_check_rslt("bmp3_get_sensor_data", rslt);
        rslt = bmp3_get_status(&dev); /* Read status register again to clear data ready interrupt status */
        bmp3_check_rslt("bmp3_get_status", rslt);
        #ifdef BMP3_DOUBLE_PRECISION_COMPENSATION
        temp = data.temperature;
        pres = data.pressure;
        #else
        temp = (double)data.temperature / 100.;
        pres = (double)data.pressure / 100.;
        #endif /* !BMP3_DOUBLE_PRECISION_COMPENSATION */
        #endif
        printf("%.1fPa %.1f°C\n", pres, temp);

        #ifdef BMP280
        bmp.delay_ms(125); /* Sleep time between measurements = BMP280_ODR_125_MS */
        #else
        usleep(125000); /* Sleep time between measurements */
        #endif
    }

    return EXIT_SUCCESS;
}


bool i2c_interface_init(const char* device, const uint8_t address)
{
    /* Open I2C device */
    if ((fd_i2c = open(device, O_RDWR)) < 0)
    {
        fprintf(stderr, "Failed to open the i2c bus %s\n", device);
        return false;
    }
    if (ioctl(fd_i2c, I2C_SLAVE, address) < 0)
    {
        fprintf(stderr, "Failed to acquire bus access and/or talk to slave.\n");
        return false;
    }
    return true;
}

bool i2c_read(const uint8_t reg_addr, uint8_t *reg_data, const uint16_t length)
{
    write(fd_i2c, &reg_addr, 1);
    read(fd_i2c, reg_data, length);
    for (int i=0; i<length; i++)
        printf("%02x ", reg_data[i]); // DEBUG
    return true;
}

bool i2c_write(const uint8_t reg_addr, const uint8_t *reg_data, const uint16_t length)
{
    int8_t *buf;

    buf = malloc(length + 1);
    buf[0] = reg_addr;
    memcpy(buf + 1, reg_data, length);
    if (write(fd_i2c, buf, length + 1) < length)
        return false;
    free(buf);
    return true;
}


#ifdef BMP280
void delay_ms(uint32_t period_ms)
{
    usleep(period_ms * 1000);
}

int8_t i2c_reg_write(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
{
    if (i2c_write(reg_addr, reg_data, length))
        return BMP280_OK;
    else
        return BMP280_E_COMM_FAIL;
}

int8_t i2c_reg_read(uint8_t i2c_addr, uint8_t reg_addr, uint8_t *reg_data, uint16_t length)
{
    i2c_read(reg_addr, reg_data, length);
    return BMP280_OK;
}

void print_rslt(const char api_name[], int8_t rslt)
{
    if (rslt != BMP280_OK)
    {
        printf("%s\t", api_name);
        if (rslt == BMP280_E_NULL_PTR)
        {
            printf("Error [%d] : Null pointer error\r\n", rslt);
        }
        else if (rslt == BMP280_E_COMM_FAIL)
        {
            printf("Error [%d] : Bus communication failed\r\n", rslt);
        }
        else if (rslt == BMP280_E_IMPLAUS_TEMP)
        {
            printf("Error [%d] : Invalid Temperature\r\n", rslt);
        }
        else if (rslt == BMP280_E_DEV_NOT_FOUND)
        {
            printf("Error [%d] : Device not found\r\n", rslt);
        }
        else
        {
            /* For more error codes refer "*_defs.h" */
            printf("Error [%d] : Unknown error code\r\n", rslt);
        }
    }
}

#else
BMP3_INTF_RET_TYPE bmp3_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    i2c_read(reg_addr, reg_data, len);
    return BMP3_INTF_RET_SUCCESS;
}

BMP3_INTF_RET_TYPE bmp3_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    if (i2c_write(reg_addr, reg_data, len))
        return BMP3_INTF_RET_SUCCESS;
    else
        return BMP3_E_COMM_FAIL;
}

void bmp3_delay_us(uint32_t period, void *intf_ptr)
{
    usleep(period);
}

void bmp3_check_rslt(const char api_name[], int8_t rslt)
{
    switch (rslt)
    {
        case BMP3_OK:

            /* Do nothing */
            break;
        case BMP3_E_NULL_PTR:
            printf("API [%s] Error [%d] : Null pointer\r\n", api_name, rslt);
            break;
        case BMP3_E_COMM_FAIL:
            printf("API [%s] Error [%d] : Communication failure\r\n", api_name, rslt);
            break;
        case BMP3_E_INVALID_LEN:
            printf("API [%s] Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
            break;
        case BMP3_E_DEV_NOT_FOUND:
            printf("API [%s] Error [%d] : Device not found\r\n", api_name, rslt);
            break;
        case BMP3_E_CONFIGURATION_ERR:
            printf("API [%s] Error [%d] : Configuration Error\r\n", api_name, rslt);
            break;
        case BMP3_W_SENSOR_NOT_ENABLED:
            printf("API [%s] Error [%d] : Warning when Sensor not enabled\r\n", api_name, rslt);
            break;
        case BMP3_W_INVALID_FIFO_REQ_FRAME_CNT:
            printf("API [%s] Error [%d] : Warning when Fifo watermark level is not in limit\r\n", api_name, rslt);
            break;
        default:
            printf("API [%s] Error [%d] : Unknown error code\r\n", api_name, rslt);
            break;
    }
}
#endif

 

8 replies