refactor(i2c): Use new I2C drivers for I2C exmaple

pull/13090/head
Cao Sen Miao 2024-01-03 16:57:33 +08:00
rodzic 0bf2b35b33
commit 4d71f7c18e
17 zmienionych plików z 142 dodań i 978 usunięć

Wyświetl plik

@ -7,13 +7,6 @@
- esp_driver_i2s
- esp_driver_spi
.i2c_dependencies: &i2c_dependencies
depends_filepatterns:
# components
- examples/system/console/advanced/components/**/*
- components/driver/i2c/**/*
- components/driver/Kconfig
examples/peripherals/adc/continuous_read:
disable:
- if: SOC_ADC_DMA_SUPPORTED != 1
@ -63,18 +56,6 @@ examples/peripherals/i2c/i2c_eeprom:
depends_components:
- esp_driver_i2c
examples/peripherals/i2c/i2c_self_test:
disable:
- if: SOC_I2C_SUPPORT_SLAVE != 1
reason: the test requires both master and slave
<<: *i2c_dependencies
examples/peripherals/i2c/i2c_simple:
disable:
- if: SOC_I2C_SUPPORT_SLAVE != 1
reason: the test requires both master and slave
<<: *i2c_dependencies
examples/peripherals/i2c/i2c_tools:
disable:
- if: SOC_I2C_SUPPORTED != 1
@ -82,7 +63,10 @@ examples/peripherals/i2c/i2c_tools:
- if: IDF_TARGET != "esp32"
temporary: true
reason: lack of runners
<<: *i2c_dependencies
depends_components:
- esp_driver_i2c
depends_filepatterns:
- examples/system/console/advanced/components/**/*
examples/peripherals/i2s/i2s_basic/i2s_pdm:
disable:

Wyświetl plik

@ -1,6 +0,0 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(i2c_example)

Wyświetl plik

