I2C lost arbitration

Hello,

I am trying to read temperature and pressure values from a BMP180 sensor.
I have tried with /dev/i2c-0 and /dev/i2c-1, the situation is the same…
In the serial console I can see the following error messages and in the end I can’t use the i2c port:

---- /dev/i2c-0 ----
[ 73.122550] i2c_designware 4000000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 74.160333] i2c_designware 4000000.i2c: controller timed out
[ 85.302134] i2c_designware 4000000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 85.321932] i2c_designware 4000000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 88.321675] i2c_designware 4000000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 88.341172] i2c_designware 4000000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 88.361020] i2c_designware 4000000.i2c: i2c_dw_handle_tx_abort: lost arbitration

----- /dev/i2c-0 -------------
[ 4838.114307] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4838.134184] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4838.154190] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4838.178650] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.353569] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.373488] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.393490] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.433674] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.453461] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.473482] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.493452] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.518301] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.553460] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.573427] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.593420] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration
[ 4840.613420] i2c_designware 4010000.i2c: i2c_dw_handle_tx_abort: lost arbitration

Are you setting the pinmux using the duo-pinmux command to set the gpio pins to i2c?

Yes, I have checked with duo-pinmux:

image

image

Just to make sure: is it the latest image?

I am using ubuntu image, and I’m compiling the code on the board directly… I have checked with blink example that is working, I assume the wiringX library is working…
I will try to compile the code on my machine and up load it on the board with the latest image.

I have run the code on the latest image same result, I’m getting some values at the beginning the only garbage and when I try to start the program again it will not work anymore…

I’m not an expert, but it looks very much like it’s being drifting left and right, that’s my thought.

To me, doesn’t seem like a hardware fault, more like it’s in software. Need to test it on my board (I got some I²C devices, and BME/BMP 180/280 are among them) soon.

Also, do you have any logic analyzer to capture what’s going on on the pins?

I have a logic analyzer, but I didn’t use it yet, as I the hardware works with arduino nano…

You said you observe this fault after a while of using with a test code for BMP280 (not BMP180, my fault).
I finally compiled it, found a BMP280 sensor and hooked it up to I²C bus #1 (pins 14,15 == GP10,GP11), and it just works, no arbitration errors for 10+ minutes already.

How soon does what you described start for you, how much time passes before you start seeing these error messages? Did any device initially work with your Duo board just fine, in the first place?

I have installed i2c-tools duo machine where ubuntu is running and I have connected the BMP180 as specified on PIN 14,15 I have run the command i2cdetect -y -r 1 which will get all devices connected to that i2c port. this is the result:

I would say that the “lost arbitration” starts instantly once the i2c communication starts…

It was never working, I haven’t had some readable data.

Can you share your code, so that I can test on my side?

# i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- 76 --

I only compiled i2c/bmp280_i2c example from the official duo-examples, that’s it. I even was too lazy to change the I²C bus #, I mostly wanted to try something as close to what you tested and as simple as possible. And the sooner the better, since I told you I could test it myself.

Oh, it wasn’t a BMP180 one, I just noticed that. Yet, I don’t think it actually changes anything tho, since in your case the driver starts going crazy with the native i²c diag tool.

If you experience such behaviour on any hardware I²C pins, there must be something wrong on the board.

I don’t know what, wrong on my side… I should order another board, but not from the same seller. I will try from aliexpress this time. The one that I have now, I got it from ebay.

1 Like

Judging by the size of the components on the board, it wouldn’t be easy to diagnose.
I got my board from AE.
Also, if I were in your place, I would try hooking up a logic analyzer to the wires and recording what it puts there, since you have both the board and some analyzer, and some time as well.

I will try to use my Oscilloscope, it can read/decode I2C protocol also… I will come back as soon as I have something.

1 Like

well, that was stupid… I forgot to connect the ground from the board with the ground from the sensor, as the sensor was powered from another power supply with 3.3V.

1 Like

I was hoping this wasn’t the case. Failing to connect common rail on every side can damage transistors in your ICs.

1 Like

Yes that is right, but it still works. I have tested it with arduino nano, but I’m still getting the wrong values with duo… maybe it is related to the i2c speed?

1 Like

