From 372584d1dea1eca13dcfe7df8ea1ba0cc3d00066 Mon Sep 17 00:00:00 2001 From: Cao Sen Miao Date: Thu, 18 Feb 2021 17:45:14 +0800 Subject: [PATCH] i2c: update api reference and example pin defination --- docs/en/api-reference/peripherals/i2c.rst | 33 +++++++++++++++-- .../peripherals/i2c/i2c_self_test/README.md | 36 ++++++++++++++----- .../i2c/i2c_self_test/main/Kconfig.projbuild | 9 +++-- .../i2c/i2c_self_test/main/i2c_example_main.c | 16 +++++++-- 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/docs/en/api-reference/peripherals/i2c.rst b/docs/en/api-reference/peripherals/i2c.rst index 083f864036..ee290bb06d 100644 --- a/docs/en/api-reference/peripherals/i2c.rst +++ b/docs/en/api-reference/peripherals/i2c.rst @@ -10,8 +10,13 @@ I2C is a serial, synchronous, half-duplex communication protocol that allows co- With such advantages as simplicity and low manufacturing cost, I2C is mostly used for communication of low-speed peripheral devices over short distances (within one foot). -{IDF_TARGET_NAME} has two I2C controllers (also referred to as ports) which are responsible for handling communications on two I2C buses. Each I2C controller can operate as master or slave. As an example, one controller can act as a master and the other as a slave at the same time. +.. only:: esp32c3 + {IDF_TARGET_NAME} has only one I2C controller (also referred to as port) which is responsible for handling communications on I2C bus. The I2C controller can operate as master or slave. + +.. only:: not esp32c3 + + {IDF_TARGET_NAME} has two I2C controllers (also referred to as ports) which are responsible for handling communications on the I2C bus. Each I2C controller can operate as master or slave. As an example, one controller can act as a master and the other as a slave at the same time. Driver Features --------------- @@ -140,10 +145,34 @@ When :cpp:member:`i2c_config_t::clk_flags` is 0, the clock allocator will select - :c:macro:`I2C_SCLK_SRC_FLAG_AWARE_DFS`, :c:macro:`I2C_SCLK_SRC_FLAG_LIGHT_SLEEP` Explanations for :cpp:member:`i2c_config_t::clk_flags` are as follows: - 1. :c:macro:`I2C_SCLK_SRC_FLAG_AWARE_DFS`: Clock's baud rate will not change while APB clock is changing. 2. :c:macro:`I2C_SCLK_SRC_FLAG_LIGHT_SLEEP`: It supports Light-sleep mode, which APB clock cannot do. +.. only:: esp32c3 + + .. list-table:: Characteristics of {IDF_TARGET_NAME} clock sources + :widths: 5 5 50 100 + :header-rows: 1 + + * - Clock name + - Clock frequency + - MAX freq for SCL + - Clock capabilities + * - XTAL clock + - 40 MHz + - 2 MHz + - / + * - RTC clock + - 20 MHz + - 1 MHz + - :c:macro:`I2C_SCLK_SRC_FLAG_AWARE_DFS`, :c:macro:`I2C_SCLK_SRC_FLAG_LIGHT_SLEEP` + +Explanations for :cpp:member:`i2c_config_t::clk_flags` are as follows: + +1. :c:macro:`I2C_SCLK_SRC_FLAG_AWARE_DFS`: Clock's baud rate will not change while APB clock is changing. +2. :c:macro:`I2C_SCLK_SRC_FLAG_LIGHT_SLEEP`: It supports Light-sleep mode, which APB clock cannot do. +3. Some flags may not be supported on {IDF_TARGET_NAME}, reading technical reference manual before using it. + .. note:: The clock frequency of SCL in master mode should not be lager than max frequency for SCL mentioned in the table above. diff --git a/examples/peripherals/i2c/i2c_self_test/README.md b/examples/peripherals/i2c/i2c_self_test/README.md index f8d7f6a1a4..d51fa8d365 100644 --- a/examples/peripherals/i2c/i2c_self_test/README.md +++ b/examples/peripherals/i2c/i2c_self_test/README.md @@ -7,7 +7,7 @@ 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 ESP32’s I2C port (master mode) to read and write another I2C port (slave mode) in ESP32. +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. @@ -15,17 +15,17 @@ If you have a new I2C application to go (for example, read the temperature data ### Hardware Required -To run this example, you should have one ESP32 dev board (e.g. ESP32-WROVER Kit) or ESP32 core board (e.g. ESP32-DevKitC). Optionally, you can also connect an external sensor, here we choose the BH1750 just for an example. BH1750 is a digital ambient light sensor, for more information about it, you can read the [PDF](http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1721fvc-e.pdf) of this sensor. +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: +#### Pin Assignment(esp32, esp32s2): **Note:** The following pin assignments are used by default, yout can change these in the `menuconfig` . -| | SDA | SCL | -| ---------------- | ------ | ------ | -| ESP32 I2C Master | GPIO18 | GPIO19 | -| ESP32 I2C Slave | GPIO4 | GPIO5 | -| BH1750 Sensor | SDA | SCL | +| | 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 @@ -39,7 +39,25 @@ To run this example, you should have one ESP32 dev board (e.g. ESP32-WROVER Kit) - connect GPIO19 with GPIO5 - connect SDA/SCL of BH1750 sensor with GPIO18/GPIO19 -**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. +**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): + +**Note:** The following pin assignments are used by default, you can change these in the `menuconfig` . + +| | SDA | SCL | +| ------------------------- | ------ | ------ | +| ESP32-C3 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 esp32c3, so you can't try any master-slave example for esp32/s2 in this repo. But you can try external devices. If you find anything wrong with your device, please try connecting pull-up resistors by yourself. ### Configure the project diff --git a/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild b/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild index bcd1c3fcfd..48b6e4e65c 100644 --- a/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild +++ b/examples/peripherals/i2c/i2c_self_test/main/Kconfig.projbuild @@ -3,19 +3,22 @@ menu "Example Configuration" menu "I2C Master" config I2C_MASTER_SCL int "SCL GPIO Num" - default 19 + default 6 if IDF_TARGET_ESP32C3 + default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 help GPIO number for I2C Master clock line. config I2C_MASTER_SDA int "SDA GPIO Num" - default 18 + default 5 if IDF_TARGET_ESP32C3 + default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 help GPIO number for I2C Master data line. config I2C_MASTER_PORT_NUM int "Port Number" - default 1 + default 1 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 + default 0 if IDF_TARGET_ESP32C3 help Port number for I2C Master device. diff --git a/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c b/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c index 7b7928c1ad..0f30e6c020 100644 --- a/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c +++ b/examples/peripherals/i2c/i2c_self_test/main/i2c_example_main.c @@ -58,8 +58,9 @@ SemaphoreHandle_t print_mux = NULL; * | 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 i2c_master_read_slave(i2c_port_t i2c_num, uint8_t *data_rd, size_t size) +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; @@ -87,8 +88,9 @@ static esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t *data_rd, siz * | 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 i2c_master_write_slave(i2c_port_t i2c_num, uint8_t *data_wr, size_t size) +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); @@ -160,6 +162,7 @@ static esp_err_t i2c_master_init(void) return i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0); } +#if !CONFIG_IDF_TARGET_ESP32C3 /** * @brief i2c slave initialization */ @@ -196,15 +199,18 @@ static void disp_buf(uint8_t *buf, int len) } printf("\n"); } +#endif //!CONFIG_IDF_TARGET_ESP32C3 static void i2c_test_task(void *arg) { - int i = 0; int ret; uint32_t task_idx = (uint32_t)arg; +#if !CONFIG_IDF_TARGET_ESP32C3 + 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) { @@ -226,6 +232,7 @@ static void i2c_test_task(void *arg) xSemaphoreGive(print_mux); vTaskDelay((DELAY_TIME_BETWEEN_ITEMS_MS * (task_idx + 1)) / portTICK_RATE_MS); //--------------------------------------------------- +#if !CONFIG_IDF_TARGET_ESP32C3 for (i = 0; i < DATA_LENGTH; i++) { data[i] = i; } @@ -281,6 +288,7 @@ static void i2c_test_task(void *arg) } xSemaphoreGive(print_mux); vTaskDelay((DELAY_TIME_BETWEEN_ITEMS_MS * (task_idx + 1)) / portTICK_RATE_MS); +#endif //!CONFIG_IDF_TARGET_ESP32C3 } vSemaphoreDelete(print_mux); vTaskDelete(NULL); @@ -289,7 +297,9 @@ static void i2c_test_task(void *arg) void app_main(void) { print_mux = xSemaphoreCreateMutex(); +#if !CONFIG_IDF_TARGET_ESP32C3 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);