@ -1,197 +0,0 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# I2C Self-Test Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## Overview
This example demonstrates basic usage of I2C driver by running two tasks on I2C bus:
1. Read external I2C sensor, here we take the BH1750 ambient light sensor (GY-30 module) for an example.
2. Use one of the ESP device's I2C port (master mode) to read and write another I2C port (slave mode) in ESP device.
If you have a new I2C application to go (for example, read the temperature data from external sensor with I2C interface), try this as a basic template, then add your own code.
## How to use example
### Hardware Required
To run this example, you should have one ESP development board (e.g. ESP32-WROVER Kit) or ESP core board (e.g. ESP32-DevKitC). Optionally, you can also connect an external sensor. Here we choose the BH1750 just as an example. BH1750 is a digital ambient light sensor. For more information about it, you can read the [datasheet](http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1721fvc-e.pdf) of this sensor.
#### Pin Assignment(esp32, esp32s2):
**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` .
| | SDA | SCL |
| ------------------------- | ------ | ------ |
| ESP32/ESP32-S2 I2C Master | GPIO18 | GPIO19 |
| ESP32/ESP32-S2 I2C Slave | GPIO4 | GPIO5 |
| BH1750 Sensor | SDA | SCL |
- slave:
- GPIO4 is assigned as the data signal of I2C slave port
- GPIO5 is assigned as the clock signal of I2C slave port
- master:
- GPIO18 is assigned as the data signal of I2C master port
- GPIO19 is assigned as the clock signal of I2C master port
- Connection:
- connect GPIO18 with GPIO4
- connect GPIO19 with GPIO5
- connect SDA/SCL of BH1750 sensor with GPIO18/GPIO19
**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.
#### Pin Assignment(esp32s3, esp32h2):
**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` .
| | SDA | SCL |
| ---------------------------------- | ------ | ------ |
| ESP32-S3/ESP32-H2 I2C Master | GPIO1 | GPIO2 |
| ESP32-S3/ESP32-H2 I2C Slave | GPIO4 | GPIO5 |
| BH1750 Sensor | SDA | SCL |
- slave:
- GPIO4 is assigned as the data signal of I2C slave port
- GPIO5 is assigned as the clock signal of I2C slave port
- master:
- GPIO1 is assigned as the data signal of I2C master port
- GPIO2 is assigned as the clock signal of I2C master port
- Connection:
- connect GPIO1 with GPIO4
- connect GPIO2 with GPIO5
- connect SDA/SCL of BH1750 sensor with GPIO18/GPIO19
**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.
#### Pin Assignment(esp32c3, esp32c2):
**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` .
| | SDA | SCL |
| ------------------------------------------- | ------ | ------ |
| ESP32-C3/ESP32-C2 I2C Master(Slave) | GPIO5 | GPIO6 |
| BH1750 Sensor | SDA | SCL |
- master:
- GPIO5 is assigned to the data signal of the I2C master port
- GPIO6 is assigned to the clock signal of the I2C master port
- Connection:
- connect SDA/SCL of BH1750 sensor to GPIO5/GPIO6
**Note:** There is only one i2c device on ESP32-C3/ESP32-C2, so it is not possible to perform any ESP32/ESP32-S2 self-test example from this repo. However it is possible to test I2C with external devices. If you find anything wrong with your device, please try connecting external pull-up resistors.
### Configure the project
Open the project configuration menu (`idf.py menuconfig`). Then go into `Example Configuration` menu.
- In the `I2C Master` submenu, you can set the pin number of SDA/SCL according to your board. Also you can modify the I2C port number and freauency of the master.
- In the `I2C Slave` submenu, you can set the pin number of SDA/SCL according to your board. Also you can modify the I2C port number and address of the slave.
- In the `BH1750 Sensor` submenu, you can choose the slave address of BH1750 accroding to the pin level of ADDR pin (if the pin level of ADDR is low then the address is `0x23`, otherwise it is `0x5c`). Here you can also control the operation mode of BH1750, each mode has a different resolution and measurement time. For example, in the `One Time L-Resolution` mode, the resolution is 4 Lux and measurement time is typically 16ms (higher resolution means longer measurement time). For more information, you can consult the datasheet of BH1750.
### Build and Flash
Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Output
```bash
I (6495) i2c-example: TASK[1] test cnt: 1
*******************
TASK[1] MASTER READ SENSOR( BH1750 )
*******************
data_h: 01
data_l: d0
sensor val: 386.67 [Lux]
I (6695) i2c-example: TASK[0] test cnt: 2
*******************
TASK[0] MASTER READ SENSOR( BH1750 )
*******************
data_h: 01
data_l: d0
sensor val: 386.67 [Lux]
*******************
TASK[0] MASTER READ FROM SLAVE
*******************
====TASK[0] Slave buffer data ====
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
====TASK[0] Master read ====
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
*******************
TASK[1] MASTER READ FROM SLAVE
*******************
====TASK[1] Slave buffer data ====
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
====TASK[1] Master read ====
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f
40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f
50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f
60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f
70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
*******************
TASK[0] MASTER WRITE TO SLAVE
*******************
----TASK[0] Master write ----
0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19
1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39
3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49
4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59
5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69
6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89
----TASK[0] Slave read: [128] bytes ----
0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19
1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29
2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39
3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49
4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59
5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69
6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79
7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89
```
## Troubleshooting
- BH1750 has two I2C address, which is decided by the voltage level of `ADDR` pin at start up. Make sure to check your schemetic before run this example.
(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)

Wyświetl plik

@ -1,2 +0,0 @@
idf_component_register(SRCS "i2c_example_main.c"
INCLUDE_DIRS ".")

Wyświetl plik

@ -1,135 +0,0 @@
menu "Example Configuration"
menu "I2C Master"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config I2C_MASTER_SCL
int "SCL GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 2 if IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32H2
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2
default 6
help
GPIO number for I2C Master clock line.
config I2C_MASTER_SDA
int "SDA GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 1 if IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32H2
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2
default 5
help
GPIO number for I2C Master data line.
config I2C_MASTER_PORT_NUM
int "Port Number"
default 1 if SOC_I2C_NUM > 1
default 0
help
Port number for I2C Master device.
config I2C_MASTER_FREQUENCY
int "Master Frequency"
default 100000
help
I2C Speed of Master device.
endmenu
menu "I2C Slave"
depends on SOC_I2C_NUM > 1
config I2C_SLAVE_SCL
int "SCL GPIO Num"
default 5
help
GPIO number for I2C Slave clock line.
config I2C_SLAVE_SDA
int "SDA GPIO Num"
default 4
help
GPIO number for I2C Slave data line.
config I2C_SLAVE_PORT_NUM
int "Port Number"
default 0
help
Port number for I2C Slave device.
config I2C_SLAVE_ADDRESS
hex "ESP Slave Address"
default 0x28
help
Hardware Address of I2C Slave Port.
endmenu
menu "BH1750 Sensor"
choice BH1750_ADDR
prompt "BH1750 I2C Address"
default BH1750_I2C_ADDRESS_LOW
help
Hardware address of BH1750, which is 2 types, and determined by ADDR terminal.
config BH1750_I2C_ADDRESS_LOW
bool "BH1750 I2C Address(ADDR=0)"
help
I2C Address of BH1750 Sensor according to your schemetic configuration.
config BH1750_I2C_ADDRESS_High
bool "BH1750 I2C Address(ADDR=1)"
help
I2C Address of BH1750 Sensor according to your schemetic configuration.
endchoice
config BH1750_ADDR
hex
default 0x5C if BH1750_I2C_ADDRESS_High
default 0x23 if BH1750_I2C_ADDRESS_LOW
choice BH1750_MODE
prompt "BH1750 Operation Mode"
default BH1750_ONETIME_L_RESOLUTION
help
Operation Mode of BH1750.
Different mode means different resolution and measurement time.
config BH1750_CONTINU_H_RESOLUTION
bool "Continuously H-Resolution Mode"
help
Resolution is 1lx, measurement time is typically 120ms.
config BH1750_CONTINU_H_RESOLUTION2
bool "Continuously H-Resolution Mode2"
help
Resolution is 0.5lx, measurement time is typically 120ms.
config BH1750_CONTINU_L_RESOLUTION
bool "Continuously L-Resolution Mode"
help
Resolution is 4lx, measurement time is typically 16ms.
config BH1750_ONETIME_H_RESOLUTION
bool "One Time H-Resolution Mode"
help
Resolution is 1lx, measurement time is typically 120ms.
It is automatically set to Power Down mode after measurement.
config BH1750_ONETIME_H_RESOLUTION2
bool "One Time H-Resolution Mode2"
help
Resolution is 0.5lx, measurement time is typically 120ms.
It is automatically set to Power Down mode after measurement.
config BH1750_ONETIME_L_RESOLUTION
bool "One Time L-Resolution Mode"
help
Resolution is 4lx, measurement time is typically 16ms.
It is automatically set to Power Down mode after measurement.
endchoice
config BH1750_OPMODE
hex
default 0x10 if BH1750_CONTINU_H_RESOLUTION
default 0x11 if BH1750_CONTINU_H_RESOLUTION2
default 0x13 if BH1750_CONTINU_L_RESOLUTION
default 0x20 if BH1750_ONETIME_H_RESOLUTION
default 0x21 if BH1750_ONETIME_H_RESOLUTION2
default 0x23 if BH1750_ONETIME_L_RESOLUTION
endmenu
endmenu

Wyświetl plik

@ -1,315 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* i2c - Example
For other examples please check:
https://github.com/espressif/esp-idf/tree/master/examples
See README.md file to get detailed usage of this example.
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 "esp_log.h"
#include "driver/i2c.h"
#include "sdkconfig.h"
static const char *TAG = "i2c-example";
#define _I2C_NUMBER(num) I2C_NUM_##num
#define I2C_NUMBER(num) _I2C_NUMBER(num)
#define DATA_LENGTH 512 /*!< Data buffer length of test buffer */
#define RW_TEST_LENGTH 128 /*!< Data length for r/w test, [0,DATA_LENGTH] */
#define DELAY_TIME_BETWEEN_ITEMS_MS 1000 /*!< delay time between different test items */
#if SOC_I2C_NUM > 1
#define I2C_SLAVE_SCL_IO CONFIG_I2C_SLAVE_SCL /*!< gpio number for i2c slave clock */
#define I2C_SLAVE_SDA_IO CONFIG_I2C_SLAVE_SDA /*!< gpio number for i2c slave data */
#define I2C_SLAVE_NUM I2C_NUMBER(CONFIG_I2C_SLAVE_PORT_NUM) /*!< I2C port number for slave dev */
#define I2C_SLAVE_TX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave tx buffer size */
#define I2C_SLAVE_RX_BUF_LEN (2 * DATA_LENGTH) /*!< I2C slave rx buffer size */
#define ESP_SLAVE_ADDR CONFIG_I2C_SLAVE_ADDRESS /*!< ESP32 slave address, you can set any 7bit value */
#endif
#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< gpio number for I2C master data */
#define I2C_MASTER_NUM I2C_NUMBER(CONFIG_I2C_MASTER_PORT_NUM) /*!< I2C port number for master dev */
#define I2C_MASTER_FREQ_HZ CONFIG_I2C_MASTER_FREQUENCY /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define BH1750_SENSOR_ADDR CONFIG_BH1750_ADDR /*!< slave address for BH1750 sensor */
#define BH1750_CMD_START CONFIG_BH1750_OPMODE /*!< Operation mode */
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
SemaphoreHandle_t print_mux = NULL;
#if SOC_I2C_NUM > 1
/**
* @brief test code to read esp-i2c-slave
* We need to fill the buffer of esp slave device, then master can read them out.
*
* _______________________________________________________________________________________
* | start | slave_addr + rd_bit +ack | read n-1 bytes + ack | read 1 byte + nack | stop |
* --------|--------------------------|----------------------|--------------------|------|
*
* @note cannot use master read slave on esp32c3 because there is only one i2c controller on esp32c3
*/
static esp_err_t __attribute__((unused)) i2c_master_read_slave(i2c_port_t i2c_num, uint8_t *data_rd, size_t size)
{
if (size == 0) {
return ESP_OK;
}
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (ESP_SLAVE_ADDR << 1) | READ_BIT, ACK_CHECK_EN);
if (size > 1) {
i2c_master_read(cmd, data_rd, size - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
/**
* @brief Test code to write esp-i2c-slave
* Master device write data to slave(both esp32),
* the data will be stored in slave buffer.
* We can read them out from slave buffer.
*
* ___________________________________________________________________
* | start | slave_addr + wr_bit + ack | write n bytes + ack | stop |
* --------|---------------------------|----------------------|------|
*
* @note cannot use master write slave on esp32c3 because there is only one i2c controller on esp32c3
*/
static esp_err_t __attribute__((unused)) i2c_master_write_slave(i2c_port_t i2c_num, uint8_t *data_wr, size_t size)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (ESP_SLAVE_ADDR << 1) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
#endif
/**
* @brief test code to operate on BH1750 sensor
*
* 1. set operation mode(e.g One time L-resolution mode)
* _________________________________________________________________
* | start | slave_addr + wr_bit + ack | write 1 byte + ack | stop |
* --------|---------------------------|---------------------|------|
* 2. wait more than 24 ms
* 3. read data
* ______________________________________________________________________________________
* | start | slave_addr + rd_bit + ack | read 1 byte + ack | read 1 byte + nack | stop |
* --------|---------------------------|--------------------|--------------------|------|
*/
static esp_err_t i2c_master_sensor_test(i2c_port_t i2c_num, uint8_t *data_h, uint8_t *data_l)
{
int ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, BH1750_CMD_START, ACK_CHECK_EN);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
if (ret != ESP_OK) {
return ret;
}
vTaskDelay(30 / portTICK_PERIOD_MS);
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, BH1750_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, data_h, ACK_VAL);
i2c_master_read_byte(cmd, data_l, NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
/**
* @brief i2c master initialization
*/
static esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_MASTER_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
// .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
};
esp_err_t err = i2c_param_config(i2c_master_port, &conf);
if (err != ESP_OK) {
return err;
}
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
#if SOC_I2C_NUM > 1
/**
* @brief i2c slave initialization
*/
static esp_err_t i2c_slave_init(void)
{
int i2c_slave_port = I2C_SLAVE_NUM;
i2c_config_t conf_slave = {
.sda_io_num = I2C_SLAVE_SDA_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = I2C_SLAVE_SCL_IO,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.mode = I2C_MODE_SLAVE,
.slave.addr_10bit_en = 0,
.slave.slave_addr = ESP_SLAVE_ADDR,
};
esp_err_t err = i2c_param_config(i2c_slave_port, &conf_slave);
if (err != ESP_OK) {
return err;
}
return i2c_driver_install(i2c_slave_port, conf_slave.mode, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0);
}
/**
* @brief test function to show buffer
*/
static void disp_buf(uint8_t *buf, int len)
{
int i;
for (i = 0; i < len; i++) {
printf("%02x ", buf[i]);
if ((i + 1) % 16 == 0) {
printf("\n");
}
}
printf("\n");
}
#endif //!CONFIG_IDF_TARGET_ESP32C3
static void i2c_test_task(void *arg)
{
int ret;
int task_idx = (int)arg;
#if SOC_I2C_NUM > 1
int i = 0;
uint8_t *data = (uint8_t *)malloc(DATA_LENGTH);
uint8_t *data_wr = (uint8_t *)malloc(DATA_LENGTH);
uint8_t *data_rd = (uint8_t *)malloc(DATA_LENGTH);
#endif //!CONFIG_IDF_TARGET_ESP32C3
uint8_t sensor_data_h, sensor_data_l;
int cnt = 0;
while (1) {
ESP_LOGI(TAG, "TASK[%d] test cnt: %d", task_idx, cnt++);
ret = i2c_master_sensor_test(I2C_MASTER_NUM, &sensor_data_h, &sensor_data_l);
xSemaphoreTake(print_mux, portMAX_DELAY);
if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGE(TAG, "I2C Timeout");
} else if (ret == ESP_OK) {
printf("*******************\n");
printf("TASK[%d] MASTER READ SENSOR( BH1750 )\n", task_idx);
printf("*******************\n");
printf("data_h: %02x\n", sensor_data_h);
printf("data_l: %02x\n", sensor_data_l);
printf("sensor val: %.02f [Lux]\n", (sensor_data_h << 8 | sensor_data_l) / 1.2);
} else {
ESP_LOGW(TAG, "%s: No ack, sensor not connected...skip...", esp_err_to_name(ret));
}
xSemaphoreGive(print_mux);
vTaskDelay((DELAY_TIME_BETWEEN_ITEMS_MS * (task_idx + 1)) / portTICK_PERIOD_MS);
//---------------------------------------------------
#if SOC_I2C_NUM > 1
for (i = 0; i < DATA_LENGTH; i++) {
data[i] = i;
}
xSemaphoreTake(print_mux, portMAX_DELAY);
size_t d_size = i2c_slave_write_buffer(I2C_SLAVE_NUM, data, RW_TEST_LENGTH, 1000 / portTICK_PERIOD_MS);
if (d_size == 0) {
ESP_LOGW(TAG, "i2c slave tx buffer full");
ret = i2c_master_read_slave(I2C_MASTER_NUM, data_rd, DATA_LENGTH);
} else {
ret = i2c_master_read_slave(I2C_MASTER_NUM, data_rd, RW_TEST_LENGTH);
}
if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGE(TAG, "I2C Timeout");
} else if (ret == ESP_OK) {
printf("*******************\n");
printf("TASK[%d] MASTER READ FROM SLAVE\n", task_idx);
printf("*******************\n");
printf("====TASK[%d] Slave buffer data ====\n", task_idx);
disp_buf(data, d_size);
printf("====TASK[%d] Master read ====\n", task_idx);
disp_buf(data_rd, d_size);
} else {
ESP_LOGW(TAG, "TASK[%d] %s: Master read slave error, IO not connected...",
task_idx, esp_err_to_name(ret));
}
xSemaphoreGive(print_mux);
vTaskDelay((DELAY_TIME_BETWEEN_ITEMS_MS * (task_idx + 1)) / portTICK_PERIOD_MS);
//---------------------------------------------------
int size;
for (i = 0; i < DATA_LENGTH; i++) {
data_wr[i] = i + 10;
}
xSemaphoreTake(print_mux, portMAX_DELAY);
//we need to fill the slave buffer so that master can read later
ret = i2c_master_write_slave(I2C_MASTER_NUM, data_wr, RW_TEST_LENGTH);
if (ret == ESP_OK) {
size = i2c_slave_read_buffer(I2C_SLAVE_NUM, data, RW_TEST_LENGTH, 1000 / portTICK_PERIOD_MS);
}
if (ret == ESP_ERR_TIMEOUT) {
ESP_LOGE(TAG, "I2C Timeout");
} else if (ret == ESP_OK) {
printf("*******************\n");
printf("TASK[%d] MASTER WRITE TO SLAVE\n", task_idx);
printf("*******************\n");
printf("----TASK[%d] Master write ----\n", task_idx);
disp_buf(data_wr, RW_TEST_LENGTH);
printf("----TASK[%d] Slave read: [%d] bytes ----\n", task_idx, size);
disp_buf(data, size);
} else {
ESP_LOGW(TAG, "TASK[%d] %s: Master write slave error, IO not connected....",
task_idx, esp_err_to_name(ret));
}
xSemaphoreGive(print_mux);
vTaskDelay((DELAY_TIME_BETWEEN_ITEMS_MS * (task_idx + 1)) / portTICK_PERIOD_MS);
#endif //!CONFIG_IDF_TARGET_ESP32C3
}
vSemaphoreDelete(print_mux);
vTaskDelete(NULL);
}
void app_main(void)
{
print_mux = xSemaphoreCreateMutex();
#if SOC_I2C_NUM > 1
ESP_ERROR_CHECK(i2c_slave_init());
#endif
ESP_ERROR_CHECK(i2c_master_init());
xTaskCreate(i2c_test_task, "i2c_test_task_0", 1024 * 2, (void *)0, 10, NULL);
xTaskCreate(i2c_test_task, "i2c_test_task_1", 1024 * 2, (void *)1, 10, NULL);
}

Wyświetl plik

@ -1,6 +0,0 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(i2c-simple)

Wyświetl plik

@ -1,52 +0,0 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# I2C Simple Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
## Overview
This example demonstrates basic usage of I2C driver by reading and writing from a I2C connected sensor:
If you have a new I2C application to go (for example, read the temperature data from external sensor with I2C interface), try this as a basic template, then add your own code.
## How to use example
### Hardware Required
To run this example, you should have one ESP32, ESP32-S, ESP32-C or ESP32-H based development board as well as a MPU9250. MPU9250 is a inertial measurement unit, which contains a accelerometer, gyroscope as well as a magnetometer, for more information about it, you can read the [datasheet of the MPU9250 sensor](https://invensense.tdk.com/wp-content/uploads/2015/02/PS-MPU-9250A-01-v1.1.pdf).
#### Pin Assignment:
**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` .
| | SDA | SCL |
| ---------------- | -------------- | -------------- |
| ESP I2C Master | I2C_MASTER_SDA | I2C_MASTER_SCL |
| MPU9250 Sensor | SDA | SCL |
For the actual default value of `I2C_MASTER_SDA` and `I2C_MASTER_SCL` see `Example Configuration` in `menuconfig`.
**Note:** There's no need to add an external pull-up resistors for SDA/SCL pin, because the driver will enable the internal pull-up resistors.
### Build and Flash
Enter `idf.py -p PORT flash monitor` to build, flash and monitor the project.
(To exit the serial monitor, type ``Ctrl-]``.)
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.
## Example Output
```bash
I (328) i2c-simple-example: I2C initialized successfully
I (338) i2c-simple-example: WHO_AM_I = 71
I (338) i2c-simple-example: I2C de-initialized successfully
```
## Troubleshooting
(For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you as soon as possible.)