May be so; yet, it will take some time for me to write some code for reading data from BMP180.
But if you’re curious, I can try your code on my board (I managed to find both BMP280 and BMP180) and tell you what results I get.

Here is my code…

bmp180.h

#ifndef _BMP180_H_
#define _BMP180_H_

#define BMP180_I2C_DEV "/dev/i2c-1"

#define BMP180_I2C_ADDR  0x77

// hardware registers
#define BMP180_REG_CTRL_MEAS  0xF4
#define BMP180_REG_SOFT_RESET 0xE0
#define BMP180_CHIP_ID        0xD0
#define BMP180_READ  1
#define BMP180_WRITE 0
#define BMP180_READ_ADDR  0xEF
#define BMP180_WRITE_ADDR 0xEE
#define BMP180_ULTRALOWPOWER 0 // 00b 1x read | Ultra low power mode
#define BMP180_STANDARD      1 // 01b 2x read | Standard mode
#define BMP180_HIGHRES       2 // 10b 4x read | High-res mode
#define BMP180_ULTRAHIGHRES  3 // 11b 8x read | Ultra high-res mode

#define BMP180_CTRL_TEMP        0x2E
#define BMP180_CTRL_PRESSURE_0  0x34
#define BMP180_CTRL_PRESSURE_1  0x74
#define BMP180_CTRL_PRESSURE_2  0xB4
#define BMP180_CTRL_PRESSURE_3  0xF4

#define BMP180_REG_OUT_XLSB 0xF8
#define BMP180_REG_OUT_LSB  0xF7
#define BMP180_REG_OUT_MSB  0xF6

// calibration registers
#define BMP180_REG_AC1_MSB 0xAA
#define BMP180_REG_AC1_LSB 0xAB
#define BMP180_REG_AC2_MSB 0xAC
#define BMP180_REG_AC2_LSB 0xAD
#define BMP180_REG_AC3_MSB 0xAE
#define BMP180_REG_AC3_LSB 0xAF
#define BMP180_REG_AC4_MSB 0xB0
#define BMP180_REG_AC4_LSB 0xB1
#define BMP180_REG_AC5_MSB 0xB2
#define BMP180_REG_AC5_LSB 0xB3
#define BMP180_REG_AC6_MSB 0xB4
#define BMP180_REG_AC6_LSB 0xB5
#define BMP180_REG_B1_MSB  0xB6
#define BMP180_REG_B1_LSB  0xB7
#define BMP180_REG_B2_MSB  0xB8
#define BMP180_REG_B2_LSB  0xB9
#define BMP180_REG_MB_MSB  0xBA
#define BMP180_REG_MB_LSB  0xBB
#define BMP180_REG_MC_MSB  0xBC
#define BMP180_REG_MC_LSB  0xBD
#define BMP180_REG_MD_MSB  0xBE
#define BMP180_REG_MD_LSB  0xBF


static int oss;
/*
* Immutable calibration data read from bmp180
*/
struct bmp180_calib_param {
    int16_t ac1;
    int16_t ac2;
    int16_t ac3;
    uint16_t ac4;
    uint16_t ac5;
    uint16_t ac6;
    int16_t b1;
    int16_t b2;
    int16_t mb;
    int16_t mc;
    int16_t md;
};

int bmp180_setup(int oversampling);
void bmp180_init(int fd);
void bmp180_get_calib_params(int fd, struct bmp180_calib_param* params); 
int32_t bmp180_get_ut(int fd);
int32_t bmp180_get_up(int fd);
int32_t bmp180_get_B5(int fd, const struct bmp180_calib_param params);
int32_t bmp180_get_temperature(int fd, const struct bmp180_calib_param params);
int32_t bmp180_get_pressure(int fd, const struct bmp180_calib_param params);

#endif

bmp180.c

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>

#include <wiringx.h>

#include <bmp180.h>
#include <math.h>

