mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-03 02:20:57 +02:00
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:
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
[I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) is a simple but very useful tool for developing I2C related applications, which is also famous in Linux platform. This example just implements some of basic features of [I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) based on [esp32 console component](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/console.html). As follows, this example supports five command-line tools:
|
[I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) is a simple but very useful tool for developing I2C related applications, which is also famous in Linux platform. This example just implements some of basic features of [I2C Tools](https://i2c.wiki.kernel.org/index.php/I2C_Tools) based on [esp32 console component](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/console.html). As follows, this example supports five command-line tools:
|
||||||
|
|
||||||
1. `i2cconfig`: It will configure the I2C bus with specific GPIO number, port number and frequency.
|
1. `i2cconfig`: It will configure the I2C bus with specific GPIO number and frequency.
|
||||||
2. `i2cdetect`: It will scan an I2C bus for devices and output a table with the list of detected devices on the bus.
|
2. `i2cdetect`: It will scan an I2C bus for devices and output a table with the list of detected devices on the bus.
|
||||||
3. `i2cget`: It will read registers visible through the I2C bus.
|
3. `i2cget`: It will read registers visible through the I2C bus.
|
||||||
4. `i2cset`: It will set registers visible through the I2C bus.
|
4. `i2cset`: It will set registers visible through the I2C bus.
|
||||||
@@ -25,26 +25,9 @@ To run this example, you should have any ESP32, ESP32-S, ESP32-C, ESP32-H, ESP32
|
|||||||
|
|
||||||
#### Pin Assignment:
|
#### Pin Assignment:
|
||||||
|
|
||||||
**Note:** The following pin assignments are used by default according to `CONFIG_I2C_MASTER_SCL` and `CONFIG_I2C_MASTER_SDA` , you can change them with `i2cconfig` command at any time.
|
**Note:** You must run the `i2cconfig` command first to setup the I2C bus with proper GPIOs.
|
||||||
|
|
||||||
| | SDA | SCL | GND | Other | VCC |
|
|
||||||
| ------------------- | ------ | ------ | ---- | ----- | ---- |
|
|
||||||
| ESP32 I2C Master | GPIO18 | GPIO19 | GND | GND | 3.3V |
|
|
||||||
| ESP32-S2 I2C Master | GPIO5 | GPIO4 | GND | GND | 3.3V |
|
|
||||||
| ESP32-S3 I2C Master | GPIO5 | GPIO4 | GND | GND | 3.3V |
|
|
||||||
| ESP32-C3 I2C Master | GPIO5 | GPIO4 | GND | GND | 3.3V |
|
|
||||||
| ESP32-C2 I2C Master | GPIO5 | GPIO4 | GND | GND | 3.3V |
|
|
||||||
| ESP32-H2 I2C Master | GPIO5 | GPIO4 | GND | GND | 3.3V |
|
|
||||||
| Sensor | SDA | SCL | GND | WAK | VCC |
|
|
||||||
|
|
||||||
**Note:** It is recommended to add external pull-up resistors for SDA/SCL pins to make the communication more stable, though the driver will enable internal pull-up resistors.
|
**Note:** It is recommended to add external pull-up resistors for SDA/SCL pins to make the communication more stable, though the driver will enable internal pull-up resistors.
|
||||||
|
|
||||||
### Configure the project
|
|
||||||
|
|
||||||
Open the project configuration menu (`idf.py menuconfig`). Then go into `Example Configuration` menu.
|
|
||||||
|
|
||||||
- You can choose whether or not to save command history into flash in `Store command history in flash` option.
|
|
||||||
|
|
||||||
### Build and Flash
|
### Build and Flash
|
||||||
|
|
||||||
Run `idf.py -p PORT flash monitor` to build and flash the project..
|
Run `idf.py -p PORT flash monitor` to build and flash the project..
|
||||||
@@ -58,33 +41,21 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l
|
|||||||
### Check all supported commands and their usages
|
### Check all supported commands and their usages
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
==============================================================
|
|
||||||
| Steps to Use i2c-tools |
|
|
||||||
| |
|
|
||||||
| 1. Try 'help', check all supported commands |
|
|
||||||
| 2. Try 'i2cconfig' to configure your I2C bus |
|
|
||||||
| 3. Try 'i2cdetect' to scan devices on the bus |
|
|
||||||
| 4. Try 'i2cget' to get the content of specific register |
|
|
||||||
| 5. Try 'i2cset' to set the value of specific register |
|
|
||||||
| 6. Try 'i2cdump' to dump all the register (Experiment) |
|
|
||||||
| |
|
|
||||||
==============================================================
|
|
||||||
|
|
||||||
|
|
||||||
Type 'help' to get the list of commands.
|
Type 'help' to get the list of commands.
|
||||||
Use UP/DOWN arrows to navigate through command history.
|
Use UP/DOWN arrows to navigate through command history.
|
||||||
Press TAB when typing command name to auto-complete.
|
Press TAB when typing command name to auto-complete.
|
||||||
I (379) main_task: Returned from app_main()
|
|
||||||
i2c-tools> help
|
i2c-tools> help
|
||||||
help
|
help [<string>] [-v <0|1>]
|
||||||
Print the list of registered commands
|
Print the summary of all registered commands if no arguments are given,
|
||||||
|
otherwise print summary of given command.
|
||||||
|
<string> Name of command
|
||||||
|
-v, --verbose=<0|1> If specified, list console commands with given verbose level
|
||||||
|
|
||||||
i2cconfig [--port=<0|1>] [--freq=<Hz>] --sda=<gpio> --scl=<gpio>
|
i2cconfig --scl=<gpio> --sda=<gpio> [--freq=<Hz>]
|
||||||
Config I2C bus
|
Config I2C bus frequency and IOs
|
||||||
--port=<0|1> Set the I2C bus port number
|
|
||||||
--freq=<Hz> Set the frequency(Hz) of I2C bus
|
|
||||||
--sda=<gpio> Set the gpio for I2C SDA
|
|
||||||
--scl=<gpio> Set the gpio for I2C SCL
|
--scl=<gpio> Set the gpio for I2C SCL
|
||||||
|
--sda=<gpio> Set the gpio for I2C SDA
|
||||||
|
--freq=<Hz> Set the frequency(Hz) of I2C bus
|
||||||
|
|
||||||
i2cdetect
|
i2cdetect
|
||||||
Scan I2C bus for devices
|
Scan I2C bus for devices
|
||||||
@@ -105,46 +76,17 @@ i2cdump -c <chip_addr> [-s <size>]
|
|||||||
Examine registers visible through the I2C bus
|
Examine registers visible through the I2C bus
|
||||||
-c, --chip=<chip_addr> Specify the address of the chip on that bus
|
-c, --chip=<chip_addr> Specify the address of the chip on that bus
|
||||||
-s, --size=<size> Specify the size of each read
|
-s, --size=<size> Specify the size of each read
|
||||||
|
|
||||||
free
|
|
||||||
Get the current size of free heap memory
|
|
||||||
|
|
||||||
heap
|
|
||||||
Get minimum size of free heap memory that was available during program execu
|
|
||||||
tion
|
|
||||||
|
|
||||||
version
|
|
||||||
Get version of chip and SDK
|
|
||||||
|
|
||||||
restart
|
|
||||||
Software reset of the chip
|
|
||||||
|
|
||||||
deep_sleep [-t <t>] [--io=<n>] [--io_level=<0|1>]
|
|
||||||
Enter deep sleep mode. Two wakeup modes are supported: timer and GPIO. If no
|
|
||||||
wakeup option is specified, will sleep indefinitely.
|
|
||||||
-t, --time=<t> Wake up time, ms
|
|
||||||
--io=<n> If specified, wakeup using GPIO with given number
|
|
||||||
--io_level=<0|1> GPIO level to trigger wakeup
|
|
||||||
|
|
||||||
light_sleep [-t <t>] [--io=<n>]... [--io_level=<0|1>]...
|
|
||||||
Enter light sleep mode. Two wakeup modes are supported: timer and GPIO. Mult
|
|
||||||
iple GPIO pins can be specified using pairs of 'io' and 'io_level' arguments
|
|
||||||
. Will also wake up on UART input.
|
|
||||||
-t, --time=<t> Wake up time, ms
|
|
||||||
--io=<n> If specified, wakeup using GPIO with given number
|
|
||||||
--io_level=<0|1> GPIO level to trigger wakeup
|
|
||||||
|
|
||||||
tasks
|
|
||||||
Get information about running tasks
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configure the I2C bus
|
### Configure the I2C bus
|
||||||
|
|
||||||
|
> [!IMPORTANT]
|
||||||
|
> You must run the `i2cconfig` command before using other I2C commands.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
i2c-tools> i2cconfig --port=0 --sda=18 --scl=19 --freq=100000
|
i2c-tools> i2cconfig --sda=18 --scl=19 --freq=100000
|
||||||
```
|
```
|
||||||
|
|
||||||
* `--port` option to specify the port of I2C, here we choose port 0 for test.
|
|
||||||
* `--sda` and `--scl` options to specify the gpio number used by I2C bus, here we choose GPIO18 as the SDA and GPIO19 as the SCL.
|
* `--sda` and `--scl` options to specify the gpio number used by I2C bus, here we choose GPIO18 as the SDA and GPIO19 as the SCL.
|
||||||
* `--freq` option to specify the frequency of I2C bus, here we set to 100KHz.
|
* `--freq` option to specify the frequency of I2C bus, here we set to 100KHz.
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
idf_component_register(SRCS "i2ctools_example_main.c"
|
idf_component_register(SRCS "i2ctools_example_main.c"
|
||||||
"cmd_i2ctools.c"
|
"cmd_i2ctools.c"
|
||||||
PRIV_REQUIRES fatfs esp_driver_i2c
|
PRIV_REQUIRES esp_driver_i2c console
|
||||||
INCLUDE_DIRS ".")
|
INCLUDE_DIRS ".")
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
menu "Example Configuration"
|
|
||||||
|
|
||||||
config EXAMPLE_STORE_HISTORY
|
|
||||||
bool "Store command history in flash"
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
Linenoise line editing library provides functions to save and load
|
|
||||||
command history. If this option is enabled, initializes a FAT filesystem
|
|
||||||
and uses it to store command history.
|
|
||||||
|
|
||||||
config EXAMPLE_I2C_MASTER_SCL
|
|
||||||
int "SCL GPIO Num"
|
|
||||||
default 19 if IDF_TARGET_ESP32
|
|
||||||
default 4
|
|
||||||
help
|
|
||||||
GPIO number for I2C Master clock line.
|
|
||||||
|
|
||||||
config EXAMPLE_I2C_MASTER_SDA
|
|
||||||
int "SDA GPIO Num"
|
|
||||||
default 18 if IDF_TARGET_ESP32
|
|
||||||
default 5
|
|
||||||
help
|
|
||||||
GPIO number for I2C Master data line.
|
|
||||||
|
|
||||||
endmenu
|
|
@@ -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
|
* 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 <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "argtable3/argtable3.h"
|
#include "argtable3/argtable3.h"
|
||||||
@@ -18,88 +10,81 @@
|
|||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
|
|
||||||
static const char *TAG = "cmd_i2ctools";
|
static const char *TAG = "i2ctools";
|
||||||
|
|
||||||
#define I2C_TOOL_TIMEOUT_VALUE_MS (50)
|
#define I2C_TOOL_TIMEOUT_VALUE_MS 50
|
||||||
static uint32_t i2c_frequency = 100 * 1000;
|
#define I2C_DEFAULT_FREQUENCY (100 * 1000) // use this safe value if the "--freq" is skipped in `i2cconfig` command
|
||||||
i2c_master_bus_handle_t tool_bus_handle;
|
|
||||||
|
|
||||||
static esp_err_t i2c_get_port(int port, i2c_port_t *i2c_port)
|
static int s_i2c_bus_frequency;
|
||||||
{
|
static i2c_master_bus_handle_t s_i2c_bus;
|
||||||
if (port >= I2C_NUM_MAX) {
|
|
||||||
ESP_LOGE(TAG, "Wrong port number: %d", port);
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
*i2c_port = port;
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
struct arg_int *port;
|
|
||||||
struct arg_int *freq;
|
|
||||||
struct arg_int *sda;
|
|
||||||
struct arg_int *scl;
|
struct arg_int *scl;
|
||||||
|
struct arg_int *sda;
|
||||||
|
struct arg_int *freq;
|
||||||
struct arg_end *end;
|
struct arg_end *end;
|
||||||
} i2cconfig_args;
|
} i2cconfig_args;
|
||||||
|
|
||||||
static int do_i2cconfig_cmd(int argc, char **argv)
|
static int do_i2cconfig_cmd(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
int nerrors = arg_parse(argc, argv, (void **)&i2cconfig_args);
|
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) {
|
if (nerrors != 0) {
|
||||||
arg_print_errors(stderr, i2cconfig_args.end, argv[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 */
|
/* Check "--freq" option */
|
||||||
if (i2cconfig_args.freq->count) {
|
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 */
|
/* Check "--sda" option */
|
||||||
i2c_gpio_sda = i2cconfig_args.sda->ival[0];
|
int i2c_gpio_sda = i2cconfig_args.sda->ival[0];
|
||||||
/* Check "--scl" option */
|
/* 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 the I2C bus is already initialized, delete it first
|
||||||
if (i2c_del_master_bus(tool_bus_handle) != ESP_OK) {
|
if (s_i2c_bus) {
|
||||||
return 1;
|
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 = {
|
i2c_master_bus_config_t i2c_bus_config = {
|
||||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
.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,
|
.scl_io_num = i2c_gpio_scl,
|
||||||
.sda_io_num = i2c_gpio_sda,
|
.sda_io_num = i2c_gpio_sda,
|
||||||
.glitch_ignore_cnt = 7,
|
.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) {
|
err = i2c_new_master_bus(&i2c_bus_config, &s_i2c_bus);
|
||||||
return 1;
|
if (err != ESP_OK) {
|
||||||
|
// propagate the error
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_i2cconfig(void)
|
static void register_i2cconfig(void)
|
||||||
{
|
{
|
||||||
i2cconfig_args.port = arg_int0(NULL, "port", "<0|1>", "Set the I2C bus port number");
|
i2cconfig_args.sda = arg_int1(NULL, "sda", "<gpio>", "Set the gpio for I2C SDA"); // mandatory
|
||||||
i2cconfig_args.freq = arg_int0(NULL, "freq", "<Hz>", "Set the frequency(Hz) of I2C bus");
|
i2cconfig_args.scl = arg_int1(NULL, "scl", "<gpio>", "Set the gpio for I2C SCL"); // mandatory
|
||||||
i2cconfig_args.sda = arg_int1(NULL, "sda", "<gpio>", "Set the gpio for I2C SDA");
|
i2cconfig_args.freq = arg_int0(NULL, "freq", "<Hz>", "Set the frequency(Hz) of I2C bus"); // optional
|
||||||
i2cconfig_args.scl = arg_int1(NULL, "scl", "<gpio>", "Set the gpio for I2C SCL");
|
|
||||||
i2cconfig_args.end = arg_end(2);
|
i2cconfig_args.end = arg_end(2);
|
||||||
const esp_console_cmd_t i2cconfig_cmd = {
|
const esp_console_cmd_t i2cconfig_cmd = {
|
||||||
.command = "i2cconfig",
|
.command = "i2cconfig",
|
||||||
.help = "Config I2C bus",
|
.help = "Config I2C bus frequency and IOs",
|
||||||
.hint = NULL,
|
.hint = NULL, // generate the hint from argtable automatically
|
||||||
.func = &do_i2cconfig_cmd,
|
.func = &do_i2cconfig_cmd,
|
||||||
.argtable = &i2cconfig_args
|
.argtable = &i2cconfig_args
|
||||||
};
|
};
|
||||||
@@ -108,6 +93,10 @@ static void register_i2cconfig(void)
|
|||||||
|
|
||||||
static int do_i2cdetect_cmd(int argc, char **argv)
|
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;
|
uint8_t address;
|
||||||
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\r\n");
|
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) {
|
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++) {
|
for (int j = 0; j < 16; j++) {
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
address = i + j;
|
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) {
|
if (ret == ESP_OK) {
|
||||||
printf("%02x ", address);
|
printf("%02x ", address);
|
||||||
} else if (ret == ESP_ERR_TIMEOUT) {
|
} else if (ret == ESP_ERR_TIMEOUT) {
|
||||||
@@ -127,7 +116,7 @@ static int do_i2cdetect_cmd(int argc, char **argv)
|
|||||||
printf("\r\n");
|
printf("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_i2cdetect(void)
|
static void register_i2cdetect(void)
|
||||||
@@ -151,10 +140,18 @@ static struct {
|
|||||||
|
|
||||||
static int do_i2cget_cmd(int argc, char **argv)
|
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);
|
int nerrors = arg_parse(argc, argv, (void **)&i2cget_args);
|
||||||
if (nerrors != 0) {
|
if (nerrors != 0) {
|
||||||
arg_print_errors(stderr, i2cget_args.end, argv[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 */
|
/* 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];
|
len = i2cget_args.data_length->ival[0];
|
||||||
}
|
}
|
||||||
uint8_t *data = malloc(len);
|
uint8_t *data = malloc(len);
|
||||||
|
if (!data) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
i2c_device_config_t i2c_dev_conf = {
|
i2c_device_config_t i2c_dev_conf = {
|
||||||
.scl_speed_hz = i2c_frequency,
|
.scl_speed_hz = s_i2c_bus_frequency,
|
||||||
.device_address = chip_addr,
|
.device_address = chip_addr,
|
||||||
};
|
};
|
||||||
i2c_master_dev_handle_t dev_handle;
|
err = i2c_master_bus_add_device(s_i2c_bus, &i2c_dev_conf, &dev_handle);
|
||||||
if (i2c_master_bus_add_device(tool_bus_handle, &i2c_dev_conf, &dev_handle) != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return 1;
|
// 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);
|
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");
|
ESP_LOGW(TAG, "Read failed");
|
||||||
}
|
}
|
||||||
free(data);
|
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)
|
static void register_i2cget(void)
|
||||||
@@ -228,10 +232,18 @@ static struct {
|
|||||||
|
|
||||||
static int do_i2cset_cmd(int argc, char **argv)
|
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);
|
int nerrors = arg_parse(argc, argv, (void **)&i2cset_args);
|
||||||
if (nerrors != 0) {
|
if (nerrors != 0) {
|
||||||
arg_print_errors(stderr, i2cset_args.end, argv[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 */
|
/* Check chip address: "-c" option */
|
||||||
@@ -245,15 +257,19 @@ static int do_i2cset_cmd(int argc, char **argv)
|
|||||||
int len = i2cset_args.data->count;
|
int len = i2cset_args.data->count;
|
||||||
|
|
||||||
i2c_device_config_t i2c_dev_conf = {
|
i2c_device_config_t i2c_dev_conf = {
|
||||||
.scl_speed_hz = i2c_frequency,
|
.scl_speed_hz = s_i2c_bus_frequency,
|
||||||
.device_address = chip_addr,
|
.device_address = chip_addr,
|
||||||
};
|
};
|
||||||
i2c_master_dev_handle_t dev_handle;
|
err = i2c_master_bus_add_device(s_i2c_bus, &i2c_dev_conf, &dev_handle);
|
||||||
if (i2c_master_bus_add_device(tool_bus_handle, &i2c_dev_conf, &dev_handle) != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return 1;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *data = malloc(len + 1);
|
uint8_t *data = malloc(len + 1);
|
||||||
|
if (!data) {
|
||||||
|
return ESP_ERR_NO_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
data[0] = data_addr;
|
data[0] = data_addr;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
data[i + 1] = i2cset_args.data->ival[i];
|
data[i + 1] = i2cset_args.data->ival[i];
|
||||||
@@ -268,10 +284,11 @@ static int do_i2cset_cmd(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
if (i2c_master_bus_rm_device(dev_handle) != ESP_OK) {
|
err = i2c_master_bus_rm_device(dev_handle);
|
||||||
return 1;
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
return 0;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void register_i2cset(void)
|
static void register_i2cset(void)
|
||||||
@@ -298,10 +315,13 @@ static struct {
|
|||||||
|
|
||||||
static int do_i2cdump_cmd(int argc, char **argv)
|
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);
|
int nerrors = arg_parse(argc, argv, (void **)&i2cdump_args);
|
||||||
if (nerrors != 0) {
|
if (nerrors != 0) {
|
||||||
arg_print_errors(stderr, i2cdump_args.end, argv[0]);
|
arg_print_errors(stderr, i2cdump_args.end, argv[0]);
|
||||||
return 0;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check chip address: "-c" option */
|
/* 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) {
|
if (size != 1 && size != 2 && size != 4) {
|
||||||
ESP_LOGE(TAG, "Wrong read size. Only support 1,2,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 = {
|
i2c_device_config_t i2c_dev_conf = {
|
||||||
.scl_speed_hz = i2c_frequency,
|
.scl_speed_hz = s_i2c_bus_frequency,
|
||||||
.device_address = chip_addr,
|
.device_address = chip_addr,
|
||||||
};
|
};
|
||||||
i2c_master_dev_handle_t dev_handle;
|
err = i2c_master_bus_add_device(s_i2c_bus, &i2c_dev_conf, &dev_handle);
|
||||||
if (i2c_master_bus_add_device(tool_bus_handle, &i2c_dev_conf, &dev_handle) != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return 1;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t data_addr;
|
uint8_t data_addr;
|
||||||
@@ -363,10 +388,12 @@ static int do_i2cdump_cmd(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
printf("\r\n");
|
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)
|
static void register_i2cdump(void)
|
||||||
|
@@ -1,21 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "driver/i2c_master.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void register_i2ctools(void);
|
void register_i2ctools(void);
|
||||||
|
|
||||||
extern i2c_master_bus_handle_t tool_bus_handle;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -9,47 +9,12 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_console.h"
|
#include "esp_console.h"
|
||||||
#include "esp_vfs_fat.h"
|
|
||||||
#include "cmd_system.h"
|
|
||||||
#include "cmd_i2ctools.h"
|
#include "cmd_i2ctools.h"
|
||||||
#include "driver/i2c_master.h"
|
|
||||||
|
|
||||||
static const char *TAG = "i2c-tools";
|
|
||||||
|
|
||||||
static gpio_num_t i2c_gpio_sda = CONFIG_EXAMPLE_I2C_MASTER_SDA;
|
|
||||||
static gpio_num_t i2c_gpio_scl = CONFIG_EXAMPLE_I2C_MASTER_SCL;
|
|
||||||
|
|
||||||
static i2c_port_t i2c_port = I2C_NUM_0;
|
|
||||||
|
|
||||||
#if CONFIG_EXAMPLE_STORE_HISTORY
|
|
||||||
|
|
||||||
#define MOUNT_PATH "/data"
|
|
||||||
#define HISTORY_PATH MOUNT_PATH "/history.txt"
|
|
||||||
|
|
||||||
static void initialize_filesystem(void)
|
|
||||||
{
|
|
||||||
static wl_handle_t wl_handle;
|
|
||||||
const esp_vfs_fat_mount_config_t mount_config = {
|
|
||||||
.max_files = 4,
|
|
||||||
.format_if_mount_failed = true
|
|
||||||
};
|
|
||||||
esp_err_t err = esp_vfs_fat_spiflash_mount_rw_wl(MOUNT_PATH, "storage", &mount_config, &wl_handle);
|
|
||||||
if (err != ESP_OK) {
|
|
||||||
ESP_LOGE(TAG, "Failed to mount FATFS (%s)", esp_err_to_name(err));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // CONFIG_EXAMPLE_STORE_HISTORY
|
|
||||||
|
|
||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
esp_console_repl_t *repl = NULL;
|
esp_console_repl_t *repl = NULL;
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
|
||||||
#if CONFIG_EXAMPLE_STORE_HISTORY
|
|
||||||
initialize_filesystem();
|
|
||||||
repl_config.history_save_path = HISTORY_PATH;
|
|
||||||
#endif
|
|
||||||
repl_config.prompt = "i2c-tools>";
|
repl_config.prompt = "i2c-tools>";
|
||||||
|
|
||||||
// install console REPL environment
|
// install console REPL environment
|
||||||
@@ -64,17 +29,6 @@ void app_main(void)
|
|||||||
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
|
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i2c_master_bus_config_t i2c_bus_config = {
|
|
||||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
|
||||||
.i2c_port = i2c_port,
|
|
||||||
.scl_io_num = i2c_gpio_scl,
|
|
||||||
.sda_io_num = i2c_gpio_sda,
|
|
||||||
.glitch_ignore_cnt = 7,
|
|
||||||
.flags.enable_internal_pullup = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &tool_bus_handle));
|
|
||||||
|
|
||||||
register_i2ctools();
|
register_i2ctools();
|
||||||
|
|
||||||
printf("\n ==============================================================\n");
|
printf("\n ==============================================================\n");
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
cmd_system:
|
|
||||||
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_system
|
|
||||||
cmd_nvs:
|
|
||||||
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_nvs
|
|
||||||
cmd_wifi:
|
|
||||||
path: ${IDF_PATH}/examples/system/console/advanced/components/cmd_wifi
|
|
@@ -1,6 +0,0 @@
|
|||||||
# Name, Type, SubType, Offset, Size, Flags
|
|
||||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
|
||||||
nvs, data, nvs, 0x9000, 0x6000,
|
|
||||||
phy_init, data, phy, 0xf000, 0x1000,
|
|
||||||
factory, app, factory, 0x10000, 1M,
|
|
||||||
storage, data, fat, , 528K,
|
|
|
@@ -11,6 +11,8 @@ EXPECT_TIMEOUT = 20
|
|||||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||||
def test_i2ctools_example(dut: IdfDut) -> None:
|
def test_i2ctools_example(dut: IdfDut) -> None:
|
||||||
dut.expect_exact('i2c-tools>', timeout=EXPECT_TIMEOUT)
|
dut.expect_exact('i2c-tools>', timeout=EXPECT_TIMEOUT)
|
||||||
|
# Configure the I2C bus
|
||||||
|
dut.write('i2cconfig --scl 19 --sda 18')
|
||||||
# Get i2c address
|
# Get i2c address
|
||||||
dut.write('i2cdetect')
|
dut.write('i2cdetect')
|
||||||
dut.expect_exact('5b', timeout=EXPECT_TIMEOUT)
|
dut.expect_exact('5b', timeout=EXPECT_TIMEOUT)
|
||||||
|
@@ -1,17 +0,0 @@
|
|||||||
# Reduce bootloader log verbosity
|
|
||||||
CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y
|
|
||||||
CONFIG_BOOTLOADER_LOG_LEVEL=2
|
|
||||||
|
|
||||||
# Increase main task stack size
|
|
||||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=7168
|
|
||||||
|
|
||||||
# Enable filesystem
|
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
|
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"
|
|
||||||
|
|
||||||
# Enable FreeRTOS stats formatting functions, needed for 'tasks' command
|
|
||||||
CONFIG_FREERTOS_USE_TRACE_FACILITY=y
|
|
||||||
CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y
|
|
||||||
|
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
|
|
Reference in New Issue
Block a user