New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for BMP581 #61535
Add support for BMP581 #61535
Conversation
Thank you very much for the effort @MeisterBob, I wasnt able to find time to finalize it. I see that it was failing due to email mismatch, I have added my email into commits so it should be ok now. |
@@ -552,6 +552,12 @@ test_i2c_bmp388: bmp388@55 { | |||
int-gpios = <&test_gpio 0 0>; | |||
}; | |||
|
|||
test_i2c_bmp581: bmp581@46 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that tests are failing due to duplicated address here. 46 is also being used by tmp112. It might be best to move bmp581 entry in dts to down to the end of the devices here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test was also failing because of a missing CONFIG_BMP581
in the tests prj.conf.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@talhaHavadar is right, the convention is to add new device at the end of the file with the next sequential address. Note this is just a build test and the address does not need to match the sensor datasheet.
Also, you should not need to set CONFIG_BMP581
in prj.conf
if you configure the Kconfig symbol to default y
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☑️
a1e7c2f
to
a9320a9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please separate these changes into multiple commits, one for each bullet:
drivers: bmp581: add BMP581 driver
addition work I did on top of @talhaHavadar's code.
- i2c_addr isn't used by the driver as this is already present in the
i2c_dt_spec struct. Also changed the i2c_dt_spec struct in bmp581_data
to a pointer, no need to store the information twice.
- fixed soft-reset: ret was checked on time too often and it didn't use
a helper function that was already present.
- added altitude interpolation: altitude calculation from pressure
requires pow() that isn't present in minimal libc. The inpolation
method interpolates the altitude between the values from a LUT. The
calculation methods ca be selected with the
`CONFIG_BMP581_ALTITUDE_CALC_[MATH|LUT|OFF]` Kconfig options.
- fixed tests
drivers/sensor/bmp581/Kconfig
Outdated
# | ||
|
||
config BMP581 | ||
bool "BMP581" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool "BMP581" | |
bool "BMP581 altitude sensor" | |
default y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☑️
drivers/sensor/bmp581/bmp581.c
Outdated
int reg_read(uint8_t reg, uint8_t *data, uint16_t length, struct bmp581_data *drv) | ||
{ | ||
return i2c_burst_read_dt(&drv->i2c, reg, data, length); | ||
} | ||
|
||
int reg_write(uint8_t reg, const uint8_t *data, uint16_t length, struct bmp581_data *drv) | ||
{ | ||
return i2c_burst_write_dt(&drv->i2c, reg, data, length); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrappers like this don't really add anything unless the sensor can support multiple bus interfaces (i.e., I2C and SPI). Please remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sensor also has an SPI interface. I can remove the wrapper or leave it to someone to add SPI support in the future. Please tell me how you want it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please give me some input about that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way these wrappers are currently implemented won't work when you add SPI (consider the case if you have two instances of this sensor, one attached to a SPI bus and the other to an I2C bus), so I suggest using i2c_burst_read_dt
and friends directly for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the wrappers.
drivers/sensor/bmp581/bmp581.c
Outdated
|
||
ret = get_power_mode(¤t_powermode, drv); | ||
if (ret != BMP5_OK) { | ||
LOG_DBG("Couldnt set the power mode because something went wrong when getting the " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOG_ERR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☑️
drivers/sensor/bmp581/bmp581.c
Outdated
* mode or continuous mode. | ||
*/ | ||
|
||
ret = reg_read(BMP5_REG_ODR_CONFIG, &odr, 1, drv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use i2c_reg_read_byte_dt
drivers/sensor/bmp581/bmp581.c
Outdated
*/ | ||
odr = BMP5_SET_BITSLICE(odr, BMP5_DEEP_DISABLE, BMP5_DEEP_DISABLED); | ||
odr = BMP5_SET_BITS_POS_0(odr, BMP5_POWERMODE, BMP5_POWERMODE_STANDBY); | ||
ret = reg_write(BMP5_REG_ODR_CONFIG, &odr, 1, drv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i2c_reg_write_byte_dt
drivers/sensor/bmp581/bmp581.c
Outdated
sensor_value_from_double(&drv->last_sample.temperature, | ||
(raw_temperature / 65536.0)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need to use floating point to divide by a power of 2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You lose the decimal places when you divide an int by an int.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some platforms in Zephyr don't have a hardware FPU so we try to avoid floating point operations if possible. I think you can do something like this:
/* use the integer part directly (may need to sign extend) */
drv->last_sample.temperature.val1 = data[2];
/* convert the fractional part to decimal */
drv->last_sample.temperature.val2 = 1000000 * ([data[1] << 8 | data[0]);
drivers/sensor/bmp581/bmp581.h
Outdated
#define BMP5_E_NULL_PTR -1 | ||
#define BMP5_E_COM_FAIL -2 | ||
#define BMP5_E_DEV_NOT_FOUND -3 | ||
#define BMP5_E_INVALID_CHIP_ID -4 | ||
#define BMP5_E_POWER_UP -5 | ||
#define BMP5_E_POR_SOFTRESET -6 | ||
#define BMP5_E_INVALID_POWERMODE -7 | ||
#define BMP5_E_INVALID_THRESHOLD -8 | ||
#define BMP5_E_FIFO_FRAME_EMPTY -9 | ||
#define BMP5_E_NVM_INVALID_ADDR -10 | ||
#define BMP5_E_NVM_NOT_READY -11 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use standard values from errno.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☑️
drivers/sensor/bmp581/bmp581.c
Outdated
drv->i2c = cfg->i2c; | ||
|
||
drv->i2c_addr = cfg->i2c_addr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed struct i2c_dt_spec i2c
from struct bmp581_data
@@ -552,6 +552,12 @@ test_i2c_bmp388: bmp388@55 { | |||
int-gpios = <&test_gpio 0 0>; | |||
}; | |||
|
|||
test_i2c_bmp581: bmp581@46 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@talhaHavadar is right, the convention is to add new device at the end of the file with the next sequential address. Note this is just a build test and the address does not need to match the sensor datasheet.
Also, you should not need to set CONFIG_BMP581
in prj.conf
if you configure the Kconfig symbol to default y
576fa3b
to
149c09e
Compare
drivers/sensor/bmp581/bmp581.c
Outdated
uint8_t odr = 0; | ||
enum bmp5_powermode current_powermode; | ||
|
||
if (dev == NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most drivers don't check this. You can use CHECKIF
to give the option to compile out the check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replaced all those NULL pointer checks with CHECKIF()
.
drivers/sensor/bmp581/bmp581.c
Outdated
int reg_read(uint8_t reg, uint8_t *data, uint16_t length, struct bmp581_data *drv) | ||
{ | ||
return i2c_burst_read_dt(&drv->i2c, reg, data, length); | ||
} | ||
|
||
int reg_write(uint8_t reg, const uint8_t *data, uint16_t length, struct bmp581_data *drv) | ||
{ | ||
return i2c_burst_write_dt(&drv->i2c, reg, data, length); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way these wrappers are currently implemented won't work when you add SPI (consider the case if you have two instances of this sensor, one attached to a SPI bus and the other to an I2C bus), so I suggest using i2c_burst_read_dt
and friends directly for now.
drivers/sensor/bmp581/bmp581.c
Outdated
*/ | ||
double last_pressure = sensor_value_to_double(&drv->last_sample.pressure); | ||
double last_temperature = sensor_value_to_double(&drv->last_sample.temperature); | ||
double sealevel_pressure = 101325.0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think having this altitude feature in the current form is missleading, to get good accurate altitude measurements from pressure, you need to feed in the actual pressure at sea level at the location you are at, typically this can be fetched from APIs on internet if you know your location. The pressure at sea level will depend alot on the weather and will change quite a bit just during a day. By hardcoding the sea-level pressure you will get inaccurate altitude, and this could be confusing for users. My suggestion is to remove this feature from the driver as it's missleading for users that are not aware of this. The only way I see this feature useful, is to calculate relative height if you compare samples taken close in time, but still I'm not sure if it should be in the driver and called altitude.
Just my thought, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left it in because it was in @talhaHavadar's original PR. I'm totaly fine with removing the altitude calculation from the driver as altitude isn't a value you can read from the sensor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My earlier comment about floating point arithmetic still needs to be addressed.
drivers/sensor/bmp581/bmp581.c
Outdated
* mode or continuous mode. | ||
*/ | ||
|
||
ret = i2c_burst_read_dt(&conf->i2c, BMP5_REG_ODR_CONFIG, &odr, 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For single byte reads and writes, you can use i2c_reg_read_byte_dt
and i2c_reg_write_byte
respectively
@MaureenHelm I addressed the remaining issues and rebased onto main. |
|
||
test_i2c_bmp581: bmp581@79 { | ||
compatible = "bosch,bmp581"; | ||
reg = <0x70>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be 0x79
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased again and increased to 0x80 due to merge conflict.
12dec0c
to
8006eb6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like a nice driver add
This commit adds source and header files required for bmp581 I2C driver. I have used bmp581_user.h to add more usage related definitions but bmp581.h to add hardware related definitions. Signed-off-by: Talha Can Havadar <havadartalha@gmail.com> Signed-off-by: Gerhard Jörges <joerges@metratec.com>
I rebased once more to fix the device address in |
@teburd would you please reapprove |
This Pullrequest add support for BMP581 Temperature/Pressure Sensor.
I started where @talhaHavadar stopped in #51849 and fixed the open issues that where left in this pull request. I also added altitude interpolation from a lookup table, because libc minimal doesn't come with
pow()
that is needed by the altitude calculation that was already implemented by @talhaHavadar.The Commits must be squashed before merge, just left them as multiple commits for easier review.