Wyświetl plik

@ -1,2 +0,0 @@
idf_component_register(SRCS "i2c_simple_main.c"
INCLUDE_DIRS ".")

Wyświetl plik

@ -1,21 +0,0 @@
menu "Example Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config I2C_MASTER_SCL
int "SCL GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 2
help
GPIO number for I2C Master clock line.
config I2C_MASTER_SDA
int "SDA GPIO Num"
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 1
help
GPIO number for I2C Master data line.
endmenu

Wyświetl plik

@ -1,96 +0,0 @@
/* i2c - Simple example
Simple I2C example that shows how to initialize I2C
as well as reading and writing from and to registers for a sensor connected over I2C.
The sensor used in this example is a MPU9250 inertial measurement unit.
For other examples please check:
https://github.com/espressif/esp-idf/tree/master/examples
See README.md file to get detailed usage of this example.
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 "esp_log.h"
#include "driver/i2c.h"
static const char *TAG = "i2c-simple-example";
#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL /*!< GPIO number used for I2C master clock */
#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA /*!< GPIO number used for I2C master data */
#define I2C_MASTER_NUM 0 /*!< I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip */
#define I2C_MASTER_FREQ_HZ 400000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_TIMEOUT_MS 1000
#define MPU9250_SENSOR_ADDR 0x68 /*!< Slave address of the MPU9250 sensor */
#define MPU9250_WHO_AM_I_REG_ADDR 0x75 /*!< Register addresses of the "who am I" register */
#define MPU9250_PWR_MGMT_1_REG_ADDR 0x6B /*!< Register addresses of the power managment register */
#define MPU9250_RESET_BIT 7
/**
* @brief Read a sequence of bytes from a MPU9250 sensor registers
*/
static esp_err_t mpu9250_register_read(uint8_t reg_addr, uint8_t *data, size_t len)
{
return i2c_master_write_read_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, &reg_addr, 1, data, len, I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
}
/**
* @brief Write a byte to a MPU9250 sensor register
*/
static esp_err_t mpu9250_register_write_byte(uint8_t reg_addr, uint8_t data)
{
int ret;
uint8_t write_buf[2] = {reg_addr, data};
ret = i2c_master_write_to_device(I2C_MASTER_NUM, MPU9250_SENSOR_ADDR, write_buf, sizeof(write_buf), I2C_MASTER_TIMEOUT_MS / portTICK_PERIOD_MS);
return ret;
}
/**
* @brief i2c master initialization
*/
static esp_err_t i2c_master_init(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = I2C_MASTER_SDA_IO,
.scl_io_num = I2C_MASTER_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = I2C_MASTER_FREQ_HZ,
};
i2c_param_config(i2c_master_port, &conf);
return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
}
void app_main(void)
{
uint8_t data[2];
ESP_ERROR_CHECK(i2c_master_init());
ESP_LOGI(TAG, "I2C initialized successfully");
/* Read the MPU9250 WHO_AM_I register, on power up the register should have the value 0x71 */
ESP_ERROR_CHECK(mpu9250_register_read(MPU9250_WHO_AM_I_REG_ADDR, data, 1));
ESP_LOGI(TAG, "WHO_AM_I = %X", data[0]);
/* Demonstrate writing by reseting the MPU9250 */
ESP_ERROR_CHECK(mpu9250_register_write_byte(MPU9250_PWR_MGMT_1_REG_ADDR, 1 << MPU9250_RESET_BIT));
ESP_ERROR_CHECK(i2c_driver_delete(I2C_MASTER_NUM));
ESP_LOGI(TAG, "I2C de-initialized successfully");
}