int bmp180_setup(int oversampling)
{
	printf("wiringXI2CSetup(%s, 0x%x)\n", BMP180_I2C_DEV, BMP180_I2C_ADDR);
	int fd_i2c = wiringXI2CSetup(BMP180_I2C_DEV, BMP180_I2C_ADDR);
	printf("fd_i2c: 0x%x\n", fd_i2c);
	if (fd_i2c < 0) {
        	printf("I2C Setup failed: 0x%x\n", fd_i2c);
		wiringXGC();
        	return -1;
	}
//    bmp180_init(fd_i2c);
        printf("wiringXI2CReadReg8(0x%x, 0x%x)\n", fd_i2c, BMP180_CHIP_ID);
	int8_t chip_id = wiringXI2CReadReg8(fd_i2c, BMP180_CHIP_ID);
	if (chip_id != 0x55){
		printf("BMP180 wrong chip ID. Got %xd, expected 0x55\n", chip_id);
		return -1;
	}

	oss = oversampling;
	return fd_i2c;
}

void bmp180_init(int fd) 
{
    // use the "handheld device dynamic" optimal setting (see datasheet)

    // 500ms sampling time, x16 filter
//    const uint8_t reg_config_val = ((0x04 << 5) | (0x05 << 2)) & 0xFC;
//    wiringXI2CWriteReg8(fd, BMP180_REG_CTRL_MEAS, reg_config_val);

    // osrs_t x1, osrs_p x4, normal mode operation
//    const uint8_t reg_ctrl_meas_val = (0x00 << 5) | (0x03 << 2) | (0x03);
//    wiringXI2CWriteReg8(fd, BMP180_REG_CTRL_MEAS, reg_ctrl_meas_val);
}

void bmp180_get_calib_params(int fd, struct bmp180_calib_param* params) 
{
	printf("function bmp180_get_calib_params(0x%x, 0x%x)\n", fd, &params);
	int8_t ac1_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC1_MSB);
	int8_t ac1_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC1_LSB);
        params->ac1 = ac1_msb << 8 + ac1_lsb;
//	printf("reading calibration parameter AC1\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC1_MSB);
//	printf("%d\n", ac1_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC1_LSB);
//	printf("%d\n", ac1_lsb);
	printf("AC1: %d\n", params->ac1);

	int8_t ac2_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC2_MSB);
	int8_t ac2_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC2_LSB);
        params->ac2 = ac2_msb << 8 + ac2_lsb;
//	printf("reading calibration parameter AC2\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC2_MSB);
//	printf("%d\n", ac2_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC2_LSB);
//	printf("%d\n", ac2_lsb);
	printf("AC2: %d\n", params->ac2);

	int8_t ac3_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC3_MSB);
	int8_t ac3_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC3_LSB);
        params->ac3 = ac3_msb << 8 + ac3_lsb;
//	printf("reading calibration parameter AC3\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC3_MSB);
//	printf("%d\n", ac3_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC3_LSB);
//	printf("%d\n", ac3_lsb);
	printf("AC3: %d\n", params->ac3);

	uint8_t ac4_msb = (uint8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC4_MSB);
	uint8_t ac4_lsb = (uint8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC4_LSB);
        params->ac4 = ac4_msb << 8 + ac4_lsb;
//	printf("reading calibration parameter AC4\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC4_MSB);
//	printf("%d\n", ac4_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC4_LSB);
//	printf("%d\n", ac4_lsb);
	printf("AC4: %d\n", params->ac4);

	uint8_t ac5_msb = (uint8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC5_MSB);
	uint8_t ac5_lsb = (uint8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC5_LSB);
        params->ac5 = ac5_msb << 8 + ac5_lsb;
//	printf("reading calibration parameter AC5\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC5_MSB);
//	printf("%d\n", ac5_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC5_LSB);
//	printf("%d\n", ac5_lsb);
	printf("AC5: %d\n", params->ac5);

	uint8_t ac6_msb = (uint8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC6_MSB);
	uint8_t ac6_lsb = (uint8_t)wiringXI2CReadReg8(fd, BMP180_REG_AC6_LSB);
        params->ac6 = ac6_msb << 8 + ac6_lsb;
//	printf("reading calibration parameter AC6\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC6_MSB);
//	printf("%d\n", ac6_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_AC6_LSB);
//	printf("%d\n", ac6_lsb);
	printf("AC6: %d\n", params->ac6);

	int8_t b1_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_B1_MSB);
	int8_t b1_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_B1_LSB);
        params->b1 = b1_msb << 8 + b1_lsb;
//	printf("reading calibration parameter B1\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_B1_MSB);
//	printf("%d\n", b1_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_B1_LSB);
//	printf("%d\n", b1_lsb);
	printf("B1: %d\n", params->b1);

	int8_t b2_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_B2_MSB);
	int8_t b2_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_B2_LSB);
        params->b2 = b2_msb << 8 + b2_lsb;
