diff --git a/.gitignore b/.gitignore index be9c698c940..5114d19da5c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ boards.sloeber.txt # Ignore docs build (Sphinx) docs/build +docs/source/_build diff --git a/docs/source/_static/arduino_i2c_master.png b/docs/source/_static/arduino_i2c_master.png new file mode 100644 index 00000000000..7381159cdad Binary files /dev/null and b/docs/source/_static/arduino_i2c_master.png differ diff --git a/docs/source/_static/arduino_i2c_slave.png b/docs/source/_static/arduino_i2c_slave.png new file mode 100644 index 00000000000..277261f3404 Binary files /dev/null and b/docs/source/_static/arduino_i2c_slave.png differ diff --git a/docs/source/api/i2c.rst b/docs/source/api/i2c.rst new file mode 100644 index 00000000000..4c690488e28 --- /dev/null +++ b/docs/source/api/i2c.rst @@ -0,0 +1,384 @@ +### +I2C +### + +About +----- + +I2C (Inter-Integrated Circuit) / TWI (Two-wire Interface) is a widely used serial communication to connect devices in a short distance. This is one of the most common peripherals used to connect sensors, EEPROMs, RTC, ADC, DAC, displays, OLED, and many other devices and microcontrollers. + +This serial communication is considered as a low-speed bus, and multiple devices can be connected on the same two-wires bus, each with a unique 7-bits address (up to 128 devices). These two wires are called SDA (serial data line) and SCL (serial clock line). + +.. note:: The SDA and SCL lines require pull-up resistors. See the device datasheet for more details about the resistors' values and the operating voltage. + +I2C Modes +********* + +The I2C can be used in two different modes: + +* **I2C Master Mode** + * In this mode, the ESP32 generates the clock signal and initiates the communication with the slave device. + +.. figure:: ../_static/arduino_i2c_master.png + :align: center + :width: 720 + :figclass: align-center + +* **I2C Slave Mode** + * The slave mode, the clock is generated by the master device and responds to the master if the destination address is the same as the destination. + +.. figure:: ../_static/arduino_i2c_slave.png + :align: center + :width: 520 + :figclass: align-center + +Arduino-ESP32 I2C API +--------------------- + +The ESP32 I2C library is based on the `Arduino Wire Library`_ and implements a few more APIs, described in this documentation. + +I2C Common API +************** + +Here are the common functions used for master and slave modes. + +begin +^^^^^ + +This function is used to start the peripheral using the default configuration. + +.. code-block:: arduino + + bool begin(); + +This function will return ``true`` if the peripheral was initialized correctly. + +setPins +^^^^^^^ + +This function is used to define the ``SDA`` and ``SCL`` pins. + +.. note:: Call this function before ``begin`` to change the pins from the default ones. + +.. code-block:: arduino + + bool setPins(int sdaPin, int sclPin); + +* ``sdaPin`` sets the GPIO to be used as the I2C peripheral data line. + +* ``sclPin`` sets the GPIO to be used as the I2C peripheral clock line. + +The default pins may vary from board to board. On the *Generic ESP32* the default I2C pins are: + +* ``sdaPin`` **GPIO21** + +* ``sclPin`` **GPIO22** + +This function will return ``true`` if the peripheral was configured correctly. + +setClock +^^^^^^^^ + +Use this function to set the bus clock. The default value will be used if this function is not used. + +.. code-block:: arduino + + bool setClock(uint32_t frequency); + +* ``frequency`` sets the bus frequency clock. + +This function will return ``true`` if the clock was configured correctly. + +getClock +^^^^^^^^ + +Use this function to get the bus clock. + +.. code-block:: arduino + + uint32_t getClock(); + +This function will return the current frequency configuration. + +setTimeOut +^^^^^^^^^^ + +Set the bus timeout given in milliseconds. The default value is 50ms. + +.. code-block:: arduino + + void setTimeOut(uint16_t timeOutMillis); + +* ``timeOutMillis`` sets the timeout in ms. + +getTimeOut +^^^^^^^^^^ + +Get the bus timeout in milliseconds. + +.. code-block:: arduino + + uint16_t getTimeOut(); + +This function will return the current timeout configuration. + +.. _i2c write: + +write +^^^^^ + +This function writes data to the buffer. + +.. code-block:: arduino + + size_t write(uint8_t); + +or + +.. code-block:: arduino + + size_t write(const uint8_t *, size_t); + +The return will be the size of the data added to the buffer. + +.. _i2c end: + +end +^^^ + +This function will finish the communication and release all the allocated resources. After calling ``end`` you need to use ``begin`` again in order to initialize the I2C driver again. + +.. code-block:: arduino + + bool end(); + + +I2C Master Mode +*************** + +This mode is used to initiate communication to the slave. + +Basic Usage +^^^^^^^^^^^ + +To start using I2C master mode on the Arduino, the first step is to include the ``Wire.h`` header to the sketch. + +.. code-block:: arduino + + #include "Wire.h" + +Now, we can start the peripheral configuration by calling ``begin`` function. + +.. code-block:: arduino + + Wire.begin(); + +By using ``begin`` without any arguments, all the settings will be done by using the default values. To set the values by your own, see the function description. This function is described here: `i2c begin`_ + +After calling ``begin``, we can start the transmission by calling ``beginTransmission`` and passing the I2C slave address: + +.. code-block:: arduino + + Wire.beginTransmission(I2C_DEV_ADDR); + +To write some bytes to the slave, use the ``write`` function. + +.. code-block:: arduino + + Wire.write(x); + +You can pass different data types using ``write`` function. This function is described here: `i2c write`_ + +.. note:: The ``write`` function does not write directly to the slave device but adds to the I2C buffer. To do so, you need to use the ``endTransmission`` function to send the buffered bytes to the slave device. + +.. code-block:: arduino + + Wire.endTransmission(true); + +After calling ``endTransmission``, the data stored in the I2C buffer will be transmitted to the slave device. + +Now you can request a reading from the slave device. The ``requestFrom`` will ask for a readout to the selected device by giving the address and the size. + +.. code-block:: arduino + + Wire.requestFrom(I2C_DEV_ADDR, SIZE); + +and the ``readBytes`` will read it. + +.. code-block:: arduino + + Wire.readBytes(temp, error); + +.. _i2c begin: + +I2C Master APIs +*************** + +Here are the I2C master APIs. These function are intended to be used only for master mode. + +begin +^^^^^ + +In master mode, the ``begin`` function can be used by passing the **pins** and **bus frequency**. Use this function only for the master mode. + +.. code-block:: arduino + + bool begin(int sdaPin, int sclPin, uint32_t frequency) + +Alternatively, you can use the ``begin`` function without any argument to use all default values. + +This function will return ``true`` if the peripheral was initialized correctly. + +beginTransmission +^^^^^^^^^^^^^^^^^ + +This function is used to star a communication process with the slave device. Call this function by passing the slave ``address`` before writing the message to the buffer. + +.. code-block:: arduino + + void beginTransmission(uint16_t address) + +endTransmission +^^^^^^^^^^^^^^^ + +After writing to the buffer using `i2c write`_, use the function ``endTransmission`` to send the message to the slave device address defined on the ``beginTransmission`` function. + +.. code-block:: arduino + + uint8_t endTransmission(bool sendStop); + +* ``sendStop`` enables **(true)** or disables **(false)** the stop signal *(only used in master mode)*. + +Calling the this function without ``sendStop`` is equivalent to ``sendStop = true``. + +.. code-block:: arduino + + uint8_t endTransmission(void); + +This function will return the error code. + +requestFrom +^^^^^^^^^^^ + +To read from the slave device, use the ``requestFrom`` function. + +.. code-block:: arduino + + uint8_t requestFrom(uint16_t address, uint8_t size, bool sendStop) + +* ``address`` set the device address. + +* ``size`` define the size to be requested. + +* ``sendStop`` enables (true) or disables (false) the stop signal. + +This function will return the number of bytes read from the device. + +Example Application - WireMaster.ino +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Here is an example of how to use the I2C in Master Mode. + +.. literalinclude:: ../../../libraries/Wire/examples/WireMaster/WireMaster.ino + :language: arduino + + +I2C Slave Mode +************** + +This mode is used to accept communication from the master. + +Basic Usage +^^^^^^^^^^^ + +To start using I2C as slave mode on the Arduino, the first step is to include the ``Wire.h`` header to the scketch. + +.. code-block:: arduino + + #include "Wire.h" + +Before calling ``begin`` we must create two callback functions to handle the communication with the master device. + +.. code-block:: arduino + + Wire.onReceive(onReceive); + +and + +.. code-block:: arduino + + Wire.onRequest(onRequest); + +The ``onReceive`` will handle the request from the master device uppon a slave read request and the ``onRequest`` will handle the answer to the master. + +Now, we can start the peripheral configuration by calling ``begin`` function with the device address. + +.. code-block:: arduino + + Wire.begin((uint8_t)I2C_DEV_ADDR); + +By using ``begin`` without any arguments, all the settings will be done by using the default values. To set the values by your own, see the function description. This function is described here: `i2c begin`_ + + +**For ESP32 only!** + +Use the function ``slaveWrite`` in order to pre-write to the slave response buffer. This is used only for the ESP32 in order to add the slave capability on the chip and keep compatability with Arduino. + +.. code-block:: arduino + + Wire.slaveWrite((uint8_t *)message, strlen(message)); + +I2C Slave APIs +************** + +Here are the I2C slave APIs. These function are intended to be used only for slave mode. + +begin +^^^^^ + +In slave mode, the ``begin`` function must be used by passing the **slave address**. You can also define the **pins** and the **bus frequency**. + +.. code-block:: arduino + + bool Wire.begin(uint8_t addr, int sdaPin, int sclPin, uint32_t frequency) + +This function will return ``true`` if the peripheral was initialized correctly. + +onReceive +^^^^^^^^^ + +The ``onReceive`` function is used to define the callback for the data received from the master. + +.. code-block:: arduino + + void onReceive( void (*)(int) ); + +onRequest +^^^^^^^^^ + +The ``onRequest`` function is used to define the callback for the data to be send to the master. + +.. code-block:: arduino + + void onRequest( void (*)(void) ); + +slaveWrite +^^^^^^^^^^ + +The ``slaveWrite`` function writes on the slave response buffer before receiving the response message. This function is only used for adding the slave compatability for the ESP32. + +.. warning:: This function is only required for the ESP32. You **don't** need to use for ESP32-S2 and ESP32-C3. + +.. code-block:: arduino + + size_t slaveWrite(const uint8_t *, size_t); + +Example Application - WireSlave.ino +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Here is an example of how to use the I2C in Slave Mode. + +.. literalinclude:: ../../../libraries/Wire/examples/WireSlave/WireSlave.ino + :language: arduino + +.. _Arduino Wire Library: https://www.arduino.cc/en/reference/wire \ No newline at end of file diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 89b5d9cc34b..cb9093df06d 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -2,7 +2,7 @@ Libraries ######### -Here is where the Libraries API's descriptions are located. +Here is where the Libraries API's descriptions are located: .. toctree:: :maxdepth: 1 @@ -12,6 +12,7 @@ Here is where the Libraries API's descriptions are located. Deep Sleep ESPNOW GPIO + I2C RainMaker Reset Reason Wi-Fi