Wyświetl plik

@ -21,20 +21,20 @@ If you have some trouble in developing I2C related applications, or just want to
### Hardware Required
To run this example, you should have any ESP32, ESP32-S and ESP32-C based development board. For test purpose, you should have a kind of device with I2C interface as well. Here we will take the CCS811 sensor as an example to show how to test the function of this sensor without writing any code (just use the command-line tools supported by this example). For more information about CCS811, you can consult the [online datasheet](http://ams.com/ccs811).
To run this example, you should have any ESP32, ESP32-S, ESP32-C, ESP32-H, ESP32-P based development board. For test purpose, you should have a kind of device with I2C interface as well. Here we will take the CCS811 sensor as an example to show how to test the function of this sensor without writing any code (just use the command-line tools supported by this example). For more information about CCS811, you can consult the [online datasheet](http://ams.com/ccs811).
#### Pin Assignment:
**Note:** The following pin assignments are used by default, you can change them with `i2cconfig` command at any time.
**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.
| | SDA | SCL | GND | Other | VCC |
| ------------------- | ------ | ------ | ---- | ----- | ---- |
| ESP32 I2C Master | GPIO18 | GPIO19 | GND | GND | 3.3V |
| ESP32-S2 I2C Master | GPIO18 | GPIO19 | GND | GND | 3.3V |
| ESP32-S3 I2C Master | GPIO1 | GPIO2 | GND | GND | 3.3V |
| ESP32-C3 I2C Master | GPIO5 | GPIO6 | GND | GND | 3.3V |
| ESP32-C2 I2C Master | GPIO5 | GPIO6 | GND | GND | 3.3V |
| ESP32-H2 I2C Master | GPIO1 | GPIO2 | 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.
@ -59,7 +59,7 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l
```bash
==============================================================
| Steps to Use i2c-tools on ESP32 |
| Steps to Use i2c-tools |
| |
| 1. Try 'help', check all supported commands |
| 2. Try 'i2cconfig' to configure your I2C bus |
@ -70,6 +70,11 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l
| |
==============================================================
Type 'help' to get the list of commands.
Use UP/DOWN arrows to navigate through command history.
Press TAB when typing command name to auto-complete.
I (379) main_task: Returned from app_main()
i2c-tools> help
help
Print the list of registered commands
@ -136,7 +141,7 @@ tasks
### Configure the I2C bus
```bash
esp32> i2cconfig --port=0 --sda=18 --scl=19 --freq=100000
i2c-tools> i2cconfig --port=0 --sda=18 --scl=19 --freq=100000
```
* `--port` option to specify the port of I2C, here we choose port 0 for test.
@ -146,7 +151,7 @@ esp32> i2cconfig --port=0 --sda=18 --scl=19 --freq=100000
### Check the I2C address (7 bits) on the I2C bus
```bash
esp32> i2cdetect
i2c-tools> i2cdetect
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
@ -163,7 +168,7 @@ esp32> i2cdetect
### Get the value of status register
```bash
esp32> i2cget -c 0x5b -r 0x00 -l 1
i2c-tools> i2cget -c 0x5b -r 0x00 -l 1
0x10
```
@ -175,11 +180,11 @@ esp32> i2cget -c 0x5b -r 0x00 -l 1
### Change the working mode
```bash
esp32> i2cset -c 0x5b -r 0xF4
i2c-tools> i2cset -c 0x5b -r 0xF4
I (734717) cmd_i2ctools: Write OK
esp32> i2cset -c 0x5b -r 0x01 0x10
i2c-tools> i2cset -c 0x5b -r 0x01 0x10
I (1072047) cmd_i2ctools: Write OK
esp32> i2cget -c 0x5b -r 0x00 -l 1
i2c-tools> i2cget -c 0x5b -r 0x00 -l 1
0x98
```
@ -189,7 +194,7 @@ esp32> i2cget -c 0x5b -r 0x00 -l 1
### Read the sensor data
```bash
esp32> i2cget -c 0x5b -r 0x02 -l 8
i2c-tools> i2cget -c 0x5b -r 0x02 -l 8
0x01 0xb0 0x00 0x04 0x98 0x00 0x19 0x8f
```

Wyświetl plik

@ -7,4 +7,19 @@ menu "Example Configuration"
Linenoise line editing library provides functions to save and load
command history. If this option is enabled, initalizes 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

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -12,35 +12,17 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "argtable3/argtable3.h"
#include "driver/i2c.h"
#include "driver/i2c_master.h"
#include "esp_console.h"
#include "esp_log.h"
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
static const char *TAG = "cmd_i2ctools";
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32H2
static gpio_num_t i2c_gpio_sda = 1;
static gpio_num_t i2c_gpio_scl = 2;
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
static gpio_num_t i2c_gpio_sda = 5;
static gpio_num_t i2c_gpio_scl = 6;
#else
static gpio_num_t i2c_gpio_sda = 18;
static gpio_num_t i2c_gpio_scl = 19;
#endif
static uint32_t i2c_frequency = 100000;
static i2c_port_t i2c_port = I2C_NUM_0;
#define I2C_TOOL_TIMEOUT_VALUE_MS (50)
static uint32_t i2c_frequency = 100 * 1000;
i2c_master_bus_handle_t tool_bus_handle;
static esp_err_t i2c_get_port(int port, i2c_port_t *i2c_port)
{
@ -52,20 +34,6 @@ static esp_err_t i2c_get_port(int port, i2c_port_t *i2c_port)
return ESP_OK;
}
static esp_err_t i2c_master_driver_initialize(void)
{
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = i2c_gpio_sda,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = i2c_gpio_scl,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = i2c_frequency,
// .clk_flags = 0, /*!< Optional, you can use I2C_SCLK_SRC_FLAG_* flags to choose i2c source clock here. */
};
return i2c_param_config(i2c_port, &conf);
}
static struct {
struct arg_int *port;
struct arg_int *freq;
@ -77,6 +45,9 @@ static struct {
static int do_i2cconfig_cmd(int argc, char **argv)
{
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;
@ -96,6 +67,25 @@ static int do_i2cconfig_cmd(int argc, char **argv)
i2c_gpio_sda = i2cconfig_args.sda->ival[0];
/* Check "--scl" option */
i2c_gpio_scl = i2cconfig_args.scl->ival[0];
// re-init the bus
if (i2c_del_master_bus(tool_bus_handle) != ESP_OK) {
return 1;
}
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,
};
if (i2c_new_master_bus(&i2c_bus_config, &tool_bus_handle) != ESP_OK) {
return 1;
}
return 0;
}
@ -118,8 +108,6 @@ static void register_i2cconfig(void)
static int do_i2cdetect_cmd(int argc, char **argv)
{
i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
i2c_master_driver_initialize();
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) {
@ -127,12 +115,7 @@ static int do_i2cdetect_cmd(int argc, char **argv)
for (int j = 0; j < 16; j++) {
fflush(stdout);
address = i + j;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (address << 1) | WRITE_BIT, ACK_CHECK_EN);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 50 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
esp_err_t ret = i2c_master_probe(tool_bus_handle, address, I2C_TOOL_TIMEOUT_VALUE_MS);
if (ret == ESP_OK) {
printf("%02x ", address);
} else if (ret == ESP_ERR_TIMEOUT) {
@ -144,7 +127,6 @@ static int do_i2cdetect_cmd(int argc, char **argv)
printf("\r\n");
}
i2c_driver_delete(i2c_port);
return 0;
}
@ -189,23 +171,16 @@ static int do_i2cget_cmd(int argc, char **argv)
}
uint8_t *data = malloc(len);
i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
i2c_master_driver_initialize();
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
if (data_addr != -1) {
i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN);
i2c_master_start(cmd);
i2c_device_config_t i2c_dev_conf = {
.scl_speed_hz = i2c_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;
}
i2c_master_write_byte(cmd, chip_addr << 1 | READ_BIT, ACK_CHECK_EN);
if (len > 1) {
i2c_master_read(cmd, data, len - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, data + len - 1, NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
esp_err_t ret = i2c_master_transmit_receive(dev_handle, (uint8_t*)&data_addr, 1, data, len, I2C_TOOL_TIMEOUT_VALUE_MS);
if (ret == ESP_OK) {
for (int i = 0; i < len; i++) {
printf("0x%02x ", data[i]);
@ -222,7 +197,9 @@ static int do_i2cget_cmd(int argc, char **argv)
ESP_LOGW(TAG, "Read failed");
}
free(data);
i2c_driver_delete(i2c_port);
if (i2c_master_bus_rm_device(dev_handle) != ESP_OK) {
return 1;
}
return 0;
}
@ -267,20 +244,21 @@ static int do_i2cset_cmd(int argc, char **argv)
/* Check data: "-d" option */
int len = i2cset_args.data->count;
i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
i2c_master_driver_initialize();
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN);
if (i2cset_args.register_address->count) {
i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN);
i2c_device_config_t i2c_dev_conf = {
.scl_speed_hz = i2c_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;
}
uint8_t *data = malloc(len + 1);
data[0] = data_addr;
for (int i = 0; i < len; i++) {
i2c_master_write_byte(cmd, i2cset_args.data->ival[i], ACK_CHECK_EN);
data[i + 1] = i2cset_args.data->ival[i];
}
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 1000 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
esp_err_t ret = i2c_master_transmit(dev_handle, data, len + 1, I2C_TOOL_TIMEOUT_VALUE_MS);
if (ret == ESP_OK) {
ESP_LOGI(TAG, "Write OK");
} else if (ret == ESP_ERR_TIMEOUT) {
@ -288,7 +266,11 @@ static int do_i2cset_cmd(int argc, char **argv)
} else {
ESP_LOGW(TAG, "Write Failed");
}
i2c_driver_delete(i2c_port);
free(data);
if (i2c_master_bus_rm_device(dev_handle) != ESP_OK) {
return 1;
}
return 0;
}
@ -333,8 +315,16 @@ static int do_i2cdump_cmd(int argc, char **argv)
ESP_LOGE(TAG, "Wrong read size. Only support 1,2,4");
return 1;
}
i2c_driver_install(i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
i2c_master_driver_initialize();
i2c_device_config_t i2c_dev_conf = {
.scl_speed_hz = i2c_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;
}
uint8_t data_addr;
uint8_t data[4];
int32_t block[16];
@ -345,19 +335,7 @@ static int do_i2cdump_cmd(int argc, char **argv)
for (int j = 0; j < 16; j += size) {
fflush(stdout);
data_addr = i + j;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, chip_addr << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, data_addr, ACK_CHECK_EN);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, chip_addr << 1 | READ_BIT, ACK_CHECK_EN);
if (size > 1) {
i2c_master_read(cmd, data, size - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, data + size - 1, NACK_VAL);
i2c_master_stop(cmd);
esp_err_t ret = i2c_master_cmd_begin(i2c_port, cmd, 50 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd);
esp_err_t ret = i2c_master_transmit_receive(dev_handle, &data_addr, 1, data, size, I2C_TOOL_TIMEOUT_VALUE_MS);
if (ret == ESP_OK) {
for (int k = 0; k < size; k++) {
printf("%02x ", data[k]);
@ -385,7 +363,9 @@ static int do_i2cdump_cmd(int argc, char **argv)
}
printf("\r\n");
}
i2c_driver_delete(i2c_port);
if (i2c_master_bus_rm_device(dev_handle) != ESP_OK) {
return 1;
}
return 0;
}

