Skip to content

Commit

Permalink
feat(qma6100p): I2C Driver-NG
Browse files Browse the repository at this point in the history
  • Loading branch information
pborcin authored and tore-espressif committed Nov 19, 2024
1 parent a2a9211 commit 649e14a
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 76 deletions.
3 changes: 3 additions & 0 deletions .build-test-rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ components/icm42670:
components/qma6100p:
depends_filepatterns:
- "components/qma6100p/**"
disable:
- if: (IDF_VERSION_MAJOR == 5 and IDF_VERSION_MINOR < 2) or IDF_VERSION_MAJOR < 5
reason: Requires I2C Driver-NG which was introduced in v5.2

components/io_expander/esp_io_expander_ht8574:
depends_filepatterns:
Expand Down
2 changes: 1 addition & 1 deletion bsp/esp32_s3_eye/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ The ESP32-S3-EYE board consists of two parts: the main board (ESP32-S3-EYE-MB) t
|AUDIO_SPEAKER| :x: | | |
| AUDIO_MIC |:heavy_check_mark:| | |
| SDCARD |:heavy_check_mark:| idf | >=5.4 |
| IMU |:heavy_check_mark:| [qma6100p](https://components.espressif.com/components/qma6100p) | 1.* |
| IMU |:heavy_check_mark:| [qma6100p](https://components.espressif.com/components/qma6100p) | ^2 |
| CAMERA |:heavy_check_mark:| [espressif/esp32-camera](https://components.espressif.com/components/espressif/esp32-camera) | ^2.0.13 |
<!-- Autogenerated end: Dependencies -->
2 changes: 1 addition & 1 deletion bsp/esp32_s3_eye/idf_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ dependencies:
public: true

qma6100p:
version: "1.*" #todo update this to v2 with driver-NG support
version: "^2"
override_path: "../../components/qma6100p"
public: true
4 changes: 2 additions & 2 deletions components/qma6100p/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: "1.0.0"
version: "2.0.0"
description: I2C driver for QMA6100P accelerometer
url: https://github.com/espressif/esp-bsp/tree/master/components/qma6100p
dependencies:
idf : ">=4.0"
idf : ">=5.2"
cmake_utilities: "0.*"
18 changes: 10 additions & 8 deletions components/qma6100p/include/qma6100p.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
extern "C" {
#endif

#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "driver/gpio.h"

#define QMA6100P_I2C_ADDRESS 0x12u /*!< I2C address with AD0 pin low */
Expand Down Expand Up @@ -89,16 +89,18 @@ typedef struct {
typedef void *qma6100p_handle_t;

/**
* @brief Create and init sensor object and return a sensor handle
*
* @param port I2C port number
* @param dev_addr I2C device address of sensor
* @brief Create and init sensor object
*
* @param[in] i2c_bus I2C bus handle. Obtained from i2c_new_master_bus()
* @param[in] dev_addr I2C device address of sensor. Can be QMA6100P_I2C_ADDRESS or QMA6100P_I2C_ADDRESS_1
* @param[out] handle_ret Handle to created QMA6100P driver object*
* @return
* - NULL Fail
* - Others Success
* - ESP_OK Success
* - ESP_ERR_NO_MEM Not enough memory for the driver
* - ESP_ERR_NOT_FOUND Sensor not found on the I2C bus
* - Others Error from underlying I2C driver
*/
qma6100p_handle_t qma6100p_create(i2c_port_t port, const uint16_t dev_addr);
esp_err_t qma6100p_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr, qma6100p_handle_t *handle_ret);

/**
* @brief Delete and release a sensor object
Expand Down
86 changes: 39 additions & 47 deletions components/qma6100p/qma6100p.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
#include <time.h>
#include <sys/time.h>
#include "esp_system.h"
#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "qma6100p.h"
#include "esp_err.h"
#include "esp_check.h"

#define I2C_CLK_SPEED 400000

#define QMA6100P_WHO_AM_I 0x00u
#define QMA6100P_ACCEL_CONFIG 0x0Fu
Expand Down Expand Up @@ -38,7 +42,6 @@
#define QMA6100P_FIFO_DATA 0x3Fu
#define QMA6100P_FIFO_MODE 0x3Eu


const uint8_t QMA6100P_DATA_RDY_INT_BIT = (uint8_t) BIT4;
// FIFO full interrupt
const uint8_t QMA6100P_FIFO_FULL_INT_BIT = (uint8_t) BIT5;
Expand All @@ -47,11 +50,11 @@ const uint8_t QMA6100P_FIFO_WM_INT_BIT = (uint8_t) BIT6;
const uint8_t QMA6100P_FIFO_OF_INT_BIT = (uint8_t) BIT7;
const uint8_t QMA6100P_ALL_INTERRUPTS = (QMA6100P_DATA_RDY_INT_BIT | QMA6100P_FIFO_FULL_INT_BIT | QMA6100P_FIFO_WM_INT_BIT | QMA6100P_FIFO_OF_INT_BIT);

static const char *TAG = "QMA6100P";

typedef struct {
i2c_port_t bus;
i2c_master_dev_handle_t i2c_handle;
gpio_num_t int_pin;
uint16_t dev_addr;
uint32_t counter;
float dt; /*!< delay time between two measurements, dt should be small (ms level) */
struct timeval *timer;
Expand All @@ -60,65 +63,54 @@ typedef struct {
static esp_err_t qma6100p_write(qma6100p_handle_t sensor, const uint8_t reg_start_addr, const uint8_t data_buf)
{
qma6100p_dev_t *sens = (qma6100p_dev_t *) sensor;
esp_err_t ret;

i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ret = i2c_master_start(cmd);
assert(ESP_OK == ret);
ret = i2c_master_write_byte(cmd, sens->dev_addr | I2C_MASTER_WRITE, true);
assert(ESP_OK == ret);
ret = i2c_master_write_byte(cmd, reg_start_addr, true);
assert(ESP_OK == ret);
ret = i2c_master_write_byte(cmd, data_buf, true);
assert(ESP_OK == ret);
ret = i2c_master_stop(cmd);
assert(ESP_OK == ret);
ret = i2c_master_cmd_begin(sens->bus, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);

return ret;
uint8_t write_buff[2] = {reg_start_addr, data_buf};
return i2c_master_transmit(sens->i2c_handle, write_buff, 2, -1);
}

static esp_err_t qma6100p_read(qma6100p_handle_t sensor, const uint8_t reg_start_addr, uint8_t *const data_buf, const uint8_t data_len)
{
qma6100p_dev_t *sens = (qma6100p_dev_t *) sensor;
esp_err_t ret;

i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ret = i2c_master_start(cmd);
assert(ESP_OK == ret);
ret = i2c_master_write_byte(cmd, sens->dev_addr | I2C_MASTER_WRITE, true);
assert(ESP_OK == ret);
ret = i2c_master_write_byte(cmd, reg_start_addr, true);
assert(ESP_OK == ret);
ret = i2c_master_start(cmd);
assert(ESP_OK == ret);
ret = i2c_master_write_byte(cmd, sens->dev_addr | I2C_MASTER_READ, true);
assert(ESP_OK == ret);
ret = i2c_master_read(cmd, data_buf, data_len, I2C_MASTER_LAST_NACK);
assert(ESP_OK == ret);
ret = i2c_master_stop(cmd);
assert(ESP_OK == ret);
ret = i2c_master_cmd_begin(sens->bus, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);

return ret;
uint8_t reg_buff[] = {reg_start_addr};
assert(sens);

return i2c_master_transmit_receive(sens->i2c_handle, reg_buff, sizeof(reg_buff), data_buf, data_len, -1);
}

qma6100p_handle_t qma6100p_create(i2c_port_t port, const uint16_t dev_addr)
esp_err_t qma6100p_create(i2c_master_bus_handle_t i2c_bus, const uint8_t dev_addr, qma6100p_handle_t *handle_ret)
{
esp_err_t ret = ESP_OK;

qma6100p_dev_t *sensor = (qma6100p_dev_t *) calloc(1, sizeof(qma6100p_dev_t));
sensor->bus = port;
sensor->dev_addr = dev_addr << 1;
sensor->counter = 0;
sensor->dt = 0;
sensor->timer = (struct timeval *) calloc(1, sizeof(struct timeval));
return (qma6100p_handle_t) sensor;
struct timeval *timer = (struct timeval *) calloc(1, sizeof(struct timeval));
ESP_RETURN_ON_FALSE(sensor != NULL && timer != NULL, ESP_ERR_NO_MEM, TAG, "Not enough memory");

// Add new I2C device
const i2c_device_config_t i2c_dev_cfg = {
.device_address = dev_addr,
.scl_speed_hz = I2C_CLK_SPEED,
};
ESP_GOTO_ON_ERROR(i2c_master_bus_add_device(i2c_bus, &i2c_dev_cfg, &sensor->i2c_handle), err, TAG, "Failed to add new I2C device");
assert(sensor->i2c_handle);

*handle_ret = sensor;
return ret;

err:
qma6100p_delete(sensor);
return ret;
}

void qma6100p_delete(qma6100p_handle_t sensor)
{
qma6100p_dev_t *sens = (qma6100p_dev_t *) sensor;
if (sens->i2c_handle) {
i2c_master_bus_rm_device(sens->i2c_handle);
}
if (sens->timer) {
free(sens->timer);
}
free(sens);
}

Expand Down
2 changes: 1 addition & 1 deletion components/qma6100p/test_apps/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## IDF Component Manager Manifest File
dependencies:
idf: ">=4.0"
idf: ">=5.2"
qma6100p:
version: "*"
override_path: "../../../qma6100p"
29 changes: 13 additions & 16 deletions components/qma6100p/test_apps/main/test_esp_acc_qma6100p.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include <stdio.h>
#include "unity.h"
#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "qma6100p.h"
#include "esp_system.h"
#include "esp_log.h"
Expand All @@ -21,25 +21,21 @@

static const char *TAG = "qma6100p test";
static qma6100p_handle_t qma6100p = NULL;
static i2c_master_bus_handle_t i2c_handle = NULL;

/**
* @brief i2c master initialization
*/
static void i2c_bus_init(void)
{
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = (gpio_num_t)I2C_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = (gpio_num_t)I2C_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
conf.clk_flags = I2C_SCLK_SRC_FLAG_FOR_NOMAL;

esp_err_t ret = i2c_param_config(I2C_MASTER_NUM, &conf);
TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, ret, "I2C config returned error");

ret = i2c_driver_install(I2C_MASTER_NUM, conf.mode, 0, 0, 0);
const i2c_master_bus_config_t bus_config = {
.i2c_port = I2C_MASTER_NUM,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.clk_source = I2C_CLK_SRC_DEFAULT,
};

esp_err_t ret = i2c_new_master_bus(&bus_config, &i2c_handle);
TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, ret, "I2C install returned error");
}

Expand All @@ -51,7 +47,8 @@ static void i2c_sensor_qma6100p_init(void)
esp_err_t ret;

i2c_bus_init();
qma6100p = qma6100p_create(I2C_MASTER_NUM, QMA6100P_I2C_ADDRESS);
ret = qma6100p_create(i2c_handle, QMA6100P_I2C_ADDRESS, &qma6100p);
TEST_ASSERT_EQUAL(ESP_OK, ret);
TEST_ASSERT_NOT_NULL_MESSAGE(qma6100p, "QMA6100P create returned NULL");

ret = qma6100p_wake_up(qma6100p);
Expand All @@ -75,7 +72,7 @@ TEST_CASE("Sensor qma6100p test", "[qma6100p][iot][sensor]")
ESP_LOGI(TAG, "acce_x:%.2f, acce_y:%.2f, acce_z:%.2f\n", acce.acce_x, acce.acce_y, acce.acce_z);

qma6100p_delete(qma6100p);
ret = i2c_driver_delete(I2C_MASTER_NUM);
ret = i2c_del_master_bus(i2c_handle);
TEST_ASSERT_EQUAL(ESP_OK, ret);
}

Expand Down

0 comments on commit 649e14a

Please sign in to comment.