I2C Tools Example
Note
This document is automatically translated using AI. Please excuse any detailed errors. The official English version is still in progress.
Example Description
This example demonstrates how to initialize and configure the I2C interface, and operate the I2C bus through Console REPL: send commands to the simulated slave in the command line environment, such as reading the value of a specified register, to verify the correctness of I2C bus communication and peripheral interaction.
The example consists of two files:
i2ctools_example_main.c
: Contains the example entry, used to initialize the I2C bus, start Console REPL, etc.
cmd_i2ctools
: Contains command registration, used to implement specific I2C command operations, including reading and writing simulated slave registers.
Console REPL
Console REPL (Read–Eval–Print Loop) is a real-time interactive debugging and control interface for embedded systems, which can execute input commands in real time and return results. In the ESP-IDF example, the professional features of Console REPL include:
Interactive execution: Allows users to enter commands in the terminal, and the system parses and executes them in real time.
Real-time feedback: The command execution results are output in real time, which is convenient for developers to observe the peripheral status and debug the program.
Extendable command registration: Supports registering custom command interfaces, such as I2C, SPI, GPIO operation commands, to achieve flexible control of hardware peripherals.
Hardware verification and debugging: Provides a means to directly access peripheral registers and bus interfaces, which is convenient for quickly verifying hardware connections and function implementation.
However, it should be noted that command line operations will not automatically recognize device types or register meanings, and users need to confirm register addresses and data formats themselves. For more information, refer to Console Terminal.
Running Method
The complete code of the example can be found in I2C Tools Example. The configuration instructions before running, corresponding GPIO pins, related commands, and build and burn processes can be found in the README.md file in the example directory.
If you need to customize the FAT file system mount path, you can view the Macro Definition/Global Variable Description section and modify the relevant definitions.
Header File Description
The header files used in this example cover system tools, file systems, command line parsing, I2C drivers, and log recording modules, providing support for console tool development, command parsing, I2C communication, and file operations.
The header files are classified by function as follows:
System Tools: Provide standard input and output, string processing, memory management, configuration macro support, FAT file system operation, and log printing functions.
#include <stdio.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_vfs_fat.h"
#include "esp_log.h"
Note
sdkconfig.h
is used to read the configuration macros generated by the build system, and is only used in thei2ctools_example_main.c
file.esp_vfs_fat.h
provides FAT file system mount and file operation interfaces, and is only used in thei2ctools_example_main.c
file.
Command Line Parsing and Console: Provide command parsing, registration, and interactive console functions.
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "cmd_system.h"
#include "cmd_i2ctools.h"
Note
argtable3/argtable3.h
is used to provide command line argument parsing functionality, only used in thecmd_i2ctools.c
file.cmd_system.h
is used to encapsulate system command registration, only used in thei2ctools_example_main.c
file.cmd_i2ctools.h
is used to encapsulate I2C tool command registration, only used in thei2ctools_example_main.c
file.
I2C Driver: Provides initialization, read/write operations, and resource release functionality in I2C master mode.
#include "driver/i2c_master.h"
Macro Definition/Global Variable Description
The macro definitions and global variables in this example are mainly used to configure the pins, port number, communication frequency, and timeout time of the I2C master, and provide a bus handle for subsequent read/write operations.
They are categorized by function as follows:
I2C Master Configuration: Defined in
i2ctools_example_main.c
Use configuration macros to define the GPIO pin numbers used by the I2C clock line (SCL) and data line (SDA). In the example, the clock line corresponds to GPIO 4; the data line corresponds to GPIO 5.
static gpio_num_t i2c_gpio_sda = CONFIG_EXAMPLE_I2C_MASTER_SDA; static gpio_num_t i2c_gpio_scl = CONFIG_EXAMPLE_I2C_MASTER_SCL;
Define the port number used by I2C, this example uses
I2C_NUM_0
, i.e., I2C0 hardware peripheral.static i2c_port_t i2c_port = I2C_NUM_0;
History Record Storage: Defined in
i2ctools_example_main.c
When the
CONFIG_EXAMPLE_STORE_HISTORY
configuration item is enabled, the example will mount the file system and save the command history to a specified file.#if CONFIG_EXAMPLE_STORE_HISTORY #define MOUNT_PATH "/data" // Mount path #define HISTORY_PATH MOUNT_PATH "/history.txt" // History record file path
I2C Communication Parameters: Defined in
cmd_i2ctools.c
Define the timeout time (ms) for I2C operations. If the operation is not completed within the specified time, a timeout error is returned.
#define I2C_TOOL_TIMEOUT_VALUE_MS (50)
Define the I2C communication frequency, set to 100 kHz in the example.
static uint32_t i2c_frequency = 100 * 1000;
I2C Bus Handle: Defined in
cmd_i2ctools.c
Define the I2C master bus handle, used to save the valid handle returned after successfully creating the bus, for subsequent operations.
i2c_master_bus_handle_t tool_bus_handle;
Note
Configuration macros start with
CONFIG_
, which are automatically generated by the ESP-IDF build system based on themenuconfig
settings and saved in thesdkconfig
file.When defining GPIO pins, use configuration macros instead of directly writing pin numbers, which allows for flexible modification of pins at compile time without modifying the source code, facilitating project expansion and management.
If you want to modify the pins used, just modify the
menuconfig
and rebuild/compile the example, and it will automatically update, no need to manually change the code.
Task Function Description
In order to interact and debug with I2C bus devices through the command line, this example mainly includes command registration and implementation and auxiliary initialization functions.
Note
The following functions are all defined in cmd_i2ctools.c
, used to implement specific I2C operation commands (such as configuring I2C, scanning devices, reading registers, writing registers, dumping registers, etc.) and registered to the console. Users can directly execute these operations through the command line.
Command Registration and Implementation
Command registration function: Used to register console commands to the ESP-IDF console system.
Build a command line parameter structure to set what information the user needs to provide and the format of the information when entering commands in the console.
Call
arg_int0()
to define an optional integer parameter, which can appear 0 or 1 time in the command.Call
arg_int1()
to define a required integer parameter, which must appear only once in the command.Call
arg_intn()
to define an integer parameter that appears a specified number of times. Users can customize the minimum and maximum number of times this parameter appears in the command.Call
arg_end()
to define the parameter end flag. Passing a parameter indicates the maximum number of parsing errors that can be recorded.The parameter definition of
arg_intn()
is as follows:
Parameter explanation Input parameter
Parameter function
Parameter description
shortopts
Short option string
Single-character command line option, can be
NULL
to indicate not using short options.
longopts
Long option string
Multi-character command line option, can be
NULL
to indicate not using long options.
datatype
Data type description
String used to generate help information
mincount
Minimum occurrence
The minimum number of times this parameter appears in the command line. Usually 0 or 1.
maxcount
Maximum occurrence
The maximum number of times this parameter appears in the command line.
glossary
Parameter description text
Description text used to generate help information, explaining the function of the parameter.
Note
Both
arg_int0()
andarg_int1()
are implemented based onarg_intn()
, which fixed the minimum and maximum occurrences. Therefore, there is no need to pass in themincount
andmaxcount
parameters when calling, to simplify the calling in common scenarios.
Build the command registration structure
esp_console_cmd_t
, used to specify the command name, callback function, help information, and parameter structure.
Structure members Structure member
Member function
Member description
command
Command name
The command name entered by the user in the console.
help
Command information
Briefly describes the purpose of the command, which can be displayed by entering
help
in the console.
hint
Command hint (optional)
Used to provide parameter format hints.
func
Callback function
The function pointer called when the command is triggered.
argtable
Command parameter structure
Points to the parameter structure, used to parse the parameters entered by the user.
func_w_context
Callback function with context
Used when the callback function needs to access external context, such as needing to pass in additional structures or states.
context
Context pointer
Points to any user-defined data structure, passed into
func_w_context
, accessible in the callback function.Note
func
andfunc_w_context
are mutually exclusive, only one needs to be registered for the callback.
context
is only valid when usingfunc_w_context
, it can carry additional data or state required for command execution.Through this mechanism, the command callback function can be executed independently, or access external state, achieving more flexible command handling.
Call
esp_console_cmd_register()
to register the command, making it usable in the console. For further explanation and parameter passing, refer to Console Terminal API.
Register Callback Function: Called when the user inputs a command, reads the values in the parameter structure and performs the corresponding operation.
Input Parameter |
Parameter Function |
Parameter Description |
---|---|---|
|
Number of command line parameters |
Passed in by the system, indicating the number of parameters in the |
|
Command line parameter array |
Passed in by the system, containing the command name and the various options and values input by the user. |
Change I2C Bus Configuration
Define Parameter Structure
i2cconfig_args
is a command line parameter structure used to define and save the parameters provided by the user when entering the i2cconfig
command in the console.
Input Parameter |
Parameter Function |
Parameter Description |
---|---|---|
|
I2C port number |
Used to parse the |
|
I2C communication frequency |
Used to parse the |
|
I2C data line pin |
Used to parse the |
|
I2C clock line pin |
Used to parse the |
|
Parameter end flag |
Used to mark the end of the parameter list and save parsing error information. |
Register Command
register_i2cconfig()
is used to register the i2cconfig
command in the ESP-IDF console, allowing users to dynamically modify the I2C bus parameter configuration (port number, frequency, and SDA/SCL pins) through the command line.
Define the command line parameter structure, i.e., the input structure of the command:
Optional parameters:
port
andfreq
.Required parameters:
sda
andscl
.Allows recording of up to 2 parsing errors.
Build the
esp_console_cmd_t
structure.
Implement Command
do_i2cconfig_cmd()
is a callback handler, used to modify the I2C bus configuration, including port number, communication frequency, SDA/SCL pins, and reinitialize the I2C master bus. It is suitable for scenarios where the I2C port or pin needs to be adjusted during operation.
The execution logic of this function is as follows:
Parse command line parameters:
Call
arg_parse()
to parse command line parameters and store the parameters in thei2cconfig_args
structure.If there is an error in parsing the command line parameters, call
arg_print_errors()
to output error information and return directly.
Define variables:
Define the variable
i2c_port
asI2C_NUM_0
, indicating that I2C controller 0 is used by default.Define the variables
i2c_gpio_sda
andi2c_gpio_scl
to save the GPIO numbers used by the I2C data line and clock line. The initial value is 0, and it will be updated to the actual pin number according to the command line parameters or default configuration.
Judge/Update parameters
Determine whether the user has specified the
port
parameter. If specified, calli2c_get_port()
to verify the port number validity and updatei2c_port
.Determine whether the user has specified the
freq
parameter. If specified, update the global I2C communication frequencyi2c_frequency
to the specified frequency.Update the variables
i2c_gpio_sda
andi2c_gpio_scl
according to the user-specifiedsda
andscl
parameters.
Update the bus
Call
i2c_del_master_bus()
to delete the existing I2C bus to ensure that there will be no conflict when reinitializing. For further introduction and parameter explanation, please refer to I2C Interface.Reconfigure and initialize the I2C bus according to the specified port number, SDA/SCL pins, and other parameters configure and initialize I2C bus.
Verify I2C Port
i2c_get_port()
is used to verify whether the I2C port number provided by the user is valid, and returns the corresponding i2c_port_t
type port handle to ensure that the subsequent I2C operations use the correct port.
Input Parameter |
Parameter Function |
Parameter Description |
---|---|---|
|
User-specified I2C port number |
Used to select the I2C controller to operate. |
|
Output port handle pointer |
Used to save the verified I2C port number, subsequent I2C operations will use this handle. |
The execution logic of this function is as follows:
Check whether the input I2C port number is within the correct range. If the port number is invalid, print an error log and return
ESP_FAIL
.If the port number is valid, point the input pointer
i2c_port
to the corresponding port number, and returnESP_OK
to indicate that the port verification has passed.
Detect Slave Device
Register Command
register_i2cdetect()
is used to register the i2cdetect
command in the ESP-IDF console.
Build the
esp_console_cmd_t
structure.
Note
This command does not require additional parameters, so there is no need to define a parameter structure.
Implement Command
do_i2cdetect_cmd()
is a callback handler, used to scan all devices on the specified I2C bus, helping users quickly detect which slave devices are connected on the bus.
The execution logic of this function is as follows:
Define a variable
address
to save the currently scanned I2C slave address.Build a table of slave device addresses:
Print the table header, used to display the offset of 16 columns of addresses.
The outer loop traverses the I2C address space in rows of 16 addresses and prints the starting address of the current row.
The inner loop traverses the 16 addresses in each row:
Call
i2c_master_probe()
to detect whether there is a device response at the corresponding address. For further introduction and parameter explanation, refer to I2C Interface.Print the result according to the return value:
ESP_OK
: The slave device responds, print the device address.
ESP_ERR_TIMEOUT
: The bus is occupied or unresponsive, printUU
.Others, such as no device detected, print
--
.
Get I2C Slave Data
Define Parameter Structure
i2cget_args
is a command-line parameter structure, used to define and save the parameters provided by the user when entering the i2cget
command in the console.
Input Parameter |
Parameter Function |
Parameter Description |
---|---|---|
|
Device Address |
The address of the slave device from which data needs to be obtained. |
|
Register Address |
Specifies the data of a particular register to be obtained. |
|
Data Length |
The length of the data to be obtained. |
|
Parameter End Flag |
Used to mark the end of the parameter list and save parsing error information. |
Register Command
register_i2cget()
is used to register the i2cget
command in the ESP-IDF console, allowing users to dynamically obtain data from a specified register of a specified device through the command line.
Define the command-line parameter structure, i.e., the input structure of the command:
Optional parameters:
register_address
anddata_length
.Required parameter:
chip_address
.Allows recording of up to 1 parsing error.
Build the
esp_console_cmd_t
structure.
Implement Command
do_i2cget_cmd()
is a callback handler, used to obtain data from a specified register of a specified device.
The execution logic of this function is as follows:
Parse command-line parameters:
Call
arg_parse()
to parse command-line parameters and store the parameters in thei2cget_args
structure.If parsing command-line parameters fails, call
arg_print_errors()
to output error information and return directly.
Judge/Update Parameters
Save the user-specified
chip_address
parameter tochip_addr
.Determine whether the user has specified the
register_address
parameter. If specified, update the register addressdata_addr
to the specified address, otherwise default to -1.Determine whether the user has specified the
data_length
parameter. If specified, update the data lengthlen
to the specified length, otherwise default to 1.
Perform read operation
Apply for a dynamic memory buffer
data
of lengthlen
for the data to be received.I2C master writes then reads. The parameter description of
i2c_master_transmit_receive()
can refer to I2C interface.Print the result according to the return value:
ESP_OK
: Loop print the read data, 16 bytes per line.
ESP_ERR_TIMEOUT
: Indicates that the bus is busy, printBus is busy
.Others, print
Read failed
.
Release resources
Release the receive buffer.
Call
i2c_master_bus_rm_device()
to remove the device and return the execution result. For further introduction and parameter description, please refer to I2C interface.
Write data to I2C slave
Define parameter structure
i2cset_args
is a command line parameter structure used to define and save the parameters provided by the user when entering the i2cset
command in the console.
Input parameter |
Parameter function |
Parameter description |
---|---|---|
|
Device address |
The address of the slave device that needs to get data. |
|
Register address |
Specify the data of a specific register. |
|
Write data |
The data to be written to the slave. |
|
Parameter end flag |
Used to mark the end of the parameter list and save parsing error information. |
Register command
register_i2cset()
is used to register the i2cset
command in the ESP-IDF console, allowing users to dynamically write data to the specified register of the specified device through the command line.
Define the command line parameter structure, that is, the input structure of the command:
Optional parameter:
register_address
.Required parameter:
chip_address
.Specified times parameter:
data
, at least 0 data to write, up to 256 data to write.Allow up to 2 parsing errors to be recorded.
Build
esp_console_cmd_t
structure.
Implement command
do_i2cset_cmd()
is a callback processing function, used to write data to the specified register of the specified device.
The execution logic of this function is as follows:
Parse command line arguments:
Call
arg_parse()
to parse command line arguments and store the parameters in thei2cset_args
structure.If there is an error in parsing the command line arguments, call
arg_print_errors()
to output the error information and return directly.
Judge/Update parameters
Save the user-specified
chip_address
parameter tochip_addr
.Determine whether the user has specified the
register_address
parameter. If specified, update the register addressdata_addr
to the specified address, otherwise default to 0.Get the length of the data that the user needs to write to the slave, and save it to
len
.
Execute write operation
Apply for a dynamic memory buffer
data
of lengthlen + 1
for the data to be written.Store the target register address
data_addr
in the 0th byte of the buffer as the first data to be sent.Copy the user’s input data to the buffer in a loop, starting to fill from
data[1]
.I2C Master Write. The parameter description of
i2c_master_transmit()
can refer to I2C Interface.Print the result according to the return value:
ESP_OK
: Indicates successful writing, printWrite OK
.
ESP_ERR_TIMEOUT
: Indicates that the bus is busy, printBus is busy
.Others, print
Write failed
.
Release resources
Release the receive buffer.
Call
i2c_master_bus_rm_device()
to remove the device and return the execution result.
Scan I2C Slave Register
Define parameter structure
i2cdump_args
is a command line parameter structure used to define and save the parameters provided by the user when entering the i2cdump
command in the console.
Input parameter |
Parameter function |
Parameter description |
---|---|---|
|
Device address |
The address of the slave device that needs to get data. |
|
Read data width |
Indicates how many bytes to read at a time, supporting 1, 2 or 4 bytes. |
|
Parameter end flag |
Used to mark the end of the parameter list and save parsing error information. |
Register command
do_i2cdump_cmd()
is used to register the i2cdump
command in the ESP-IDF console, allowing users to dynamically scan and print the values of the internal registers of the I2C slave device through the command line, helping users quickly check the device register status.
Define the command line parameter structure, that is, the input structure of the command:
Optional parameter:
size
.Required parameter:
chip_address
.Allows recording up to 1 parsing error.
Build the
esp_console_cmd_t
structure.
Implement command
do_i2cdump_cmd()
is a callback handler, used to scan and print the values of internal registers in the I2C slave device.
The execution logic of this function is as follows:
Parse command line arguments:
Call
arg_parse()
to parse command line arguments and store the parameters in thei2cset_args
structure.If there is an error in parsing the command line arguments, call
arg_print_errors()
to output the error information and return directly.
Judge/Update parameters
Save the user-specified
chip_address
parameter tochip_addr
.Determine whether the user has written the
size
parameter. If written, update the data widthsize
to the specified width, otherwise default to 1.Determine whether the data width specified by the user is valid (only accepts 1, 2, and 4 bytes).
Scan registers
Define buffer variables:
data_addr
: Temporarily save the register address to be accessed currently.
data[4]
: Store the data read back from the device, supporting up to 4 bytes.
block[16]
: Store a row (16 registers) of data for subsequent ASCII visual printing.Print the header, including the hexadecimal data column and ASCII character display column.
The outer loop scans the registers of the slave device in rows of 16 registers and prints the starting address of the current row.
The inner loop traverses the 16 registers in each row:
Calculate the current register address.
I2C master write then read register data. The parameter description of
i2c_master_transmit_receive()
can refer to I2C interface.Print the result according to the return value:
ESP_OK
: Print the hexadecimal value of the data and save it toblock[]
.Others, such as data acquisition failure or no data in the current register, print
xx
and setblock[]
to -1 to indicate invalid.Traverse
block[16]
to complete ASCII visual output.
Remove the slave device
Call
i2c_master_bus_rm_device()
to remove the device and return the execution result.
Register all commands at once
register_i2ctools()
is a general entry function. By calling this function, all I2C commands can be registered to the ESP-IDF console at once, without the need for individual registration.
Note
The following function is defined in i2ctools_example_main.c
and is effective when the CONFIG_EXAMPLE_STORE_HISTORY
configuration item is enabled.
Store command history
initialize_filesystem()
is used to initialize and mount the FAT file system on the SPI Flash, so as to store command history or other files in the example.
Define the handle variable
wl_handle
for managing the file system access on the SPI Flash.Construct the mount configuration structure
esp_vfs_fat_mount_config_t
. For a description of the structure members, refer to FAT File System.
Allow up to 4 files to be opened at the same time.
If the mount fails, automatically format the SPI Flash and create a file system.
Call
esp_vfs_fat_spiflash_mount_rw_wl()
to mount the FAT file system to theMOUNT_PATH
directory and use thestorage
partition. For further introduction and parameter description, refer to FAT File System.
If the mount is successful, save the file system handle for subsequent access.
If the mount fails, print an error log and return, do not continue subsequent operations.
Main Function Description
This example demonstrates how to interact with I2C bus devices using I2C tool commands in the ESP-IDF console environment, including I2C bus initialization, command registration, and console REPL environment configuration.
The execution logic is as follows:
Configure REPL:
Define the console REPL handle
repl
.Initialize the
esp_console_repl_config_t
structure with the default configurationESP_CONSOLE_REPL_CONFIG_DEFAULT()
. For a description of the structure members, refer to Console Terminal.Set the prompt
prompt
to prompt the user to enter commands.
Initialize the file system:
When
CONFIG_EXAMPLE_STORE_HISTORY
is enabled, callinitialize_filesystem()
to mount the FAT file system, which is used to save console history commands.Set the history record save path to
HISTORY_PATH
.
Determine and initialize the REPL environment through conditional compilation.
Call
register_i2ctools()
to register I2C tool commands.Print the command usage steps to guide users on how to operate the I2C bus and devices through console commands.
Call
esp_console_start_repl()
, enter the interactive command line, and wait for the user to enter commands. For further introduction and parameter description, refer to Console Terminal.