You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -36,6 +36,14 @@ Typically, an I2C slave device has a 7-bit address or 10-bit address. {IDF_TARGE
36
36
37
37
Keep in mind that the higher the frequency, the smaller the pull-up resistor should be (but not less than 1 kΩ). Indeed, large resistors will decline the current, which will increase the clock switching time and reduce the frequency. A range of 2 kΩ to 5 kΩ is recommended, but adjustments may also be necessary depending on their current draw requirements.
38
38
39
+
.. toctree::
40
+
:hidden:
41
+
42
+
i2c_slave_v1
43
+
44
+
.. note::
45
+
46
+
We realized that our first version of the I2C slave driver had some problems and was not easy to use, so we have prepared a second version of the I2C slave driver, which solves many of the problems with our current I2C slave and which will be the focus of our maintenance. We encourage and recommend that you use the second version of the I2C slave driver, which you can do by enabling :ref:`CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2`. This document focuses on the content of I2C slave v2.0. If you still want to read programming guide of I2C slave v1.0, please refer to :ref:`i2c-slave-v1`. The I2C slave v1.0 driver will be removed with the IDF v6.0 update.
39
47
40
48
I2C Clock Configuration
41
49
-----------------------
@@ -218,27 +226,26 @@ I2C slave requires the configuration specified by :cpp:type:`i2c_slave_config_t`
218
226
- :cpp:member:`i2c_slave_config_t::sda_io_num` sets the GPIO number for serial data bus (SDA).
219
227
- :cpp:member:`i2c_slave_config_t::scl_io_num` sets the GPIO number for serial clock bus (SCL).
220
228
- :cpp:member:`i2c_slave_config_t::clk_source` selects the source clock for I2C bus. The available clocks are listed in :cpp:type:`i2c_clock_source_t`. For the effect on power consumption of different clock source, please refer to `Power Management <#power-management>`__ section.
221
-
- :cpp:member:`i2c_slave_config_t::send_buf_depth` sets the sending buffer length.
222
-
- :cpp:member:`i2c_slave_config_t::slave_addr` sets the slave address.
223
-
- :cpp:member:`i2c_master_bus_config_t::intr_priority` sets the priority of the interrupt. If set to ``0`` , then the driver will use a interrupt with low or medium priority (priority level may be one of 1, 2 or 3), otherwise use the priority indicated by :cpp:member:`i2c_master_bus_config_t::intr_priority`. Please use the number form (1, 2, 3), instead of the bitmask form ((1<<1), (1<<2), (1<<3)). Please pay attention that once the interrupt priority is set, it cannot be changed until :cpp:func:`i2c_del_master_bus` is called.
224
-
- :cpp:member:`i2c_slave_config_t::addr_bit_len`. Set this variable to ``I2C_ADDR_BIT_LEN_10`` if the slave should have a 10-bit address.
225
-
:SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE: - :cpp:member:`i2c_slave_config_t::stretch_en`. Set this variable to true, then the slave controller stretch will work. Please refer to [`TRM <{IDF_TARGET_TRM_EN_URL}#i2c>`__] to learn how I2C stretch works.
226
-
:SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE: - :cpp:member:`i2c_slave_config_t::broadcast_en`. Set this to true to enable the slave broadcast. When the slave receives the general call address 0x00 from the master and the R/W bit followed is 0, it responds to the master regardless of its own address.
227
-
:SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS: - :cpp:member:`i2c_slave_config_t::access_ram_en`. Set this to true to enable the non-FIFO mode. Thus the I2C data FIFO can be used as RAM, and double addressing will be synchronised opened.
228
-
:SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH: - :cpp:member:`i2c_slave_config_t::slave_unmatch_en`. Set this to true to enable the slave unmatch interrupt. If the command address sent by master can't match the slave address, then unmatch interrupt will be triggered.
229
+
- :cpp:member:`i2c_slave_config_t::send_buf_depth` sets the sending software buffer length.
230
+
- :cpp:member:`i2c_slave_config_t::receive_buf_depth` sets the receiving software buffer length.
231
+
- :cpp:member:`i2c_slave_config_t::intr_priority` sets the priority of the interrupt. If set to ``0`` , then the driver will use a interrupt with low or medium priority (priority level may be one of 1, 2 or 3), otherwise use the priority indicated by :cpp:member:`i2c_slave_config_t::intr_priority`. Please use the number form (1, 2, 3), instead of the bitmask form ((1<<1), (1<<2), (1<<3)). Please pay attention that once the interrupt priority is set, it cannot be changed until :cpp:func:`i2c_del_slave_device` is called.
232
+
- :cpp:member:`i2c_slave_config_t::addr_bit_len` Set this variable to ``I2C_ADDR_BIT_LEN_10`` if the slave should have a 10-bit address.
233
+
- :cpp:member:`i2c_slave_config_t::allow_pd` If set, the driver will backup/restore the I2C registers before/after entering/exist sleep mode. By this approach, the system can power off I2C's power domain. This can save power, but at the expense of more RAM being consumed.
234
+
:SOC_I2C_SLAVE_SUPPORT_BROADCAST: - :cpp:member:`i2c_slave_config_t::broadcast_en` Set this to true to enable the slave broadcast. When the slave receives the general call address 0x00 from the master and the R/W bit followed is 0, it responds to the master regardless of its own address.
235
+
- :cpp:member:`i2c_slave_config_t::enable_internal_pullup` Set this to enable internal pull-up. Even though, an output pull-up resistance is strongly recommended.
229
236
230
237
Once the :cpp:type:`i2c_slave_config_t` structure is populated with mandatory parameters, :cpp:func:`i2c_new_slave_device` can be called to allocate and initialize an I2C master bus. This function will return an I2C bus handle if it runs correctly. Specifically, when there are no more I2C port available, this function will return :c:macro:`ESP_ERR_NOT_FOUND` error.
231
238
232
239
.. code:: c
233
240
234
241
i2c_slave_config_t i2c_slv_config = {
235
-
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
242
+
.i2c_port = I2C_SLAVE_NUM,
236
243
.clk_source = I2C_CLK_SRC_DEFAULT,
237
-
.i2c_port = TEST_I2C_PORT,
238
-
.send_buf_depth = 256,
239
244
.scl_io_num = I2C_SLAVE_SCL_IO,
240
245
.sda_io_num = I2C_SLAVE_SDA_IO,
241
-
.slave_addr = 0x58,
246
+
.slave_addr = ESP_SLAVE_ADDR,
247
+
.send_buf_depth = 100,
248
+
.receive_buf_depth = 100,
242
249
};
243
250
244
251
i2c_slave_dev_handle_t slave_handle;
@@ -437,142 +444,72 @@ I2C Slave Controller
437
444
438
445
After installing the I2C slave driver by :cpp:func:`i2c_new_slave_device`, {IDF_TARGET_NAME} is ready to communicate with other I2C masters as a slave.
439
446
447
+
The I2C slave is not as subjective as the I2C master which knows when it should send data and when it should receive data. The I2C slave is very passive in most cases, that means the I2C slave's ability to send and receive data is largely dependent on the master's actions. Therefore, we throw two callback functions in the driver that represent read requests and write requests from the I2C master.
448
+
440
449
I2C Slave Write
441
450
~~~~~~~~~~~~~~~
442
451
443
-
The send buffer of the I2C slave is used as a FIFO to store the data to be sent. The data will queue up until the master requests them. You can call :cpp:func:`i2c_slave_transmit` to transfer data.
452
+
You can get I2C slave write event be register :cpp:member:`i2c_slave_event_callbacks_t::on_request` callback, and in a task when get the request event, you can call `i2c_slave_write` to send data.
Whenever the master writes data to the slave, the slave will automatically store data in the receive buffer. This allows the slave application to call the function :cpp:func:`i2c_slave_receive` as its own discretion. As :cpp:func:`i2c_slave_receive` is designed as a non-blocking interface, users need to register callback :cpp:func:`i2c_slave_register_event_callbacks` to know when the receive has finished.
492
+
Same as write, you can get I2C slave read event be register :cpp:member:`i2c_slave_event_callbacks_t::on_receive` callback, and in a task when get the request event, you can save the data and do what you want.
I2C slave FIFO mentioned above can be used as RAM, which means user can access the RAM directly via address fields. For example, write data to the third RAM block with following graph. Before using this, please note that :cpp:member:`i2c_slave_config_t::access_ram_en` needs to be set to true.
Data can be stored in the RAM with a specific offset by the slave controller, and the master can read this data directly via the RAM address. For example, if the data is stored in the third RAM block, master can read this data by the following graph. Before using this, please note that :cpp:member:`i2c_slave_config_t::access_ram_en` needs to be set to true.
@@ -601,8 +538,8 @@ I2C slave event callbacks are listed in the :cpp:type:`i2c_slave_event_callbacks
601
538
602
539
.. list::
603
540
604
-
- :cpp:member:`i2c_slave_event_callbacks_t::on_recv_done` sets a callback function for "receive-done" event. The function prototype is declared in :cpp:type:`i2c_slave_received_callback_t`.
605
-
:SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE:- :cpp:member:`i2c_slave_event_callbacks_t::on_stretch_occur` sets a callback function for "stretch" cause. The function prototype is declared in :cpp:type:`i2c_slave_stretch_callback_t`.
541
+
- :cpp:member:`i2c_slave_event_callbacks_t::on_request` sets a callback function for request event.
542
+
- :cpp:member:`i2c_slave_event_callbacks_t::on_receive` sets a callback function for receive event. The function prototype is declared in :cpp:type:`i2c_slave_received_callback_t`.
606
543
607
544
Power Management
608
545
^^^^^^^^^^^^^^^^
@@ -637,13 +574,28 @@ This will allow the interrupt to run while the cache is disabled but will come a
637
574
Thread Safety
638
575
^^^^^^^^^^^^^
639
576
640
-
The factory function :cpp:func:`i2c_new_master_bus` and :cpp:func:`i2c_new_slave_device` are guaranteed to be thread safe by the driver, which means that the functions can be called from different RTOS tasks without protection by extra locks. Other public I2C APIs are not thread safe, which means the user should avoid calling them from multiple tasks, if it is necessary to call them in multiple tasks, please add extra locks.
577
+
The factory function :cpp:func:`i2c_new_master_bus` and :cpp:func:`i2c_new_slave_device` are guaranteed to be thread safe by the driver, which means that the functions can be called from different RTOS tasks without protection by extra locks.
578
+
579
+
I2C master operation functions are also guaranteed to be thread safe by bus operation semaphore.
580
+
581
+
- :cpp:func:`i2c_master_transmit`
582
+
- :cpp:func:`i2c_master_multi_buffer_transmit`
583
+
- :cpp:func:`i2c_master_transmit_receive`
584
+
- :cpp:func:`i2c_master_receive`
585
+
- :cpp:func:`i2c_master_probe`
586
+
587
+
I2C slave operation functions are also guaranteed to be thread safe by bus operation semaphore.
588
+
589
+
- :cpp:func:`i2c_slave_write`
590
+
591
+
Other functions are not guaranteed to be thread-safe. Thus, you should avoid calling them in different tasks without mutex protection.
641
592
642
593
Kconfig Options
643
594
^^^^^^^^^^^^^^^
644
595
645
596
- :ref:`CONFIG_I2C_ISR_IRAM_SAFE` controls whether the default ISR handler can work when cache is disabled, see also `IRAM Safe <#iram-safe>`__ for more information.
646
597
- :ref:`CONFIG_I2C_ENABLE_DEBUG_LOG` is used to enable the debug log at the cost of increased firmware binary size.
598
+
- :ref:`CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2` is used to enable the I2C slave driver v2.0.
647
599
648
600
Application Examples
649
601
--------------------
@@ -652,6 +604,7 @@ Application Examples
652
604
653
605
- :example:`peripherals/i2c/i2c_tools` demonstrates how to use the I2C Tools for developing I2C related applications, providing command-line tools for configuring the I2C bus, scanning for devices, reading and setting registers, and examining registers.
654
606
607
+
- :example:`peripherals/i2c/i2c_slave_network_sensor` demonstrates how to use the I2C slave for developing I2C related applications, providing how I2C slave can behave as a network sensor, and use event callbacks to receive and send data.
0 commit comments