Wyświetl plik

@ -1,20 +1,21 @@
/* cmd_i2ctools.h
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.
*/
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "driver/i2c_master.h"
#ifdef __cplusplus
extern "C" {
#endif
void register_i2ctools(void);
extern i2c_master_bus_handle_t tool_bus_handle;
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -1,11 +1,8 @@
/* i2c-tools example
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.
*/
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
@ -15,9 +12,15 @@
#include "esp_vfs_fat.h"
#include "cmd_system.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"
@ -61,6 +64,17 @@ void app_main(void)
ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl));
#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();
printf("\n ==============================================================\n");

Wyświetl plik

@ -1136,9 +1136,6 @@ examples/network/simple_sniffer/main/simple_sniffer_example_main.c
examples/peripherals/gpio/generic_gpio/main/gpio_example_main.c
examples/peripherals/gpio/matrix_keyboard/components/matrix_keyboard/include/matrix_keyboard.h
examples/peripherals/gpio/matrix_keyboard/main/matrix_keyboard_example_main.c
examples/peripherals/i2c/i2c_simple/main/i2c_simple_main.c
examples/peripherals/i2c/i2c_tools/main/cmd_i2ctools.h
examples/peripherals/i2c/i2c_tools/main/i2ctools_example_main.c
examples/peripherals/ledc/ledc_basic/main/ledc_basic_example_main.c
examples/peripherals/ledc/ledc_fade/main/ledc_fade_example_main.c
examples/peripherals/sdio/host/main/app_main.c