//	printf("reading calibration parameter B2\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_B2_MSB);
//	printf("%d\n", b2_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_B2_LSB);
//	printf("%d\n", b2_lsb);
	printf("B2: %d\n", params->b2);

	int8_t mb_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_MB_MSB);
	int8_t mb_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_MB_LSB);
        params->mb = mb_msb << 8 + mb_lsb;
//	printf("reading calibration parameter MB\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_MB_MSB);
//	printf("%d\n", mb_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_MB_LSB);
//	printf("%d\n", mb_lsb);
	printf("MB: %d\n", params->mb);

	int8_t mc_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_MC_MSB);
	int8_t mc_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_MC_LSB);
        params->mc = mc_msb << 8 + mc_lsb;
//	printf("reading calibration parameter MC\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_MC_MSB);
//	printf("%d\n", mc_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_MC_LSB);
//	printf("%d\n", mc_lsb);
	printf("MC: %d\n", params->mc);

	int8_t md_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_MD_MSB);
	int8_t md_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_MD_LSB);
        params->md = md_msb << 8 + md_lsb; 
//	printf("reading calibration parameter MD\n");
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_MD_MSB);
//	printf("%d\n", md_msb);
//	printf("wiringXI2CReadReg8(0x%x, 0x%X) = ", fd, BMP180_REG_MD_LSB);
//	printf("%d\n", md_lsb);
	printf("MD: %d\n", params->md);
}

int32_t bmp180_get_ut(int fd)
{
  printf("bmp180_get_ut\n");
	wiringXI2CWriteReg8(fd, BMP180_REG_CTRL_MEAS, BMP180_CTRL_TEMP);
	if (oss == BMP180_ULTRALOWPOWER)
	   delayMicroseconds(5000);
	else if (oss == BMP180_STANDARD)
           delayMicroseconds(8000);
	else if (oss == BMP180_HIGHRES)
	   delayMicroseconds(14000);
	else
           delayMicroseconds(26000);
	int8_t out_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_OUT_MSB);
	int8_t out_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_OUT_LSB);
	int32_t ut = out_msb << 8 + out_lsb;
	printf("out_msb: %d\n",out_msb);
	printf("out_lsb: %d\n",out_lsb);
	printf("ut: %d\n",ut);
	return ut;
}

int32_t bmp180_get_up(int fd)
{
  printf("bmp180_get_up\n");
        wiringXI2CWriteReg8(fd, BMP180_REG_CTRL_MEAS, BMP180_CTRL_PRESSURE_0 + (oss << 6));
	if (oss == BMP180_ULTRALOWPOWER)
	   delayMicroseconds(5000);
	else if (oss == BMP180_STANDARD)
           delayMicroseconds(8000);
	else if (oss == BMP180_HIGHRES)
	   delayMicroseconds(14000);
	else
           delayMicroseconds(26000);
	int8_t out_msb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_OUT_MSB);
	int8_t out_lsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_OUT_LSB);
	int8_t out_xlsb = (int8_t)wiringXI2CReadReg8(fd, BMP180_REG_OUT_XLSB);

	int32_t up = (out_msb << 16 + out_lsb << 8 + out_xlsb) >> (8-oss);
	printf("out_msb:  %d | ",out_msb);
	printf("out_lsb:  %d | ",out_lsb);
	printf("out_xlsb: %d\n",out_xlsb);
	printf("up: %d | oversampling: %d\n",up, oss);
	return up;

}

int32_t bmp180_get_B5(int fd, const struct bmp180_calib_param params)
{
  printf("bmp180_get_B5\n");
  int32_t UT = bmp180_get_ut(fd);
  printf("UT:  %u | ", UT);
  printf("AC5: %u | ", params.ac5);
  printf("AC6: %u | ", params.ac6);
  printf("MC:  %d | ", params.mc);
  printf("MD:  %d\n", params.md);
  int32_t X1 = (UT - (int32_t)params.ac6) * ((int32_t)params.ac5) >> 15;
  printf("X1:  %d | ", X1);
  int32_t X2 = ((int32_t)params.mc << 11) / (X1 + (int32_t)params.md);
  printf("X2:  %d\n", X2);
  return X1 + X2;
}

