Compare commits

..

2 Commits

Author SHA1 Message Date
PurpleCloudX
b682f5424b
Merge 35f236ce0389d36c891f59bae3bdce5e7c758d7d into 298cbec7fc7b32abd30b7e00b37ad71e3ab0ec81 2024-11-25 19:43:32 +08:00
PurpleCloudX
35f236ce03 Changes requested 2024-11-25 19:42:52 +08:00
6 changed files with 110 additions and 92 deletions

@ -1,3 +1,5 @@
cmake_minimum_required(VERSION 3.1)
set(CMAKE_C_STANDARD 11)
idf_component_register( idf_component_register(
SRCS bmx280.c SRCS bmx280.c
INCLUDE_DIRS "include" INCLUDE_DIRS "include"

21
Kconfig

@ -2,21 +2,18 @@ menu "BMX280 Options"
choice I2C_DRIVER_SETTING choice I2C_DRIVER_SETTING
prompt "I2C driver setting" prompt "I2C driver setting"
help help
Select I2C driver: I2C_OLD: Use old driver I2C.h, I2C_NEW: Use new i2c_master.h(ESP-IDF >=5.3) Select I2C Driver: I2C Legacy Driver: I2C.h , I2C Master Driver i2c_master.h for ESP-IDF >= 5.3 AND Set I2C Clock Speed.
default USE_I2C_OLD_DEVICE default USE_I2C_LEGACY_DRIVER
config USE_I2C_LEGACY_DRIVER
config USE_I2C_OLD_DEVICE bool "I2C Legacy Driver (I2C.h)"
bool "old I2C driver (I2C.h)"
help help
Use the old I2C driver (I2C.h). Use I2C Legacy Driver (I2C.h).
config USE_I2C_MASTER_DRIVER
config USE_I2C_NEW_DEVICE bool "I2C Master Driver (i2c_master.h)"
bool "new I2C driver (i2c_master.h)"
help help
Use the new I2C driver (i2c_master.h) for ESP-IDF >= 5.2. Use I2C Master Driver (i2c_master.h) for ESP-IDF >= 5.3.
config BMX280_I2C_CLK_SPEED_HZ config BMX280_I2C_CLK_SPEED_HZ
int "I2C clock speed (Hz)" int "I2C Clock Speed (Hz)"
default 100000 default 100000
range 1000 400000 range 1000 400000
help help

@ -12,18 +12,19 @@ Example Code
------------ ------------
To use the legacy i2c.h driver, please refer to the [example_with_i2c.h](examples/bmx280_example_without_i2c_master.c). To use the legacy i2c.h driver, please refer to the [example_with_i2c.h](examples/bmx280_example_without_i2c_master.c).
To use the new i2c_master.h driver (ESP-IDF >= 5.3): To use the i2c_master.h driver (ESP-IDF >= 5.3):
* First, run `idf.py menuconfig` to configure the project. * First, run `idf.py menuconfig` to configure the project.
* Navigate to Component Config -> BMX280 Options -> I2C driver setting -> new I2C driver (i2c_master.h). * Navigate to Component Config -> BMX280 Options -> I2C driver setting -> I2C Master Driver (i2c_master.h).
* Press the 'S' key to save the configuration. * Press the 'S' key to save the configuration.
* You can then use the new driver to complete your code. * You can then use the I2C Master driver to complete your code.
For example code, please see the [example_with_i2c_master.h](examples/bmx280_example_with_i2c_master.c). For example code, please see the [example_with_i2c_master.h](examples/bmx280_example_with_i2c_master.c).
**Note:** If you want to use the legacy i2c.h driver, no changes are needed; continue using `bmx280_create` to create the anonymous structure `bmx280`. If you use the i2c_master.h driver, you need to use `bmx280_create_master` to create the structure.
License License
------- -------

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

132
bmx280.c

@ -69,18 +69,8 @@
// Value of REG_CHPID for BMP280 (Production) // Value of REG_CHPID for BMP280 (Production)
#define BMP280_ID2 0x58 #define BMP280_ID2 0x58
#if CONFIG_USE_I2C_NEW_DEVICE
// I2C Master configuration structure (temporary)
typedef struct i2c_config_t{
// I2C master configuration
i2c_device_config_t dev_cfg;
// I2C master handle via port
i2c_master_bus_handle_t bus_handle;
}*i2c_config_t;
#endif
struct bmx280_t{ struct bmx280_t{
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
// I2C port. // I2C port.
i2c_port_t i2c_port; i2c_port_t i2c_port;
// Slave Address of sensor. // Slave Address of sensor.
@ -88,8 +78,10 @@ struct bmx280_t{
#else #else
// I2C master handle via port with configuration // I2C master handle via port with configuration
i2c_master_dev_handle_t i2c_dev; i2c_master_dev_handle_t i2c_dev;
// I2C master configuration structure // I2C master configuration
i2c_config_t i2c_cfg; i2c_device_config_t dev_cfg;
// I2C master handle via port
i2c_master_bus_handle_t bus_handle;
#endif #endif
// Chip ID of sensor // Chip ID of sensor
uint8_t chip_id; uint8_t chip_id;
@ -139,25 +131,34 @@ struct bmx280_t{
* Returns false if the sensor was not found. * Returns false if the sensor was not found.
* @param bmx280 The driver structure. * @param bmx280 The driver structure.
*/ */
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
#define bmx280_validate(bmx280) (!(bmx280->slave == 0xDE && bmx280->chip_id == 0xAD)) #define bmx280_validate(bmx280) (!(bmx280->slave == 0xDE && bmx280->chip_id == 0xAD))
#else #else
#define bmx280_validate(bmx280) (!(bmx280->i2c_dev == NULL && bmx280->chip_id == 0xAD)) #define bmx280_validate(bmx280) (!(bmx280->i2c_dev == NULL && bmx280->chip_id == 0xAD))
#endif #endif
#if CONFIG_USE_I2C_NEW_DEVICE #if CONFIG_USE_I2C_MASTER_DRIVER
/** /**
* Read from sensor. * Read from sensor.
* @param bmx280 Driver Sturcture. * @param bmx280 Driver Sturcture.
* @param dev_addr Chip addresses. * @param dev_addr Chip addresses.
*/ */
static void bmx280_device_create(bmx280_t *bmx280, const uint16_t dev_addr) static esp_err_t bmx280_device_create(bmx280_t *bmx280, const uint16_t dev_addr)
{ {
ESP_LOGI("bmx280", "device_create for BMP280/BME280 sensors on ADDR %X", dev_addr); ESP_LOGI("bmx280", "device_create for BMP280/BME280 sensors on ADDR %X", dev_addr);
bmx280->i2c_cfg->dev_cfg.device_address = dev_addr; bmx280->dev_cfg.device_address = dev_addr;
// Add device to the I2C bus // Add device to the I2C bus
ESP_ERROR_CHECK(i2c_master_bus_add_device(bmx280->i2c_cfg->bus_handle, &bmx280->i2c_cfg->dev_cfg, &bmx280->i2c_dev)); esp_err_t err = i2c_master_bus_add_device(bmx280->bus_handle, &bmx280->dev_cfg, &bmx280->i2c_dev);
if (err == ESP_OK)
{
ESP_LOGI("bmx280", "device_create success on 0x%x", dev_addr); ESP_LOGI("bmx280", "device_create success on 0x%x", dev_addr);
return err;
}
else
{
ESP_LOGE("bmx280", "device_create error on 0x%x", dev_addr);
return err;
}
} }
#endif #endif
@ -171,7 +172,7 @@ static void bmx280_device_create(bmx280_t *bmx280, const uint16_t dev_addr)
*/ */
static esp_err_t bmx280_read(bmx280_t *bmx280, uint8_t addr, uint8_t *dout, size_t size) static esp_err_t bmx280_read(bmx280_t *bmx280, uint8_t addr, uint8_t *dout, size_t size)
{ {
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
esp_err_t err; esp_err_t err;
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
if (cmd) if (cmd)
@ -204,7 +205,7 @@ static esp_err_t bmx280_read(bmx280_t *bmx280, uint8_t addr, uint8_t *dout, size
static esp_err_t bmx280_write(bmx280_t* bmx280, uint8_t addr, const uint8_t *din, size_t size) static esp_err_t bmx280_write(bmx280_t* bmx280, uint8_t addr, const uint8_t *din, size_t size)
{ {
esp_err_t err; esp_err_t err;
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_cmd_handle_t cmd = i2c_cmd_link_create();
if (cmd) if (cmd)
{ {
@ -228,10 +229,9 @@ static esp_err_t bmx280_write(bmx280_t* bmx280, uint8_t addr, const uint8_t *din
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
#else #else
for(int i = 0; i < size; i++) for(uint8_t i = 0; i < size; i++)
{ {
uint8_t addri = addr + i; uint8_t dat[2] = {(addr + i), din[i]};
uint8_t dat[2] = {addri, din[i]};
if ((err = i2c_master_transmit(bmx280->i2c_dev, dat, 2, CONFIG_BMX280_TIMEOUT)) != ESP_OK) if ((err = i2c_master_transmit(bmx280->i2c_dev, dat, 2, CONFIG_BMX280_TIMEOUT)) != ESP_OK)
return err; return err;
} }
@ -254,38 +254,43 @@ static esp_err_t bmx280_probe_address(bmx280_t *bmx280)
#endif #endif
) )
{ {
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
ESP_LOGI("bmx280", "Probe success: address=%hhx, id=%hhx", bmx280->slave, bmx280->chip_id); ESP_LOGI("bmx280", "Probe success: address=%hhx, id=%hhx", bmx280->slave, bmx280->chip_id);
#else #else
ESP_LOGI("bmx280", "Probe success: address=%hhx, id=%hhx", bmx280->i2c_cfg->dev_cfg.device_address, bmx280->chip_id); ESP_LOGI("bmx280", "Probe success: address=%hhx, id=%hhx", bmx280->dev_cfg.device_address, bmx280->chip_id);
#endif #endif
return ESP_OK; return ESP_OK;
} }
else else
{ {
ESP_LOGE("bmx280", "Sensor model may be incorrect. Please check the sensor model configuration. If unsure, set it to AUTO.");
err = ESP_ERR_NOT_FOUND; err = ESP_ERR_NOT_FOUND;
} }
} }
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
ESP_LOGW("bmx280", "Probe failure: address=%hhx, id=%hhx, reason=%s", bmx280->slave, bmx280->chip_id, esp_err_to_name(err)); ESP_LOGW("bmx280", "Probe failure: address=%hhx, id=%hhx, reason=%s", bmx280->slave, bmx280->chip_id, esp_err_to_name(err));
#else #else
ESP_LOGW("bmx280", "Probe failure: address=%hhx, id=%hhx, reason=%s", bmx280->i2c_cfg->dev_cfg.device_address, bmx280->chip_id, esp_err_to_name(err)); ESP_LOGW("bmx280", "Probe failure: address=%hhx, id=%hhx, reason=%s", bmx280->dev_cfg.device_address, bmx280->chip_id, esp_err_to_name(err));
#endif #endif
return err; return err;
} }
static esp_err_t bmx280_probe(bmx280_t *bmx280) static esp_err_t bmx280_probe(bmx280_t *bmx280)
{ {
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
ESP_LOGI("bmx280", "Probing for BMP280/BME280 sensors on I2C %d", bmx280->i2c_port); ESP_LOGI("bmx280", "Probing for BMP280/BME280 sensors on I2C %d", bmx280->i2c_port);
esp_err_t err;
#if CONFIG_BMX280_ADDRESS_HI #if CONFIG_BMX280_ADDRESS_HI
bmx280->slave = 0xEE; bmx280->slave = 0xEE;
return bmx280_probe_address(bmx280); err = bmx280_probe_address(bmx280);
if (err != ESP_OK) ESP_LOGE("bmx280", "Sensor not found at 0x77 , Please check the address.");
return err;
#elif CONFIG_BMX280_ADDRESS_LO #elif CONFIG_BMX280_ADDRESS_LO
bmx280->slave = 0xEC; bmx280->slave = 0xEC;
return bmx280_probe_address(bmx280); err = bmx280_probe_address(bmx280);
if (err != ESP_OK) ESP_LOGE("bmx280", "Sensor not found at 0x76 , Please check the address.");
return err;
#else #else
esp_err_t err;
bmx280->slave = 0xEC; bmx280->slave = 0xEC;
if ((err = bmx280_probe_address(bmx280)) != ESP_OK) if ((err = bmx280_probe_address(bmx280)) != ESP_OK)
{ {
@ -303,20 +308,24 @@ static esp_err_t bmx280_probe(bmx280_t *bmx280)
ESP_LOGI("bmx280", "Probing for BMP280/BME280 sensors on I2C"); ESP_LOGI("bmx280", "Probing for BMP280/BME280 sensors on I2C");
esp_err_t err; esp_err_t err;
#if CONFIG_BMX280_ADDRESS_HI #if CONFIG_BMX280_ADDRESS_HI
bmx280_device_create(bmx280, 0x77); err = bmx280_device_create(bmx280, 0x77);
if (err != ESP_OK) return err;
err = bmx280_probe_address(bmx280); err = bmx280_probe_address(bmx280);
free(bmx280->i2c_cfg); if (err != ESP_OK) ESP_LOGE("bmx280", "Sensor not found at 0x77 , Please check the address.");
return err; return err;
#elif CONFIG_BMX280_ADDRESS_LO #elif CONFIG_BMX280_ADDRESS_LO
bmx280_device_create(bmx280, 0x76); err = bmx280_device_create(bmx280, 0x76);
if (err != ESP_OK) return err;
err = bmx280_probe_address(bmx280); err = bmx280_probe_address(bmx280);
free(bmx280->i2c_cfg); if (err != ESP_OK) ESP_LOGE("bmx280", "Sensor not found at 0x76 , Please check the address.");
return err; return err;
#else #else
bmx280_device_create(bmx280, 0x76); err = bmx280_device_create(bmx280, 0x76);
if (err != ESP_OK) return err;
if ((err = bmx280_probe_address(bmx280)) != ESP_OK) if ((err = bmx280_probe_address(bmx280)) != ESP_OK)
{ {
bmx280_device_create(bmx280, 0x77); err = bmx280_device_create(bmx280, 0x77);
if (err != ESP_OK) return err;
if ((err = bmx280_probe_address(bmx280)) != ESP_OK) if ((err = bmx280_probe_address(bmx280)) != ESP_OK)
{ {
ESP_LOGE("bmx280", "Sensor not found."); ESP_LOGE("bmx280", "Sensor not found.");
@ -324,7 +333,6 @@ static esp_err_t bmx280_probe(bmx280_t *bmx280)
bmx280->chip_id = 0xAD; bmx280->chip_id = 0xAD;
} }
} }
free(bmx280->i2c_cfg);
return err; return err;
#endif #endif
#endif #endif
@ -397,32 +405,15 @@ static esp_err_t bmx280_calibrate(bmx280_t *bmx280)
return ESP_OK; return ESP_OK;
} }
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
bmx280_t* bmx280_create(i2c_port_t port) bmx280_t* bmx280_create_legacy(i2c_port_t port)
{ {
bmx280_t* bmx280 = malloc(sizeof(bmx280_t)); bmx280_t* bmx280 = malloc(sizeof(bmx280_t));
if (bmx280) if (bmx280)
{ {
memset(bmx280, 0, sizeof(bmx280_t)); memset(bmx280, 0, sizeof(bmx280_t));
bmx280->i2c_port = port; bmx280->i2c_port = port;
bmx280->slave = 0xDE; bmx280->slave = 0xDE;
#else
bmx280_t* bmx280_create(i2c_master_bus_handle_t bus_handle)
{
bmx280_t* bmx280 = malloc(sizeof(bmx280_t));
i2c_config_t dev_cfg = malloc(sizeof(struct i2c_config_t));
if (bmx280 && dev_cfg)
{
memset(bmx280, 0, sizeof(bmx280_t));
memset(dev_cfg, 0, sizeof(struct i2c_config_t));
bmx280->i2c_cfg = dev_cfg;
bmx280->i2c_cfg->bus_handle = bus_handle;
bmx280->i2c_cfg->dev_cfg.dev_addr_length = I2C_ADDR_BIT_LEN_7;
bmx280->i2c_cfg->dev_cfg.device_address = 0xDE;
bmx280->i2c_cfg->dev_cfg.scl_speed_hz =CONFIG_BMX280_I2C_CLK_SPEED_HZ;
bmx280->i2c_dev = NULL;
#endif
bmx280->chip_id = 0xAD; bmx280->chip_id = 0xAD;
} }
else else
@ -433,11 +424,34 @@ bmx280_t* bmx280_create(i2c_master_bus_handle_t bus_handle)
} }
return bmx280; return bmx280;
} }
#else
bmx280_t* bmx280_create_master(i2c_master_bus_handle_t bus_handle)
{
bmx280_t* bmx280 = malloc(sizeof(bmx280_t));
if (bmx280)
{
memset(bmx280, 0, sizeof(bmx280_t));
bmx280->bus_handle = bus_handle;
bmx280->dev_cfg.dev_addr_length = I2C_ADDR_BIT_LEN_7;
bmx280->dev_cfg.device_address = 0xDE;
bmx280->dev_cfg.scl_speed_hz =CONFIG_BMX280_I2C_CLK_SPEED_HZ;
bmx280->i2c_dev = NULL;
bmx280->chip_id = 0xAD;
}
else
{
ESP_LOGE("bmx280", "Failed to allocate memory for bmx280.");
bmx280_close(bmx280);
return NULL;
}
return bmx280;
}
#endif
void bmx280_close(bmx280_t *bmx280) void bmx280_close(bmx280_t *bmx280)
{ {
#if CONFIG_USE_I2C_NEW_DEVICE #if CONFIG_USE_I2C_MASTER_DRIVER
free(bmx280->i2c_cfg); if(bmx280->i2c_dev!=NULL)
i2c_master_bus_rm_device(bmx280->i2c_dev); i2c_master_bus_rm_device(bmx280->i2c_dev);
#endif #endif
free(bmx280); free(bmx280);

@ -24,7 +24,7 @@ i2c_master_bus_handle_t i2c_bus_init(uint8_t sda_io, uint8_t scl_io)
esp_err_t bmx280_dev_init(bmx280_t** bmx280,i2c_master_bus_handle_t bus_handle) esp_err_t bmx280_dev_init(bmx280_t** bmx280,i2c_master_bus_handle_t bus_handle)
{ {
*bmx280 = bmx280_create(bus_handle); *bmx280 = bmx280_create_master(bus_handle);
if (!*bmx280) { if (!*bmx280) {
ESP_LOGE("test", "Could not create bmx280 driver."); ESP_LOGE("test", "Could not create bmx280 driver.");
return ESP_FAIL; return ESP_FAIL;
@ -59,7 +59,6 @@ void app_main(void)
bmx280_close(bmx280); bmx280_close(bmx280);
i2c_del_master_bus(bus_handle); i2c_del_master_bus(bus_handle);
ESP_LOGI("test", "Restarting now."); ESP_LOGI("test", "Restarting now.");
esp_restart(); esp_restart();
} }

@ -16,10 +16,11 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <limits.h> #include <limits.h>
#include <assert.h>
#include "sdkconfig.h" #include "sdkconfig.h"
#include "bmx280_bits.h" #include "bmx280_bits.h"
#if !(CONFIG_USE_I2C_NEW_DEVICE) #if !(CONFIG_USE_I2C_MASTER_DRIVER)
#include "driver/i2c.h" #include "driver/i2c.h"
#else #else
#include "driver/i2c_master.h" #include "driver/i2c_master.h"
@ -34,24 +35,28 @@ extern "C" {
*/ */
typedef struct bmx280_t bmx280_t; typedef struct bmx280_t bmx280_t;
#if CONFIG_USE_I2C_MASTER_DRIVER
#if !(CONFIG_USE_I2C_NEW_DEVICE)
/**
* Create an instance of the BMX280 driver.
* @param port The I2C port to use.
* @return A non-null pointer to the driver structure on success.
*/
BMXAPI bmx280_t* bmx280_create(i2c_port_t port);
#else
/** /**
* Create an instance of the BMX280 driver. * Create an instance of the BMX280 driver.
* @param bus_handle The I2C master handle via port. * @param bus_handle The I2C master handle via port.
* @return A non-null pointer to the driver structure on success. * @return A non-null pointer to the driver structure on success.
*/ */
BMXAPI bmx280_t* bmx280_create(i2c_master_bus_handle_t bus_handle); BMXAPI bmx280_t* bmx280_create_master(i2c_master_bus_handle_t bus_handle);
// legacy define for existing code bases
#define bmx280_create(port) bmx280_create_legacy(port)
#define bmx280_create_legacy(port) static_assert(0, "You have the wrong driver configuration for using the legacy I2C driver.")
#else
/**
* Create an instance of the BMX280 driver.
* @param port The I2C port to use.
* @return A non-null pointer to the driver structure on success.
*/
BMXAPI bmx280_t* bmx280_create_legacy(i2c_port_t port);
// legacy define for existing code bases
#define bmx280_create(port) bmx280_create_legacy(port)
#define bmx280_create_master(port) static_assert(0, "You have the wrong driver configuration for using the new I2C master driver.")
#endif #endif
/** /**
* Destroy your the instance. * Destroy your the instance.
* @param bmx280 The instance to destroy. * @param bmx280 The instance to destroy.