refactor(i2c): clean up the i2ctool example

removed unused console cli.
removed unnecessary dependencies.
behaviour changed: user must run the i2cconfig command before others
updated pytest as well
This commit is contained in:
morris
2025-08-29 15:38:00 +08:00
parent 1275129a62
commit 57034c3bcf
10 changed files with 126 additions and 260 deletions

View File

@@ -1,16 +1,8 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* cmd_i2ctools.c
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "argtable3/argtable3.h"
@@ -18,88 +10,81 @@
#include "esp_console.h"
#include "esp_log.h"
static const char *TAG = "cmd_i2ctools";
static const char *TAG = "i2ctools";
#define I2C_TOOL_TIMEOUT_VALUE_MS (50)
static uint32_t i2c_frequency = 100 * 1000;
i2c_master_bus_handle_t tool_bus_handle;
#define I2C_TOOL_TIMEOUT_VALUE_MS 50
#define I2C_DEFAULT_FREQUENCY (100 * 1000) // use this safe value if the "--freq" is skipped in `i2cconfig` command
static esp_err_t i2c_get_port(int port, i2c_port_t *i2c_port)
{
if (port >= I2C_NUM_MAX) {
ESP_LOGE(TAG, "Wrong port number: %d", port);
return ESP_FAIL;
}
*i2c_port = port;
return ESP_OK;
}
static int s_i2c_bus_frequency;
static i2c_master_bus_handle_t s_i2c_bus;
static struct {
struct arg_int *port;
struct arg_int *freq;
struct arg_int *sda;
struct arg_int *scl;
struct arg_int *sda;
struct arg_int *freq;
struct arg_end *end;
} i2cconfig_args;
static int do_i2cconfig_cmd(int argc, char **argv)
{
esp_err_t err = ESP_OK;
int nerrors = arg_parse(argc, argv, (void **)&i2cconfig_args);
i2c_port_t i2c_port = I2C_NUM_0;
int i2c_gpio_sda = 0;
int i2c_gpio_scl = 0;
if (nerrors != 0) {
arg_print_errors(stderr, i2cconfig_args.end, argv[0]);
return 0;
return ESP_ERR_INVALID_ARG;
}
/* Check "--port" option */
if (i2cconfig_args.port->count) {
if (i2c_get_port(i2cconfig_args.port->ival[0], &i2c_port) != ESP_OK) {
return 1;
}
}
/* Check "--freq" option */
if (i2cconfig_args.freq->count) {
i2c_frequency = i2cconfig_args.freq->ival[0];
s_i2c_bus_frequency = i2cconfig_args.freq->ival[0];
} else {
s_i2c_bus_frequency = I2C_DEFAULT_FREQUENCY;
}
/* Check "--sda" option */
i2c_gpio_sda = i2cconfig_args.sda->ival[0];
int i2c_gpio_sda = i2cconfig_args.sda->ival[0];
/* Check "--scl" option */
i2c_gpio_scl = i2cconfig_args.scl->ival[0];
int i2c_gpio_scl = i2cconfig_args.scl->ival[0];
// re-init the bus
if (i2c_del_master_bus(tool_bus_handle) != ESP_OK) {
return 1;
// if the I2C bus is already initialized, delete it first
if (s_i2c_bus) {
err = i2c_del_master_bus(s_i2c_bus);
if (err != ESP_OK) {
// propagate the error
return err;
}
s_i2c_bus = NULL;
}
i2c_master_bus_config_t i2c_bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = i2c_port,
.i2c_port = -1, // select a free I2C port automatically
.scl_io_num = i2c_gpio_scl,
.sda_io_num = i2c_gpio_sda,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = true,
.flags = {
.enable_internal_pullup = true, // in case external pull-up resistors are not available, enable the internal weak pull-up
}
};
if (i2c_new_master_bus(&i2c_bus_config, &tool_bus_handle) != ESP_OK) {
return 1;
err = i2c_new_master_bus(&i2c_bus_config, &s_i2c_bus);
if (err != ESP_OK) {
// propagate the error
return err;
}
return 0;
return ESP_OK;
}
static void register_i2cconfig(void)
{
i2cconfig_args.port = arg_int0(NULL, "port", "<0|1>", "Set the I2C bus port number");
i2cconfig_args.freq = arg_int0(NULL, "freq", "<Hz>", "Set the frequency(Hz) of I2C bus");
i2cconfig_args.sda = arg_int1(NULL, "sda", "<gpio>", "Set the gpio for I2C SDA");
i2cconfig_args.scl = arg_int1(NULL, "scl", "<gpio>", "Set the gpio for I2C SCL");
i2cconfig_args.sda = arg_int1(NULL, "sda", "<gpio>", "Set the gpio for I2C SDA"); // mandatory
i2cconfig_args.scl = arg_int1(NULL, "scl", "<gpio>", "Set the gpio for I2C SCL"); // mandatory
i2cconfig_args.freq = arg_int0(NULL, "freq", "<Hz>", "Set the frequency(Hz) of I2C bus"); // optional
i2cconfig_args.end = arg_end(2);
const esp_console_cmd_t i2cconfig_cmd = {
.command = "i2cconfig",
.help = "Config I2C bus",
.hint = NULL,
.help = "Config I2C bus frequency and IOs",
.hint = NULL, // generate the hint from argtable automatically
.func = &do_i2cconfig_cmd,
.argtable = &i2cconfig_args
};
@@ -108,6 +93,10 @@ static void register_i2cconfig(void)
static int do_i2cdetect_cmd(int argc, char **argv)
{
if (!s_i2c_bus) {
ESP_LOGE(TAG, "I2C bus is not initialized. Please run 'i2cconfig' first");
return ESP_ERR_INVALID_STATE;
}
uint8_t address;
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
for (int i = 0; i < 128; i += 16) {
@@ -115,7 +104,7 @@ static int do_i2cdetect_cmd(int argc, char **argv)
for (int j = 0; j < 16; j++) {
fflush(stdout);
address = i + j;
esp_err_t ret = i2c_master_probe(tool_bus_handle, address, I2C_TOOL_TIMEOUT_VALUE_MS);
esp_err_t ret = i2c_master_probe(s_i2c_bus, address, I2C_TOOL_TIMEOUT_VALUE_MS);
if (ret == ESP_OK) {
printf("%02x ", address);
} else if (ret == ESP_ERR_TIMEOUT) {
@@ -127,7 +116,7 @@ static int do_i2cdetect_cmd(int argc, char **argv)
printf("\r\n");
}
return 0;
return ESP_OK;
}
static void register_i2cdetect(void)
@@ -151,10 +140,18 @@ static struct {
static int do_i2cget_cmd(int argc, char **argv)
{
i2c_master_dev_handle_t dev_handle = NULL;
esp_err_t err = ESP_OK;
int nerrors = arg_parse(argc, argv, (void **)&i2cget_args);
if (nerrors != 0) {
arg_print_errors(stderr, i2cget_args.end, argv[0]);
return 0;
return ESP_ERR_INVALID_ARG;
}
if (!s_i2c_bus) {
ESP_LOGE(TAG, "I2C bus is not initialized. Please run 'i2cconfig' first");
return ESP_ERR_INVALID_STATE;
}
/* Check chip address: "-c" option */
@@ -170,14 +167,18 @@ static int do_i2cget_cmd(int argc, char **argv)
len = i2cget_args.data_length->ival[0];
}
uint8_t *data = malloc(len);
if (!data) {
return ESP_ERR_NO_MEM;
}
i2c_device_config_t i2c_dev_conf = {
.scl_speed_hz = i2c_frequency,
.scl_speed_hz = s_i2c_bus_frequency,
.device_address = chip_addr,
};
i2c_master_dev_handle_t dev_handle;
if (i2c_master_bus_add_device(tool_bus_handle, &i2c_dev_conf, &dev_handle) != ESP_OK) {
return 1;
err = i2c_master_bus_add_device(s_i2c_bus, &i2c_dev_conf, &dev_handle);
if (err != ESP_OK) {
// propagate the error
return err;
}
esp_err_t ret = i2c_master_transmit_receive(dev_handle, (uint8_t*)&data_addr, 1, data, len, I2C_TOOL_TIMEOUT_VALUE_MS);
@@ -197,10 +198,13 @@ static int do_i2cget_cmd(int argc, char **argv)
ESP_LOGW(TAG, "Read failed");
}
free(data);
if (i2c_master_bus_rm_device(dev_handle) != ESP_OK) {
return 1;
err = i2c_master_bus_rm_device(dev_handle);
if (err != ESP_OK) {
// propagate the error
return err;
}
return 0;
return ESP_OK;
}
static void register_i2cget(void)
@@ -228,10 +232,18 @@ static struct {
static int do_i2cset_cmd(int argc, char **argv)
{
i2c_master_dev_handle_t dev_handle = NULL;
esp_err_t err = ESP_OK;
int nerrors = arg_parse(argc, argv, (void **)&i2cset_args);
if (nerrors != 0) {
arg_print_errors(stderr, i2cset_args.end, argv[0]);
return 0;
return ESP_ERR_INVALID_ARG;
}
if (!s_i2c_bus) {
ESP_LOGE(TAG, "I2C bus is not initialized. Please run 'i2cconfig' first");
return ESP_ERR_INVALID_STATE;
}
/* Check chip address: "-c" option */
@@ -245,15 +257,19 @@ static int do_i2cset_cmd(int argc, char **argv)
int len = i2cset_args.data->count;
i2c_device_config_t i2c_dev_conf = {
.scl_speed_hz = i2c_frequency,
.scl_speed_hz = s_i2c_bus_frequency,
.device_address = chip_addr,
};
i2c_master_dev_handle_t dev_handle;
if (i2c_master_bus_add_device(tool_bus_handle, &i2c_dev_conf, &dev_handle) != ESP_OK) {
return 1;
err = i2c_master_bus_add_device(s_i2c_bus, &i2c_dev_conf, &dev_handle);
if (err != ESP_OK) {
return err;
}
uint8_t *data = malloc(len + 1);
if (!data) {
return ESP_ERR_NO_MEM;
}
data[0] = data_addr;
for (int i = 0; i < len; i++) {
data[i + 1] = i2cset_args.data->ival[i];
@@ -268,10 +284,11 @@ static int do_i2cset_cmd(int argc, char **argv)
}
free(data);
if (i2c_master_bus_rm_device(dev_handle) != ESP_OK) {
return 1;
err = i2c_master_bus_rm_device(dev_handle);
if (err != ESP_OK) {
return err;
}
return 0;
return ESP_OK;
}
static void register_i2cset(void)
@@ -298,10 +315,13 @@ static struct {
static int do_i2cdump_cmd(int argc, char **argv)
{
i2c_master_dev_handle_t dev_handle = NULL;
esp_err_t err = ESP_OK;
int nerrors = arg_parse(argc, argv, (void **)&i2cdump_args);
if (nerrors != 0) {
arg_print_errors(stderr, i2cdump_args.end, argv[0]);
return 0;
return ESP_ERR_INVALID_ARG;
}
/* Check chip address: "-c" option */
@@ -313,16 +333,21 @@ static int do_i2cdump_cmd(int argc, char **argv)
}
if (size != 1 && size != 2 && size != 4) {
ESP_LOGE(TAG, "Wrong read size. Only support 1,2,4");
return 1;
return ESP_ERR_INVALID_ARG;
}
if (!s_i2c_bus) {
ESP_LOGE(TAG, "I2C bus is not initialized. Please run 'i2cconfig' first");
return ESP_ERR_INVALID_STATE;
}
i2c_device_config_t i2c_dev_conf = {
.scl_speed_hz = i2c_frequency,
.scl_speed_hz = s_i2c_bus_frequency,
.device_address = chip_addr,
};
i2c_master_dev_handle_t dev_handle;
if (i2c_master_bus_add_device(tool_bus_handle, &i2c_dev_conf, &dev_handle) != ESP_OK) {
return 1;
err = i2c_master_bus_add_device(s_i2c_bus, &i2c_dev_conf, &dev_handle);
if (err != ESP_OK) {
return err;
}
uint8_t data_addr;
@@ -363,10 +388,12 @@ static int do_i2cdump_cmd(int argc, char **argv)
}
printf("\r\n");
}
if (i2c_master_bus_rm_device(dev_handle) != ESP_OK) {
return 1;
err = i2c_master_bus_rm_device(dev_handle);
if (err != ESP_OK) {
return err;
}
return 0;
return ESP_OK;
}
static void register_i2cdump(void)