int32_t bmp180_get_temperature(int fd, const struct bmp180_calib_param params)
{
	printf("bmp180_get_temperature\n");
	int32_t B5 = bmp180_get_B5(fd, params);
//	return (B5 + 8) >> 4;
	return ((B5 + 8) >> 4) / 10;
}

int32_t bmp180_get_pressure(int fd, const struct bmp180_calib_param params)
{
	printf("bmp180_get_pressure\n");
        int32_t UP = bmp180_get_up(fd);
	printf("UP: %d | ", UP);
	int32_t B5 = bmp180_get_B5(fd, params);
	printf("B5: %d | ", B5);
	int32_t B6 = B5 - 4000;
	printf("B6: %d\n", B6);
	int32_t X1 = ((params.b2 * B6 * B6) >> 12) >> 11;
	printf("X1: %d | ", X1);
	int32_t X2 = (params.ac2 * B6) >> 11;
	printf("X2: %d | ", X2);
	int32_t X3 = X1 + X2;
	printf("X3: %d\n", X3);
	int32_t B3 = (((params.ac1 * 4 + X3) << oss) + 2) >> 2;
	printf("B3: %d | ", B3);
	X1 = (params.ac3 * B6) >> 13;
	printf("X1: %d | ", X1);
	X2 = ((params.b1 * B6 * B6) >> 12) >> 16;
	printf("X2: %d | ", X2);
	X3 = ((X1 + X2) + 2) >> 2;
	printf("X3: %d\n", X3);
	uint32_t B4 = ((uint32_t)params.ac4 * (uint32_t)(X3 + 32768)) >> 15;
	printf("B4: %d | ", B4);
	uint32_t B7 = ((uint32_t)UP - B3) * (uint32_t)(50000UL >> oss);
	printf("B7: %d\n ", B7);
	int32_t p;
	if (B7 < 0x80000000) 
		p = (B7 * 2) / B4;
	else
		p = (B7 / B4) * 2;
	X1 = (p >> 8) * (p >> 8);
	printf("X1: %d | ", X1);
	X1 = (X1 * 3038) >> 16;
	printf("X1: %d | ", X1);
	X2 = (-7357 * p) >> 16;
	printf("X2: %d\n", X1);
	p = p + ((X1 + X2 + (int32_t)3791) >> 2);
	printf("p: %d\n", p);
	return p;
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <math.h>

#include <wiringx.h>

#include <bmp180.h>

/*
this part is required for compiler on duo with ubuntu
as I'm compiling it directly on the duo dev board.
*/
unsigned long __stack_chk_guard;

void __stack_chk_guard_setup(void)
{
     __stack_chk_guard = 0xBAAAAAAD;//provide some magic numbers
}

void __stack_chk_fail(void)
{
	printf("variable corrupted");

}// will be called when guard variable is corrupted

int bmp180_i2c;
struct bmp180_calib_param bmp180_calib_params;

int setup()
{
    // wiringx setup to duo
    printf("wiringXSetup duo\n");
    if (wiringXSetup("duo", NULL) == -1)
    {
        wiringXGC();
	return -1;
    }

    // bmp180 setup
    printf("bmp180_setup\n");
    bmp180_i2c = bmp180_setup(BMP180_ULTRALOWPOWER);
    if (bmp180_i2c == -1)
	    exit(-1);
    printf("bmp180 setup completed\n");

    printf("reading bmp180 calibration parameters...\n");
    bmp180_get_calib_params(bmp180_i2c, &bmp180_calib_params);

}

void loop()
{

	int32_t temp = bmp180_get_temperature(bmp180_i2c, bmp180_calib_params); 
	int32_t pressure = bmp180_get_pressure(bmp180_i2c, bmp180_calib_params);

	//long altitude_meters = 101325;
	int32_t altitude_meters = 101500;
	float sea_level_pressure = (int32_t) (pressure / pow(1.0 - altitude_meters / 44330, 5.255));
	printf("sea_level_pressure: %f\n", sea_level_pressure);
	float altitude = 44330 * (1.0 - pow(pressure / sea_level_pressure, 0.1903));

	printf("Temperature: %d | ", temp);
        printf("Pressure: %d | ", pressure);
	printf("Altitude: %f ", altitude);
	printf("\n");

}

int main()
{
	if (setup() == -1)
	{
		printf("Setup failed\n");	
		return 0;
	}

	while(1)
	{
		loop();
		delayMicroseconds(1500000);
	}

}

This is the serial output from arduino nano:

09:43:35.727 -> ac1 = 7195
09:43:37.463 -> ac2 = -1085
09:43:37.463 -> ac3 = -14736
09:43:37.496 -> ac4 = 32024
09:43:37.496 -> ac5 = 25157
09:43:37.529 -> ac6 = 17830
09:43:37.529 -> b1 = 6515
09:43:37.529 -> b2 = 39
09:43:37.563 -> mb = -32768
09:43:37.563 -> mc = -11786
09:43:37.563 -> md = 2724
09:43:37.596 -> Temperature = Raw temp: 26171
09:43:37.629 -> 23.50 *C
09:43:37.629 -> Pressure = Raw temp: 26170
09:43:37.662 -> Raw pressure: 306705
09:43:37.695 -> X1 = 0
09:43:37.695 -> X2 = 0
09:43:37.695 -> B5 = 3758
09:43:37.695 -> B6 = -242
09:43:37.728 -> X1 = 0
09:43:37.728 -> X2 = 128
09:43:37.728 -> B3 = 57816
09:43:37.761 -> X1 = 435
09:43:37.761 -> X2 = 1
09:43:37.761 -> B4 = 32130
09:43:37.794 -> B7 = 1555556250
09:43:37.794 -> p = 96828
09:43:37.827 -> X1 = 6623
09:43:37.827 -> X2 = -10870
09:43:37.827 -> p = 96799
09:43:37.860 -> 96799 Pa
09:43:37.860 -> Altitude = Raw temp: 26172
09:43:37.893 -> Raw pressure: 306710
09:43:37.893 -> X1 = 0
09:43:37.926 -> X2 = 0
09:43:37.926 -> B5 = 3760
09:43:37.926 -> B6 = -240
09:43:37.959 -> X1 = 0
09:43:37.959 -> X2 = 127
09:43:37.959 -> B3 = 57814
09:43:37.993 -> X1 = 431
09:43:37.993 -> X2 = 1
09:43:37.993 -> B4 = 32129
09:43:38.026 -> B7 = 1555600000
09:43:38.026 -> p = 96834
09:43:38.026 -> X1 = 6623
09:43:38.059 -> X2 = -10871
09:43:38.059 -> p = 96805
09:43:38.092 -> 383.31 meters
09:43:38.092 -> Pressure at sealevel (calculated) = Raw temp: 26173
09:43:38.158 -> Raw pressure: 306709
09:43:38.158 -> X1 = 0
09:43:38.191 -> X2 = 0
09:43:38.191 -> B5 = 3761
09:43:38.191 -> B6 = -239
09:43:38.224 -> X1 = 0
09:43:38.224 -> X2 = 126
09:43:38.224 -> B3 = 57812
09:43:38.224 -> X1 = 429
09:43:38.257 -> X2 = 1
09:43:38.257 -> B4 = 32129
09:43:38.257 -> B7 = 1555606250
09:43:38.290 -> p = 96835
09:43:38.290 -> X1 = 6623
09:43:38.323 -> X2 = -10871
09:43:38.323 -> p = 96806
09:43:38.323 -> 96806 Pa
09:43:38.356 -> Real altitude = Raw temp: 26174
09:43:38.389 -> Raw pressure: 306692
09:43:38.389 -> X1 = 0
09:43:38.422 -> X2 = 0
09:43:38.422 -> B5 = 3761
09:43:38.422 -> B6 = -239
09:43:38.456 -> X1 = 0
09:43:38.456 -> X2 = 126
09:43:38.456 -> B3 = 57812
09:43:38.489 -> X1 = 429
09:43:38.489 -> X2 = 1
09:43:38.489 -> B4 = 32129
09:43:38.489 -> B7 = 1555500000
09:43:38.522 -> p = 96828
09:43:38.522 -> X1 = 6623
09:43:38.555 -> X2 = -10870
09:43:38.555 -> p = 96799
09:43:38.555 -> 398.25 meters
09:43:38.588 ->