mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-10 18:06:29 +00:00
docs: fix broken references to misc API functions and types.
This commit is contained in:
@@ -133,7 +133,7 @@ Ethernet driver is composed of two parts: MAC and PHY.
|
||||
* Some EMAC controller can generate the ``REF_CLK`` using its internal high precision PLL (as seen the option *c* in the picture). In this case, you should select ``CONFIG_ETH_RMII_CLK_OUTPUT`` in :ref:`CONFIG_ETH_RMII_CLK_MODE`.
|
||||
|
||||
.. note::
|
||||
``REF_CLK`` is configured via Project Configuration as described above by default. However, it can be overwritten from user application code by appropriately setting :cpp:member:`interface` and :cpp:member:`clock_config` members of :cpp:class:`eth_mac_config_t` structure. See :cpp:enum:`emac_rmii_clock_mode_t` and :cpp:enum:`emac_rmii_clock_gpio_t` for more details.
|
||||
``REF_CLK`` is configured via Project Configuration as described above by default. However, it can be overwritten from user application code by appropriately setting :cpp:member:`eth_esp32_emac_config_t::interface` and :cpp:member:`eth_esp32_emac_config_t::clock_config` members. See :cpp:enum:`emac_rmii_clock_mode_t` and :cpp:enum:`emac_rmii_clock_gpio_t` for more details.
|
||||
|
||||
.. warning::
|
||||
If the RMII clock mode is selected to ``CONFIG_ETH_RMII_CLK_OUTPUT``, then ``GPIO0`` can be used to output the ``REF_CLK`` signal. See :ref:`CONFIG_ETH_RMII_CLK_OUTPUT_GPIO0` for more information.
|
||||
@@ -164,21 +164,21 @@ Configuration for MAC is described in :cpp:class:`eth_mac_config_t`, including:
|
||||
|
||||
.. list::
|
||||
|
||||
* :cpp:member:`sw_reset_timeout_ms`: software reset timeout value, in milliseconds, typically MAC reset should be finished within 100ms.
|
||||
* :cpp:member:`rx_task_stack_size` and :cpp:member:`rx_task_prio`: the MAC driver creates a dedicated task to process incoming packets, these two parameters are used to set the stack size and priority of the task.
|
||||
* :cpp:member:`flags`: specifying extra features that the MAC driver should have, it could be useful in some special situations. The value of this field can be OR'd with macros prefixed with ``ETH_MAC_FLAG_``. For example, if the MAC driver should work when cache is disabled, then you should configure this field with :c:macro:`ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE`.
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`smi_mdc_gpio_num` and :cpp:member:`smi_mdio_gpio_num`: the GPIO number used to connect the SMI signals.
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`interface`: configuration of MAC Data interface to PHY (MII/RMII).
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`clock_config`: configuration of EMAC Interface clock (``REF_CLK`` mode and GPIO number in case of RMII).
|
||||
* :cpp:member:`eth_mac_config_t::sw_reset_timeout_ms`: software reset timeout value, in milliseconds, typically MAC reset should be finished within 100ms.
|
||||
* :cpp:member:`eth_mac_config_t::rx_task_stack_size` and :cpp:member:`eth_mac_config_t::rx_task_prio`: the MAC driver creates a dedicated task to process incoming packets, these two parameters are used to set the stack size and priority of the task.
|
||||
* :cpp:member:`eth_mac_config_t::flags`: specifying extra features that the MAC driver should have, it could be useful in some special situations. The value of this field can be OR'd with macros prefixed with ``ETH_MAC_FLAG_``. For example, if the MAC driver should work when cache is disabled, then you should configure this field with :c:macro:`ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE`.
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::smi_mdc_gpio_num` and :cpp:member:`eth_esp32_emac_config_t::smi_mdio_gpio_num`: the GPIO number used to connect the SMI signals.
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::interface`: configuration of MAC Data interface to PHY (MII/RMII).
|
||||
:SOC_EMAC_SUPPORTED: * :cpp:member:`eth_esp32_emac_config_t::clock_config`: configuration of EMAC Interface clock (``REF_CLK`` mode and GPIO number in case of RMII).
|
||||
|
||||
Configuration for PHY is described in :cpp:class:`eth_phy_config_t`, including:
|
||||
|
||||
.. list::
|
||||
|
||||
* :cpp:member:`phy_addr`: multiple PHY device can share the same SMI bus, so each PHY needs a unique address. Usually this address is configured during hardware design by pulling up/down some PHY strapping pins. You can set the value from 0 to 15 based on your Ethernet board. Especially, if the SMI bus is shared by only one PHY device, setting this value to -1 can enable the driver to detect the PHY address automatically.
|
||||
* :cpp:member:`reset_timeout_ms`: reset timeout value, in milliseconds, typically PHY reset should be finished within 100ms.
|
||||
* :cpp:member:`autonego_timeout_ms`: auto-negotiation timeout value, in milliseconds. Ethernet driver will start negotiation with the peer Ethernet node automatically, to determine to duplex and speed mode. This value usually depends on the ability of the PHY device on your board.
|
||||
* :cpp:member:`reset_gpio_num`: if your board also connect the PHY reset pin to one of the GPIO, then set it here. Otherwise, set this field to -1.
|
||||
* :cpp:member:`eth_phy_config_t::phy_addr`: multiple PHY device can share the same SMI bus, so each PHY needs a unique address. Usually this address is configured during hardware design by pulling up/down some PHY strapping pins. You can set the value from 0 to 15 based on your Ethernet board. Especially, if the SMI bus is shared by only one PHY device, setting this value to -1 can enable the driver to detect the PHY address automatically.
|
||||
* :cpp:member:`eth_phy_config_t::reset_timeout_ms`: reset timeout value, in milliseconds, typically PHY reset should be finished within 100ms.
|
||||
* :cpp:member:`eth_phy_config_t::autonego_timeout_ms`: auto-negotiation timeout value, in milliseconds. Ethernet driver will start negotiation with the peer Ethernet node automatically, to determine to duplex and speed mode. This value usually depends on the ability of the PHY device on your board.
|
||||
* :cpp:member:`eth_phy_config_t::reset_gpio_num`: if your board also connect the PHY reset pin to one of the GPIO, then set it here. Otherwise, set this field to -1.
|
||||
|
||||
ESP-IDF provides a default configuration for MAC and PHY in macro :c:macro:`ETH_MAC_DEFAULT_CONFIG` and :c:macro:`ETH_PHY_DEFAULT_CONFIG`.
|
||||
|
||||
@@ -281,11 +281,11 @@ Install Driver
|
||||
|
||||
To install the Ethernet driver, we need to combine the instance of MAC and PHY and set some additional high-level configurations (i.e. not specific to either MAC or PHY) in :cpp:class:`esp_eth_config_t`:
|
||||
|
||||
* :cpp:member:`mac`: instance that created from MAC generator (e.g. :cpp:func:`esp_eth_mac_new_esp32`).
|
||||
* :cpp:member:`phy`: instance that created from PHY generator (e.g. :cpp:func:`esp_eth_phy_new_ip101`).
|
||||
* :cpp:member:`check_link_period_ms`: Ethernet driver starts an OS timer to check the link status periodically, this field is used to set the interval, in milliseconds.
|
||||
* :cpp:member:`stack_input`: In most of Ethernet IoT applications, any Ethernet frame that received by driver should be passed to upper layer (e.g. TCP/IP stack). This field is set to a function which is responsible to deal with the incoming frames. You can even update this field at runtime via function :cpp:func:`esp_eth_update_input_path` after driver installation.
|
||||
* :cpp:member:`on_lowlevel_init_done` and :cpp:member:`on_lowlevel_deinit_done`: These two fields are used to specify the hooks which get invoked when low level hardware has been initialized or de-initialized.
|
||||
* :cpp:member:`esp_eth_config_t::mac`: instance that created from MAC generator (e.g. :cpp:func:`esp_eth_mac_new_esp32`).
|
||||
* :cpp:member:`esp_eth_config_t::phy`: instance that created from PHY generator (e.g. :cpp:func:`esp_eth_phy_new_ip101`).
|
||||
* :cpp:member:`esp_eth_config_t::check_link_period_ms`: Ethernet driver starts an OS timer to check the link status periodically, this field is used to set the interval, in milliseconds.
|
||||
* :cpp:member:`esp_eth_config_t::stack_input`: In most of Ethernet IoT applications, any Ethernet frame that received by driver should be passed to upper layer (e.g. TCP/IP stack). This field is set to a function which is responsible to deal with the incoming frames. You can even update this field at runtime via function :cpp:func:`esp_eth_update_input_path` after driver installation.
|
||||
* :cpp:member:`esp_eth_config_t::on_lowlevel_init_done` and :cpp:member:`esp_eth_config_t::on_lowlevel_deinit_done`: These two fields are used to specify the hooks which get invoked when low level hardware has been initialized or de-initialized.
|
||||
|
||||
ESP-IDF provides a default configuration for driver installation in macro :c:macro:`ETH_DEFAULT_CONFIG`.
|
||||
|
||||
|
||||
@@ -142,10 +142,10 @@ Network stack has no public interaction with application code with regard to pub
|
||||
|
||||
E) ESP-NETIF L2 TAP Interface
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The ESP-NETIF L2 TAP interface is ESP-IDF mechanism utilized to access Data Link Layer (L2 per OSI/ISO) for frame reception and transmission from user application. Its typical usage in embedded world might be implementation of non-IP related protocols such as PTP, Wake on LAN and others. Note that only Ethernet (IEEE 802.3) is currently supported.
|
||||
The ESP-NETIF L2 TAP interface is ESP-IDF mechanism utilized to access Data Link Layer (L2 per OSI/ISO) for frame reception and transmission from user application. Its typical usage in embedded world might be implementation of non-IP related protocols such as PTP, Wake on LAN and others. Note that only Ethernet (IEEE 802.3) is currently supported.
|
||||
|
||||
From user perspective, the ESP-NETIF L2 TAP interface is accessed using file descriptors of VFS which provides a file-like interfacing (using functions like ``open()``, ``read()``, ``write()``, etc). Refer to :doc:`/api-reference/storage/vfs` to learn more.
|
||||
|
||||
|
||||
There is only one ESP-NETIF L2 TAP interface device (path name) available. However multiple file descriptors with different configuration can be opened at a time since the ESP-NETIF L2 TAP interface can be understood as generic entry point to the NETIF internal structure. Important is then specific configuration of particular file descriptor. It can be configured to give an access to specific Network Interface identified by ``if_key`` (e.g. `ETH_DEF`) and to filter only specific frames based on their type (e.g. Ethernet type in case of IEEE 802.3). Filtering only specific frames is crucial since the ESP-NETIF L2 TAP needs to work along with IP stack and so the IP related traffic (IP, ARP, etc.) should not be passed directly to the user application. Even though such option is still configurable, it is not recommended in standard use cases. Filtering is also advantageous from a perspective the user’s application gets access only to frame types it is interested in and the remaining traffic is either passed to other L2 TAP file descriptors or to IP stack.
|
||||
|
||||
ESP-NETIF L2 TAP Interface Usage Manual
|
||||
@@ -153,7 +153,7 @@ ESP-NETIF L2 TAP Interface Usage Manual
|
||||
|
||||
Initialization
|
||||
^^^^^^^^^^^^^^
|
||||
To be able to use the ESP-NETIF L2 TAP interface, it needs to be enabled in Kconfig by :ref:`CONFIG_ESP_NETIF_L2_TAP` first and then registered by :cpp:func:`esp_vfs_l2tap_intf_register()` prior usage of any VFS function.
|
||||
To be able to use the ESP-NETIF L2 TAP interface, it needs to be enabled in Kconfig by :ref:`CONFIG_ESP_NETIF_L2_TAP` first and then registered by :cpp:func:`esp_vfs_l2tap_intf_register()` prior usage of any VFS function.
|
||||
|
||||
open()
|
||||
^^^^^^
|
||||
@@ -177,7 +177,7 @@ All set configuration options have getter counterpart option to read the current
|
||||
|
||||
| On success, ``ioctl()`` returns 0. On error, -1 is returned, and ``errno`` is set to indicate the error.
|
||||
| **EBADF** - not a valid file descriptor.
|
||||
| **EINVAL** - invalid configuration argument. Ethernet type filter is already used by other file descriptor.
|
||||
| **EINVAL** - invalid configuration argument. Ethernet type filter is already used by other file descriptor.
|
||||
| **ENODEV** - no such Network Interface which is tried to be assigned to the file descriptor exists.
|
||||
| **ENOSPC** - NETIF L2 receive hook is already taken by other function when trying to assign Network Interface to the file descriptor.
|
||||
| **ENOSYS** - unsupported operation, passed configuration option does not exists.
|
||||
@@ -201,7 +201,7 @@ A raw Data Link Layer frame can be sent to Network Interface via opened and conf
|
||||
+-------------------+-------------------+-------------+------------------------------- --+
|
||||
6B 6B 2B 0-1486B
|
||||
|
||||
In other words, there is no additional frame processing performed by the ESP-NETIF L2 TAP interface. It only checks the Ethernet type of the frame is the same as the filter configured in the file descriptor. If the Ethernet type is different, an error is returned and the frame is not sent. Note that the ``write()`` may block in current implementation when accessing a Network interface since it is a shared resource among multiple ESP-NETIF L2 TAP file descriptors and IP stack, and there is currently no queuing mechanism deployed.
|
||||
In other words, there is no additional frame processing performed by the ESP-NETIF L2 TAP interface. It only checks the Ethernet type of the frame is the same as the filter configured in the file descriptor. If the Ethernet type is different, an error is returned and the frame is not sent. Note that the ``write()`` may block in current implementation when accessing a Network interface since it is a shared resource among multiple ESP-NETIF L2 TAP file descriptors and IP stack, and there is currently no queuing mechanism deployed.
|
||||
|
||||
| On success, ``write()`` returns the number of bytes written. Zero is returned when size of the input buffer is 0. On error, -1 is returned, and ``errno`` is set to indicate the error.
|
||||
| **EBADF** - not a valid file descriptor.
|
||||
@@ -210,7 +210,7 @@ In other words, there is no additional frame processing performed by the ESP-NET
|
||||
|
||||
close()
|
||||
^^^^^^^
|
||||
Opened ESP-NETIF L2 TAP file descriptor can be closed by the ``close()`` to free its allocated resources. The ESP-NETIF L2 TAP implementation of ``close()`` may block. On the other hand, it is thread safe and can be called from different task than the file descriptor is actually used. If such situation occurs and one task is blocked in I/O operation and another task tries to close the file descriptor, the first task is unblocked. The first's task read operation then ends with error.
|
||||
Opened ESP-NETIF L2 TAP file descriptor can be closed by the ``close()`` to free its allocated resources. The ESP-NETIF L2 TAP implementation of ``close()`` may block. On the other hand, it is thread safe and can be called from different task than the file descriptor is actually used. If such situation occurs and one task is blocked in I/O operation and another task tries to close the file descriptor, the first task is unblocked. The first's task read operation then ends with error.
|
||||
|
||||
| On success, ``close()`` returns zero. On error, -1 is returned, and ``errno`` is set to indicate the error.
|
||||
| **EBADF** - not a valid file descriptor.
|
||||
@@ -263,6 +263,9 @@ API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/esp_netif.inc
|
||||
.. include-build-file:: inc/esp_netif_types.inc
|
||||
.. include-build-file:: inc/esp_netif_ip_addr.inc
|
||||
.. include-build-file:: inc/esp_vfs_l2tap.inc
|
||||
|
||||
|
||||
WiFi default API reference
|
||||
|
||||
@@ -38,17 +38,17 @@ From driver's point of view, a GPTimer instance is represented by :cpp:type:`gpt
|
||||
|
||||
To install a timer instance, there's a configuration structure that needs to be given in advance: :cpp:type:`gptimer_config_t`:
|
||||
|
||||
- :cpp:member:`clk_src` selects the source clock for the timer. The available clocks are listed in :cpp:type:`gptimer_clock_source_t`, [1]_ you can only pick one of them. For the effect on power consumption of different clock source, please refer to `Power management <#power-management>`__ section.
|
||||
- :cpp:member:`gptimer_config_t::clk_src` selects the source clock for the timer. The available clocks are listed in :cpp:type:`gptimer_clock_source_t`, [1]_ you can only pick one of them. For the effect on power consumption of different clock source, please refer to `Power management <#power-management>`__ section.
|
||||
|
||||
- :cpp:member:`direction` sets the counting direction of the timer, supported directions are listed in :cpp:type:`gptimer_count_direction_t`, you can only pick one of them.
|
||||
- :cpp:member:`gptimer_config_t::direction` sets the counting direction of the timer, supported directions are listed in :cpp:type:`gptimer_count_direction_t`, you can only pick one of them.
|
||||
|
||||
- :cpp:member:`resolution_hz` sets the resolution of the internal counter. Each count step is equivalent to **1 / resolution_hz** seconds.
|
||||
- :cpp:member:`gptimer_config_t::resolution_hz` sets the resolution of the internal counter. Each count step is equivalent to **1 / resolution_hz** seconds.
|
||||
|
||||
- Optional :cpp:member:`intr_shared` sets whether or not mark the timer interrupt source as a shared one. For the pros/cons of a shared interrupt, you can refer to :doc:`Interrupt Handling <../../api-reference/system/intr_alloc>`.
|
||||
- Optional :cpp:member:`gptimer_config_t::intr_shared` sets whether or not mark the timer interrupt source as a shared one. For the pros/cons of a shared interrupt, you can refer to :doc:`Interrupt Handling <../../api-reference/system/intr_alloc>`.
|
||||
|
||||
With all the above configurations set in the structure, the structure can be passed to :cpp:func:`gptimer_new_timer` which will instantiate the timer instance and return a handle of the timer.
|
||||
|
||||
The function can fail due to various errors such as insufficient memory, invalid arguments, etc. Specifically, when there are no more free timers (i.e. all hardware resources have been used up), then :cpp:member:`ESP_ERR_NOT_FOUND` will be returned. The total number of available timers is represented by the :c:macro:`SOC_TIMER_GROUP_TOTAL_TIMERS` and its value will depend on the ESP chip.
|
||||
The function can fail due to various errors such as insufficient memory, invalid arguments, etc. Specifically, when there are no more free timers (i.e. all hardware resources have been used up), then :c:macro:`ESP_ERR_NOT_FOUND` will be returned. The total number of available timers is represented by the :c:macro:`SOC_TIMER_GROUP_TOTAL_TIMERS` and its value will depend on the ESP chip.
|
||||
|
||||
If a previously created GPTimer instance is no longer required, you should recycle the timer by calling :cpp:func:`gptimer_del_timer`. This will allow the underlying HW timer to be used for other purposes. Before deleting a GPTimer handle, you should stop it by :cpp:func:`gptimer_stop` in advance or make sure it has not started yet by :cpp:func:`gptimer_start`.
|
||||
|
||||
@@ -77,12 +77,12 @@ Set Up Alarm Action
|
||||
|
||||
Most of the use cases of GPTimer should set up the alarm action before starting the timer, except for the simple wall-clock scenario, where a free running timer is enough. To set up the alarm action, one should configure several members of :cpp:type:`gptimer_alarm_config_t` based on how he takes use of the alarm event:
|
||||
|
||||
- :cpp:member:`alarm_count` sets the target count value that will trigger the alarm event. You should also take the counting direction into consideration when setting the alarm value.
|
||||
Specially, :cpp:member:`alarm_count` and :cpp:member:`reload_count` can't be set to the same value when :cpp:member:`auto_reload_on_alarm` is true, as keeping reload with a target alarm count is meaningless.
|
||||
- :cpp:member:`gptimer_alarm_config_t::alarm_count` sets the target count value that will trigger the alarm event. You should also take the counting direction into consideration when setting the alarm value.
|
||||
Specially, :cpp:member:`gptimer_alarm_config_t::alarm_count` and :cpp:member:`gptimer_alarm_config_t::reload_count` can't be set to the same value when :cpp:member:`gptimer_alarm_config_t::auto_reload_on_alarm` is true, as keeping reload with a target alarm count is meaningless.
|
||||
|
||||
- :cpp:member:`reload_count` sets the count value to be reloaded when the alarm event happens. This configuration only takes effect when :cpp:member:`auto_reload_on_alarm` is set to true.
|
||||
- :cpp:member:`gptimer_alarm_config_t::reload_count` sets the count value to be reloaded when the alarm event happens. This configuration only takes effect when :cpp:member:`gptimer_alarm_config_t::auto_reload_on_alarm` is set to true.
|
||||
|
||||
- :cpp:member:`auto_reload_on_alarm` flag sets whether to enable the auto-reload feature. If enabled, the hardware timer will reload the value of :cpp:member:`reload_count` into counter immediately when alarm event happens.
|
||||
- :cpp:member:`gptimer_alarm_config_t::auto_reload_on_alarm` flag sets whether to enable the auto-reload feature. If enabled, the hardware timer will reload the value of :cpp:member:`gptimer_alarm_config_t::reload_count` into counter immediately when alarm event happens.
|
||||
|
||||
To make the alarm configurations take effect, one should call :cpp:func:`gptimer_set_alarm_action`. Especially, if :cpp:type:`gptimer_alarm_config_t` is set to ``NULL``, the alarm function will be disabled.
|
||||
|
||||
@@ -95,7 +95,7 @@ Register Event Callbacks
|
||||
|
||||
After the timer starts up, it can generate specific event (e.g. the "Alarm Event") dynamically. If you have some function that should be called when event happens, you should hook your function to the interrupt service routine by calling :cpp:func:`gptimer_register_event_callbacks`. All supported event callbacks are listed in the :cpp:type:`gptimer_event_callbacks_t`:
|
||||
|
||||
- :cpp:member:`on_alarm` sets callback function for alarm event. As this function is called within the ISR context, user must ensure that the function doesn't attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function). The function prototype is declared in :cpp:type:`gptimer_alarm_cb_t`.
|
||||
- :cpp:member:`gptimer_event_callbacks_t::on_alarm` sets callback function for alarm event. As this function is called within the ISR context, user must ensure that the function doesn't attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function). The function prototype is declared in :cpp:type:`gptimer_alarm_cb_t`.
|
||||
|
||||
One can save his own context to :cpp:func:`gptimer_register_event_callbacks` as well, via the parameter ``user_data``. The user data will be directly passed to the callback functions.
|
||||
|
||||
@@ -192,7 +192,7 @@ Trigger One-Shot Event
|
||||
Dynamic Alarm Update
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Alarm value can be updated dynamically inside the ISR handler callback, by changing the :cpp:member:`alarm_value` of :cpp:type:`gptimer_alarm_event_data_t`. Then the alarm value will be updated after the callback function returns.
|
||||
Alarm value can be updated dynamically inside the ISR handler callback, by changing the :cpp:member:`gptimer_alarm_event_data_t::alarm_value`. Then the alarm value will be updated after the callback function returns.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@@ -235,7 +235,7 @@ Power Management
|
||||
|
||||
When power management is enabled (i.e. :ref:`CONFIG_PM_ENABLE` is on), the system will adjust the APB frequency before going into light sleep, thus potentially changing the period of a GPTimer's counting step and leading to inaccurate time keeping.
|
||||
|
||||
However, the driver can prevent the system from changing APB frequency by acquiring a power management lock of type :c:member:`ESP_PM_APB_FREQ_MAX`. Whenever the driver creates a GPTimer instance that has selected :c:member:`GPTIMER_CLK_SRC_APB` as its clock source, the driver will guarantee that the power management lock is acquired when the timer is started by :cpp:func:`gptimer_start`. Likewise, the driver releases the lock when :cpp:func:`gptimer_stop` is called for that timer. This requires that the :cpp:func:`gptimer_start` and :cpp:func:`gptimer_stop` should appear in pairs.
|
||||
However, the driver can prevent the system from changing APB frequency by acquiring a power management lock of type :cpp:enumerator:`ESP_PM_APB_FREQ_MAX`. Whenever the driver creates a GPTimer instance that has selected :cpp:enumerator:`GPTIMER_CLK_SRC_APB` as its clock source, the driver will guarantee that the power management lock is acquired when the timer is started by :cpp:func:`gptimer_start`. Likewise, the driver releases the lock when :cpp:func:`gptimer_stop` is called for that timer. This requires that the :cpp:func:`gptimer_start` and :cpp:func:`gptimer_stop` should appear in pairs.
|
||||
|
||||
IRAM Safe
|
||||
^^^^^^^^^
|
||||
@@ -288,4 +288,4 @@ API Reference
|
||||
Some ESP chip might only support a sub-set of the clocks, if an unsupported clock source is specified, you will get a runtime error during timer installation.
|
||||
|
||||
.. [2]
|
||||
:cpp:member:`on_alarm` callback and the functions invoked by itself should also be placed in IRAM, users need to take care of them by themselves.
|
||||
:cpp:member:`gptimer_event_callbacks_t::on_alarm` callback and the functions invoked by itself should also be placed in IRAM, users need to take care of them by themselves.
|
||||
|
||||
@@ -335,7 +335,7 @@ Customized Configuration
|
||||
|
||||
As mentioned at the end of Section :ref:`i2c-api-configure-driver`, when the function :cpp:func:`i2c_param_config` initializes the driver configuration for an I2C port, it also sets several I2C communication parameters to default values defined in the `I2C specification <https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_. Some other related parameters are pre-configured in registers of the I2C controller.
|
||||
|
||||
All these parameters can be changed to user-defined values by calling dedicated functions given in the table below. Please note that the timing values are defined in APB clock cycles. The frequency of APB is specified in :cpp:type:`I2C_APB_CLK_FREQ`.
|
||||
All these parameters can be changed to user-defined values by calling dedicated functions given in the table below. Please note that the timing values are defined in APB clock cycles. The frequency of APB is specified in :c:macro:`I2C_APB_CLK_FREQ`.
|
||||
|
||||
.. list-table:: Other Configurable I2C Communication Parameters
|
||||
:widths: 65 35
|
||||
|
||||
@@ -9,7 +9,7 @@ ESP chips can generate various kinds of timings that needed by common LCDs on th
|
||||
Functional Overview
|
||||
-------------------
|
||||
|
||||
In ``esp_lcd``, an LCD panel is represented by :c:type:`esp_lcd_panel_handle_t`, which plays the role of an **abstract frame buffer**, regardless of the frame memory is allocated inside ESP chip or in external LCD controller. Based on the location of the frame buffer, the LCD panel allocation functions are mainly grouped into the following categories:
|
||||
In ``esp_lcd``, an LCD panel is represented by :cpp:type:`esp_lcd_panel_handle_t`, which plays the role of an **abstract frame buffer**, regardless of the frame memory is allocated inside ESP chip or in external LCD controller. Based on the location of the frame buffer, the LCD panel allocation functions are mainly grouped into the following categories:
|
||||
|
||||
- ``RGB LCD panel`` - is simply based on a group of specific synchronous signals indicating where to start and stop a frame.
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@ Install PCNT Unit
|
||||
|
||||
To install a PCNT unit, there's a configuration structure that needs to be given in advance: :cpp:type:`pcnt_unit_config_t`:
|
||||
|
||||
- :cpp:member:`low_limit` and :cpp:member:`high_limit` specify the range for the internal counter. Counter will back to zero when it crosses either limit value.
|
||||
- :cpp:member:`pcnt_unit_config_t::low_limit` and :cpp:member:`pcnt_unit_config_t::high_limit` specify the range for the internal counter. Counter will back to zero when it crosses either limit value.
|
||||
|
||||
Unit allocation and initialization is done by calling a function :cpp:func:`pcnt_new_unit` with :cpp:type:`pcnt_unit_config_t` as an input parameter. The function will return a PCNT unit handle only when it runs correctly. Specifically, when there are no more free PCNT units in the pool (i.e. unit resources have been used up), then this function will return :cpp:member:`ESP_ERR_NOT_FOUND` error. The total number of available PCNT units is recorded by :c:macro:`SOC_PCNT_UNITS_PER_GROUP` for reference.
|
||||
Unit allocation and initialization is done by calling a function :cpp:func:`pcnt_new_unit` with :cpp:type:`pcnt_unit_config_t` as an input parameter. The function will return a PCNT unit handle only when it runs correctly. Specifically, when there are no more free PCNT units in the pool (i.e. unit resources have been used up), then this function will return :c:macro:`ESP_ERR_NOT_FOUND` error. The total number of available PCNT units is recorded by :c:macro:`SOC_PCNT_UNITS_PER_GROUP` for reference.
|
||||
|
||||
If a previously created PCNT unit is no longer needed, it's recommended to recycle the resource by calling :cpp:func:`pcnt_del_unit`. Which in return allows the underlying unit hardware to be used for other purposes. Before deleting a PCNT unit, one should ensure the following prerequisites:
|
||||
|
||||
@@ -67,11 +67,11 @@ Install PCNT Channel
|
||||
|
||||
To install a PCNT channel, there's a configuration structure that needs to be given in advance: :cpp:type:`pcnt_chan_config_t` as well:
|
||||
|
||||
- :cpp:member:`edge_gpio_num` and :cpp:member:`level_gpio_num` specify the GPIO numbers used by **edge** type signal and **level** type signal. :cpp:member:`level_gpio_num` is optional and can be assigned with `-1` if it's not used whereas the :cpp:member:`edge_gpio_num` is mandatory.
|
||||
- :cpp:member:`invert_edge_input` and :cpp:member:`invert_level_input` are used to decide whether to invert the input signals before they going into PCNT hardware. The invert is done by GPIO matrix instead of PCNT hardware.
|
||||
- :cpp:member:`io_loop_back` is for debug only, which enables both the GPIO's input and output paths. This can help to simulate the pulse signals by function :cpp:func:`gpio_set_level` on the same GPIO.
|
||||
- :cpp:member:`pcnt_chan_config_t::edge_gpio_num` and :cpp:member:`pcnt_chan_config_t::level_gpio_num` specify the GPIO numbers used by **edge** type signal and **level** type signal. :cpp:member:`pcnt_chan_config_t::level_gpio_num` is optional and can be assigned with `-1` if it's not used whereas the :cpp:member:`pcnt_chan_config_t::edge_gpio_num` is mandatory.
|
||||
- :cpp:member:`pcnt_chan_config_t::invert_edge_input` and :cpp:member:`pcnt_chan_config_t::invert_level_input` are used to decide whether to invert the input signals before they going into PCNT hardware. The invert is done by GPIO matrix instead of PCNT hardware.
|
||||
- :cpp:member:`pcnt_chan_config_t::io_loop_back` is for debug only, which enables both the GPIO's input and output paths. This can help to simulate the pulse signals by function :cpp:func:`gpio_set_level` on the same GPIO.
|
||||
|
||||
Channel allocating and initialization is done by calling a function :cpp:func:`pcnt_new_channel` with the above :cpp:type:`pcnt_chan_config_t` input parameter plus a PCNT unit handle returned from :cpp:func:`pcnt_new_unit`. This function will return a PCNT channel handle if it runs correctly. Specifically, when there are no more free PCNT channel within the unit (i.e. channel resources have been used up), then this function will return :cpp:member:`ESP_ERR_NOT_FOUND` error. The total number of available PCNT channels within the unit is recorded by :c:macro:`SOC_PCNT_CHANNELS_PER_UNIT` for reference.
|
||||
Channel allocating and initialization is done by calling a function :cpp:func:`pcnt_new_channel` with the above :cpp:type:`pcnt_chan_config_t` input parameter plus a PCNT unit handle returned from :cpp:func:`pcnt_new_unit`. This function will return a PCNT channel handle if it runs correctly. Specifically, when there are no more free PCNT channel within the unit (i.e. channel resources have been used up), then this function will return :c:macro:`ESP_ERR_NOT_FOUND` error. The total number of available PCNT channels within the unit is recorded by :c:macro:`SOC_PCNT_CHANNELS_PER_UNIT` for reference.
|
||||
|
||||
If a previously created PCNT channel is no longer needed, it's recommended to recycle the resources by calling :cpp:func:`pcnt_del_channel`. Which in return allows the underlying channel hardware to be used for other purposes.
|
||||
|
||||
@@ -92,8 +92,8 @@ Set Up Channel Actions
|
||||
|
||||
The PCNT will increase/decrease/hold its internal count value when the input pulse signal toggles. User can set different actions for edge signal and/or level signal.
|
||||
|
||||
- :cpp:func:`pcnt_channel_set_edge_action` function is to set specific actions for rising and falling edge of the signal attached to the :cpp:member:`edge_gpio_num`. Supported actions are listed in :cpp:type:`pcnt_channel_edge_action_t`.
|
||||
- :cpp:func:`pcnt_channel_set_level_action` function is to set specific actions for high and low level of the signal attached to the :cpp:member:`level_gpio_num`. Supported actions are listed in :cpp:type:`pcnt_channel_level_action_t`. This function is not mandatory if the :cpp:member:`level_gpio_num` is set to `-1` when allocating PCNT channel by :cpp:func:`pcnt_new_channel`.
|
||||
- :cpp:func:`pcnt_channel_set_edge_action` function is to set specific actions for rising and falling edge of the signal attached to the :cpp:member:`pcnt_chan_config_t::edge_gpio_num`. Supported actions are listed in :cpp:type:`pcnt_channel_edge_action_t`.
|
||||
- :cpp:func:`pcnt_channel_set_level_action` function is to set specific actions for high and low level of the signal attached to the :cpp:member:`pcnt_chan_config_t::level_gpio_num`. Supported actions are listed in :cpp:type:`pcnt_channel_level_action_t`. This function is not mandatory if the :cpp:member:`pcnt_chan_config_t::level_gpio_num` is set to `-1` when allocating PCNT channel by :cpp:func:`pcnt_new_channel`.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@@ -105,7 +105,7 @@ The PCNT will increase/decrease/hold its internal count value when the input pul
|
||||
Watch Points
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Each PCNT unit can be configured to watch several different values that you're interested in. The value to be watched is also called **Watch Point**. The watch point itself can't exceed the range set in :cpp:type:`pcnt_unit_config_t` by :cpp:member:`low_limit` and :cpp:member:`high_limit`. When the counter reaches either watch point, a watch event will be triggered and notify user by interrupt if any watch event callback has ever registered in :cpp:func:`pcnt_unit_register_event_callbacks`. See `Register Event Callbacks <#register-event-callbacks>`__ for how to register event callbacks.
|
||||
Each PCNT unit can be configured to watch several different values that you're interested in. The value to be watched is also called **Watch Point**. The watch point itself can't exceed the range set in :cpp:type:`pcnt_unit_config_t` by :cpp:member:`pcnt_unit_config_t::low_limit` and :cpp:member:`pcnt_unit_config_t::high_limit`. When the counter reaches either watch point, a watch event will be triggered and notify user by interrupt if any watch event callback has ever registered in :cpp:func:`pcnt_unit_register_event_callbacks`. See `Register Event Callbacks <#register-event-callbacks>`__ for how to register event callbacks.
|
||||
|
||||
The watch point can be added and removed by :cpp:func:`pcnt_unit_add_watch_point` and :cpp:func:`pcnt_unit_remove_watch_point`. The commonly used watch points are: **zero cross**, **maximum / minimum count** and other threshold values. The number of available watch point is limited, :cpp:func:`pcnt_unit_add_watch_point` will return error :c:macro:`ESP_ERR_NOT_FOUND` if it can't find any free hardware resource to save the watch point. User can't add the same watch point for multiple times, otherwise it will return error :c:macro:`ESP_ERR_INVALID_STATE`.
|
||||
|
||||
@@ -123,14 +123,14 @@ Register Event Callbacks
|
||||
|
||||
When PCNT unit reaches any enabled watch point, specific event will be generated and notify the CPU by interrupt. If you have some function that want to get executed when event happens, you should hook your function to the interrupt service routine by calling :cpp:func:`pcnt_unit_register_event_callbacks`. All supported event callbacks are listed in the :cpp:type:`pcnt_event_callbacks_t`:
|
||||
|
||||
- :cpp:member:`on_reach` sets a callback function for watch point event. As this function is called within the ISR context, user must ensure that the function doesn't attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function). The function prototype is declared in :cpp:type:`pcnt_watch_cb_t`.
|
||||
- :cpp:member:`pcnt_event_callbacks_t::on_reach` sets a callback function for watch point event. As this function is called within the ISR context, user must ensure that the function doesn't attempt to block (e.g., by making sure that only FreeRTOS APIs with ``ISR`` suffix are called from within the function). The function prototype is declared in :cpp:type:`pcnt_watch_cb_t`.
|
||||
|
||||
User can save their own context to :cpp:func:`pcnt_unit_register_event_callbacks` as well, via the parameter ``user_ctx``. This user data will be directly passed to the callback functions.
|
||||
|
||||
In the callback function, the driver will fill in the event data of specific event. For example, the watch point event data is declared as :cpp:type:`pcnt_watch_event_data_t`:
|
||||
|
||||
- :cpp:member:`watch_point_value` saves the watch point value that triggers the event.
|
||||
- :cpp:member:`zero_cross_mode` saves how the PCNT unit crosses the zero point in the latest time. The possible zero cross modes are listed in the :cpp:type:`pcnt_unit_zero_cross_mode_t`. Usually different zero cross mode means different **counting direction** and **counting step size**.
|
||||
- :cpp:member:`pcnt_watch_event_data_t::watch_point_value` saves the watch point value that triggers the event.
|
||||
- :cpp:member:`pcnt_watch_event_data_t::zero_cross_mode` saves how the PCNT unit crosses the zero point in the latest time. The possible zero cross modes are listed in the :cpp:type:`pcnt_unit_zero_cross_mode_t`. Usually different zero cross mode means different **counting direction** and **counting step size**.
|
||||
|
||||
.. code:: c
|
||||
|
||||
@@ -156,9 +156,9 @@ Unit IO Control
|
||||
Set Glitch Filter
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The PCNT unit features filters to ignore possible short glitches in the signals. The parameters can to be configured for the glitch filter are listed in :cpp:type:`pcnt_glitch_filter_config_t`:
|
||||
The PCNT unit features filters to ignore possible short glitches in the signals. The parameters that can be configured for the glitch filter are listed in :cpp:type:`pcnt_glitch_filter_config_t`:
|
||||
|
||||
- :cpp:member:`max_glitch_ns` sets the maximum glitch width, in nano seconds. If a signal pulse's width is smaller than this value, then it will be treated as noise and won't increase/decrease the internal counter.
|
||||
- :cpp:member:`pcnt_glitch_filter_config_t::max_glitch_ns` sets the maximum glitch width, in nano seconds. If a signal pulse's width is smaller than this value, then it will be treated as noise and won't increase/decrease the internal counter.
|
||||
|
||||
User can enable the glitch filter for PCNT unit by calling :cpp:func:`pcnt_unit_set_glitch_filter` with the filter configuration provided above. Particularly, user can disable the glitch filter later by calling :cpp:func:`pcnt_unit_set_glitch_filter` with a `NULL` filter configuration.
|
||||
|
||||
@@ -202,7 +202,7 @@ Power Management
|
||||
|
||||
When power management is enabled (i.e. :ref:`CONFIG_PM_ENABLE` is on), the system will adjust the APB frequency before going into light sleep, thus potentially changing the behavior of PCNT glitch filter and leading to valid signal being treated as noise.
|
||||
|
||||
However, the driver can prevent the system from changing APB frequency by acquiring a power management lock of type :c:member:`ESP_PM_APB_FREQ_MAX`. Whenever user enables the glitch filter by :cpp:func:`pcnt_unit_set_glitch_filter`, the driver will guarantee that the power management lock is acquired after the PCNT unit is started by :cpp:func:`pcnt_unit_start`. Likewise, the driver releases the lock after :cpp:func:`pcnt_unit_stop` is called. This requires that the :cpp:func:`pcnt_unit_start` and :cpp:func:`pcnt_unit_stop` should appear in pairs, otherwise the power management will be out of action.
|
||||
However, the driver can prevent the system from changing APB frequency by acquiring a power management lock of type :cpp:enumerator:`ESP_PM_APB_FREQ_MAX`. Whenever user enables the glitch filter by :cpp:func:`pcnt_unit_set_glitch_filter`, the driver will guarantee that the power management lock is acquired after the PCNT unit is started by :cpp:func:`pcnt_unit_start`. Likewise, the driver releases the lock after :cpp:func:`pcnt_unit_stop` is called. This requires that the :cpp:func:`pcnt_unit_start` and :cpp:func:`pcnt_unit_stop` should appear in pairs, otherwise the power management will be out of action.
|
||||
|
||||
IRAM Safe
|
||||
^^^^^^^^^
|
||||
@@ -255,4 +255,4 @@ API Reference
|
||||
Different ESP chip series might have different number of PCNT units and channels. Please refer to the [`TRM <{IDF_TARGET_TRM_EN_URL}#pcnt>`__] for details. The driver won't forbid you from applying for more PCNT units and channels, but it will return error when all available hardware resources are used up. Please always check the return value when doing resource allocation (e.g. :cpp:func:`pcnt_new_unit`).
|
||||
|
||||
.. [2]
|
||||
:cpp:member:`on_reach` callback and the functions invoked by itself should also be placed in IRAM, users need to take care of them by themselves.
|
||||
:cpp:member:`pcnt_event_callbacks_t::on_reach` callback and the functions invoked by itself should also be placed in IRAM, users need to take care of them by themselves.
|
||||
|
||||
@@ -170,7 +170,7 @@ Finalize Configuration
|
||||
|
||||
Once the :cpp:type:`rmt_config_t` structure is populated with parameters, it should be then invoked with :cpp:func:`rmt_config` to make the configuration effective.
|
||||
|
||||
The last configuration step is installation of the driver in memory by calling :cpp:func:`rmt_driver_install`. If :cpp:type:`rx_buf_size` parameter of this function is > 0, then a ring buffer for incoming data will be allocated. A default ISR handler will be installed, see a note in `Use Interrupts`_.
|
||||
The last configuration step is installation of the driver in memory by calling :cpp:func:`rmt_driver_install`. If `rx_buf_size` parameter of this function is > 0, then a ring buffer for incoming data will be allocated. A default ISR handler will be installed, see a note in `Use Interrupts`_.
|
||||
|
||||
Now, depending on how the channel is configured, we are ready to either `Transmit Data`_ or `Receive Data`_. This is described in next two sections.
|
||||
|
||||
@@ -291,8 +291,6 @@ The RMT controller triggers interrupts on four specific events describes below.
|
||||
* The number of events the transmitter has sent matches a threshold value :cpp:func:`rmt_set_tx_thr_intr_en`
|
||||
* Ownership to the RMT memory block has been violated - :cpp:func:`rmt_set_err_intr_en`
|
||||
|
||||
Setting or clearing an interrupt enable mask for specific channels and events may be also done by calling :cpp:func:`rmt_set_intr_enable_mask` or :cpp:func:`rmt_clr_intr_enable_mask`.
|
||||
|
||||
When servicing an interrupt within an ISR, the interrupt need to explicitly cleared. To do so, set specific bits described as ``RMT.int_clr.val.chN_event_name`` and defined as a ``volatile struct`` in :component_file:`soc/{IDF_TARGET_PATH_NAME}/include/soc/rmt_struct.h`, where N is the RMT channel number [0, n] and the ``event_name`` is one of four events described above.
|
||||
|
||||
If you do not need an ISR anymore, you can deregister it by calling a function :cpp:func:`rmt_isr_deregister`.
|
||||
|
||||
@@ -118,11 +118,11 @@ An SPI Host can send full-duplex transactions, during which the read and write p
|
||||
|
||||
While the member :cpp:member:`spi_transaction_t::rxlength` only determines the length of data received into the buffer.
|
||||
|
||||
In half-duplex transactions, the read and write phases are not simultaneous (one direction at a time). The lengths of the write and read phases are determined by :cpp:member:`length` and :cpp:member:`rxlength` members of the struct :cpp:type:`spi_transaction_t` respectively.
|
||||
In half-duplex transactions, the read and write phases are not simultaneous (one direction at a time). The lengths of the write and read phases are determined by :cpp:member:`spi_transaction_t::length` and :cpp:member:`spi_transaction_t::rxlength` respectively.
|
||||
|
||||
The command and address phases are optional, as not every SPI device requires a command and/or address. This is reflected in the Device's configuration: if :cpp:member:`command_bits` and/or :cpp:member:`address_bits` are set to zero, no command or address phase will occur.
|
||||
The command and address phases are optional, as not every SPI device requires a command and/or address. This is reflected in the Device's configuration: if :cpp:member:`spi_device_interface_config_t::command_bits` and/or :cpp:member:`spi_device_interface_config_t::address_bits` are set to zero, no command or address phase will occur.
|
||||
|
||||
The read and write phases can also be optional, as not every transaction requires both writing and reading data. If :cpp:member:`rx_buffer` is NULL and :cpp:type:`SPI_TRANS_USE_RXDATA` is not set, the read phase is skipped. If :cpp:member:`tx_buffer` is NULL and :cpp:type:`SPI_TRANS_USE_TXDATA` is not set, the write phase is skipped.
|
||||
The read and write phases can also be optional, as not every transaction requires both writing and reading data. If :cpp:member:`spi_transaction_t::rx_buffer` is NULL and :c:macro:`SPI_TRANS_USE_RXDATA` is not set, the read phase is skipped. If :cpp:member:`spi_transaction_t::tx_buffer` is NULL and :c:macro:`SPI_TRANS_USE_TXDATA` is not set, the write phase is skipped.
|
||||
|
||||
The driver supports two types of transactions: the interrupt transactions and polling transactions. The programmer can choose to use a different transaction type per Device. If your Device requires both transaction types, see :ref:`mixed_transactions`.
|
||||
|
||||
@@ -205,9 +205,9 @@ Supported line modes for {IDF_TARGET_NAME} are listed as follows, to make use of
|
||||
Command and Address Phases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
During the command and address phases, the members :cpp:member:`cmd` and :cpp:member:`addr` in the struct :cpp:type:`spi_transaction_t` are sent to the bus, nothing is read at this time. The default lengths of the command and address phases are set in :cpp:type:`spi_device_interface_config_t` by calling :cpp:func:`spi_bus_add_device`. If the flags :cpp:type:`SPI_TRANS_VARIABLE_CMD` and :cpp:type:`SPI_TRANS_VARIABLE_ADDR` in the member :cpp:member:`spi_transaction_t::flags` are not set, the driver automatically sets the length of these phases to default values during Device initialization.
|
||||
During the command and address phases, the members :cpp:member:`spi_transaction_t::cmd` and :cpp:member:`spi_transaction_t::addr` are sent to the bus, nothing is read at this time. The default lengths of the command and address phases are set in :cpp:type:`spi_device_interface_config_t` by calling :cpp:func:`spi_bus_add_device`. If the flags :c:macro:`SPI_TRANS_VARIABLE_CMD` and :c:macro:`SPI_TRANS_VARIABLE_ADDR` in the member :cpp:member:`spi_transaction_t::flags` are not set, the driver automatically sets the length of these phases to default values during Device initialization.
|
||||
|
||||
If the lengths of the command and address phases need to be variable, declare the struct :cpp:type:`spi_transaction_ext_t`, set the flags :cpp:type:`SPI_TRANS_VARIABLE_CMD` and/or :cpp:type:`SPI_TRANS_VARIABLE_ADDR` in the member :cpp:member:`spi_transaction_ext_t::base` and configure the rest of base as usual. Then the length of each phase will be equal to :cpp:member:`command_bits` and :cpp:member:`address_bits` set in the struct :cpp:type:`spi_transaction_ext_t`.
|
||||
If the lengths of the command and address phases need to be variable, declare the struct :cpp:type:`spi_transaction_ext_t`, set the flags :c:macro:`SPI_TRANS_VARIABLE_CMD` and/or :c:macro:`SPI_TRANS_VARIABLE_ADDR` in the member :cpp:member:`spi_transaction_ext_t::base` and configure the rest of base as usual. Then the length of each phase will be equal to :cpp:member:`spi_transaction_ext_t::command_bits` and :cpp:member:`spi_transaction_ext_t::address_bits` set in the struct :cpp:type:`spi_transaction_ext_t`.
|
||||
|
||||
If the command and address phase need to be as the same number of lines as data phase, you need to set `SPI_TRANS_MULTILINE_CMD` and/or `SPI_TRANS_MULTILINE_ADDR` to the `flags` member in the struct :cpp:type:`spi_transaction_t`. Also see :ref:`transaction-line-mode`.
|
||||
|
||||
@@ -215,7 +215,7 @@ If the command and address phase need to be as the same number of lines as data
|
||||
Write and Read Phases
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Normally, the data that needs to be transferred to or from a Device will be read from or written to a chunk of memory indicated by the members :cpp:member:`rx_buffer` and :cpp:member:`tx_buffer` of the structure :cpp:type:`spi_transaction_t`. If DMA is enabled for transfers, the buffers are required to be:
|
||||
Normally, the data that needs to be transferred to or from a Device will be read from or written to a chunk of memory indicated by the members :cpp:member:`spi_transaction_t::rx_buffer` and :cpp:member:`spi_transaction_t::tx_buffer`. If DMA is enabled for transfers, the buffers are required to be:
|
||||
|
||||
1. Allocated in DMA-capable internal memory. If :ref:`external PSRAM is enabled<dma-capable-memory>`, this means using ``pvPortMallocCaps(size, MALLOC_CAP_DMA)``.
|
||||
2. 32-bit aligned (staring from a 32-bit boundary and having a length of multiples of 4 bytes).
|
||||
@@ -287,7 +287,7 @@ The example code for the SPI master driver can be found in the :example:`periphe
|
||||
Transactions with Data Not Exceeding 32 Bits
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When the transaction data size is equal to or less than 32 bits, it will be sub-optimal to allocate a buffer for the data. The data can be directly stored in the transaction struct instead. For transmitted data, it can be achieved by using the :cpp:member:`tx_data` member and setting the :cpp:type:`SPI_TRANS_USE_TXDATA` flag on the transmission. For received data, use :cpp:member:`rx_data` and set :cpp:type:`SPI_TRANS_USE_RXDATA`. In both cases, do not touch the :cpp:member:`tx_buffer` or :cpp:member:`rx_buffer` members, because they use the same memory locations as :cpp:member:`tx_data` and :cpp:member:`rx_data`.
|
||||
When the transaction data size is equal to or less than 32 bits, it will be sub-optimal to allocate a buffer for the data. The data can be directly stored in the transaction struct instead. For transmitted data, it can be achieved by using the :cpp:member:`spi_transaction_t::tx_data` member and setting the :c:macro:`SPI_TRANS_USE_TXDATA` flag on the transmission. For received data, use :cpp:member:`spi_transaction_t::rx_data` and set :c:macro:`SPI_TRANS_USE_RXDATA`. In both cases, do not touch the :cpp:member:`spi_transaction_t::tx_buffer` or :cpp:member:`spi_transaction_t::rx_buffer` members, because they use the same memory locations as :cpp:member:`spi_transaction_t::tx_data` and :cpp:member:`spi_transaction_t::rx_data`.
|
||||
|
||||
|
||||
Transactions with Integers Other Than ``uint8_t``
|
||||
@@ -493,7 +493,7 @@ For an interrupt transaction, the overall cost is *20+8n/Fspi[MHz]* [us] for n b
|
||||
|
||||
When a transaction length is short, the cost of transaction interval is high. If possible, try to squash several short transactions into one transaction to achieve a higher transfer speed.
|
||||
|
||||
Please note that the ISR is disabled during flash operation by default. To keep sending transactions during flash operations, enable :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` and set :cpp:class:`ESP_INTR_FLAG_IRAM` in the member :cpp:member:`spi_bus_config_t::intr_flags`. In this case, all the transactions queued before starting flash operations will be handled by the ISR in parallel. Also note that the callback of each Device and their callee functions should be in IRAM, or your callback will crash due to cache miss. For more details, see :ref:`iram-safe-interrupt-handlers`.
|
||||
Please note that the ISR is disabled during flash operation by default. To keep sending transactions during flash operations, enable :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` and set :c:macro:`ESP_INTR_FLAG_IRAM` in the member :cpp:member:`spi_bus_config_t::intr_flags`. In this case, all the transactions queued before starting flash operations will be handled by the ISR in parallel. Also note that the callback of each Device and their callee functions should be in IRAM, or your callback will crash due to cache miss. For more details, see :ref:`iram-safe-interrupt-handlers`.
|
||||
|
||||
|
||||
.. only:: esp32
|
||||
@@ -515,7 +515,7 @@ Please note that the ISR is disabled during flash operation by default. To keep
|
||||
|
||||
The maximum allowed frequency is dependent on:
|
||||
|
||||
- ``input_delay_ns`` - maximum data valid time on the MISO bus after a clock cycle on SCLK starts
|
||||
- :cpp:member:`spi_device_interface_config_t::input_delay_ns` - maximum data valid time on the MISO bus after a clock cycle on SCLK starts
|
||||
- If the IO_MUX pin or the GPIO Matrix is used
|
||||
|
||||
When the GPIO matrix is used, the maximum allowed frequency is reduced to about 33~77% in comparison to the existing *input delay*. To retain a higher frequency, you have to use the IO_MUX pins or the *dummy bit workaround*. You can obtain the maximum reading frequency of the master by using the function :cpp:func:`spi_get_freq_limit`.
|
||||
@@ -540,7 +540,7 @@ Please note that the ISR is disabled during flash operation by default. To keep
|
||||
|
||||
:cpp:member:`spi_device_interface_config_t::flags`
|
||||
|
||||
The SPI master driver still works even if the :cpp:member:`input_delay_ns` in the structure :cpp:type:`spi_device_interface_config_t` is set to 0. However, setting an accurate value helps to:
|
||||
The SPI master driver still works even if the :cpp:member:`spi_device_interface_config_t::input_delay_ns` in the structure :cpp:type:`spi_device_interface_config_t` is set to 0. However, setting an accurate value helps to:
|
||||
|
||||
- Calculate the frequency limit for full-duplex transactions
|
||||
- Compensate the timing correctly with dummy bits for half-duplex transactions
|
||||
|
||||
@@ -73,7 +73,7 @@ As not every transaction requires both writing and reading data, you have a choi
|
||||
Driver Usage
|
||||
------------
|
||||
|
||||
- Initialize an SPI peripheral as a Device by calling the function cpp:func:`spi_slave_initialize`. Make sure to set the correct I/O pins in the struct :cpp:type:`bus_config`. Set the unused signals to ``-1``.
|
||||
- Initialize an SPI peripheral as a Device by calling the function cpp:func:`spi_slave_initialize`. Make sure to set the correct I/O pins in the struct `bus_config`. Set the unused signals to ``-1``.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -91,11 +91,11 @@ Driver Usage
|
||||
Transaction Data and Master/Slave Length Mismatches
|
||||
---------------------------------------------------
|
||||
|
||||
Normally, the data that needs to be transferred to or from a Device is read or written to a chunk of memory indicated by the :cpp:member:`rx_buffer` and :cpp:member:`tx_buffer` members of the :cpp:type:`spi_transaction_t` structure. The SPI driver can be configured to use DMA for transfers, in which case these buffers must be allocated in DMA-capable memory using ``pvPortMallocCaps(size, MALLOC_CAP_DMA)``.
|
||||
Normally, the data that needs to be transferred to or from a Device is read or written to a chunk of memory indicated by the :cpp:member:`spi_slave_transaction_t::rx_buffer` and :cpp:member:`spi_slave_transaction_t::tx_buffer`. The SPI driver can be configured to use DMA for transfers, in which case these buffers must be allocated in DMA-capable memory using ``pvPortMallocCaps(size, MALLOC_CAP_DMA)``.
|
||||
|
||||
The amount of data that the driver can read or write to the buffers is limited by the member :cpp:member:`spi_transaction_t::length`. However, this member does not define the actual length of an SPI transaction. A transaction's length is determined by a Host which drives the clock and CS lines. The actual length of the transmission can be read only after a transaction is finished from the member :cpp:member:`spi_slave_transaction_t::trans_len`.
|
||||
The amount of data that the driver can read or write to the buffers is limited by :cpp:member:`spi_slave_transaction_t::length`. However, this member does not define the actual length of an SPI transaction. A transaction's length is determined by a Host which drives the clock and CS lines. The actual length of the transmission can be read only after a transaction is finished from the member :cpp:member:`spi_slave_transaction_t::trans_len`.
|
||||
|
||||
If the length of the transmission is greater than the buffer length, only the initial number of bits specified in the :cpp:member:`length` member will be sent and received. In this case, :cpp:member:`trans_len` is set to :cpp:member:`length` instead of the actual transaction length. To meet the actual transaction length requirements, set :cpp:member:`length` to a value greater than the maximum :cpp:member:`trans_len` expected. If the transmission length is shorter than the buffer length, only the data equal to the length of the buffer will be transmitted.
|
||||
If the length of the transmission is greater than the buffer length, only the initial number of bits specified in the :cpp:member:`spi_slave_transaction_t::length` member will be sent and received. In this case, :cpp:member:`spi_slave_transaction_t::trans_len` is set to :cpp:member:`spi_slave_transaction_t::length` instead of the actual transaction length. To meet the actual transaction length requirements, set :cpp:member:`spi_slave_transaction_t::length` to a value greater than the maximum :cpp:member:`spi_slave_transaction_t::trans_len` expected. If the transmission length is shorter than the buffer length, only the data equal to the length of the buffer will be transmitted.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ The UART controller supports a number of communication modes. A mode can be sele
|
||||
Using Interrupts
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
There are many interrupts that can be generated following specific UART states or detected errors. The full list of available interrupts is provided in *{IDF_TARGET_NAME} Technical Reference Manual* > *UART Controller (UART)* > *UART Interrupts* and *UHCI Interrupts* [`PDF <{IDF_TARGET_TRM_EN_URL}#uart>`__]. You can enable or disable specific interrupts by calling :cpp:func:`uart_enable_intr_mask` or :cpp:func:`uart_disable_intr_mask` respectively. The mask of all interrupts is available as :c:macro:`UART_INTR_MASK`.
|
||||
There are many interrupts that can be generated following specific UART states or detected errors. The full list of available interrupts is provided in *{IDF_TARGET_NAME} Technical Reference Manual* > *UART Controller (UART)* > *UART Interrupts* and *UHCI Interrupts* [`PDF <{IDF_TARGET_TRM_EN_URL}#uart>`__]. You can enable or disable specific interrupts by calling :cpp:func:`uart_enable_intr_mask` or :cpp:func:`uart_disable_intr_mask` respectively.
|
||||
|
||||
The :cpp:func:`uart_driver_install` function installs the driver's internal interrupt handler to manage the Tx and Rx ring buffers and provides high-level API functions like events (see below).
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ The following API of `esp_http_server` should not be used with `esp_https_server
|
||||
* :cpp:func:`httpd_sess_get_transport_ctx` - returns SSL used for the session
|
||||
* :cpp:func:`httpd_sess_set_transport_ctx`
|
||||
* :cpp:func:`httpd_get_global_transport_ctx` - returns the shared SSL context
|
||||
* :c:member:`httpd_config_t.global_transport_ctx`
|
||||
* :c:member:`httpd_config_t.global_transport_ctx_free_fn`
|
||||
* :c:member:`httpd_config_t.open_fn` - used to set up secure sockets
|
||||
* :cpp:member:`httpd_config::global_transport_ctx`
|
||||
* :cpp:member:`httpd_config::global_transport_ctx_free_fn`
|
||||
* :cpp:member:`httpd_config::open_fn` - used to set up secure sockets
|
||||
|
||||
Everything else can be used without limitations.
|
||||
|
||||
@@ -36,7 +36,7 @@ Please see the example :example:`protocols/https_server` to learn how to set up
|
||||
|
||||
Basically all you need is to generate a certificate, embed it in the firmware, and provide its pointers and lengths to the start function via the init struct.
|
||||
|
||||
The server can be started with or without SSL by changing a flag in the init struct - :c:member:`httpd_ssl_config.transport_mode`. This could be used e.g. for testing or in trusted environments where you prefer speed over security.
|
||||
The server can be started with or without SSL by changing a flag in the init struct - :cpp:member:`httpd_ssl_config::transport_mode`. This could be used e.g. for testing or in trusted environments where you prefer speed over security.
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
||||
@@ -153,7 +153,7 @@ TX FIFO
|
||||
receive data from the master. This is optional. The master will poll `tx_buffer_num` when it try
|
||||
to send packets to the slave, until the slave has enough buffer or timeout.
|
||||
|
||||
2. Call :cpp:func:`essl_send_paket` to send data to the slave.
|
||||
2. Call :cpp:func:`essl_send_packet` to send data to the slave.
|
||||
|
||||
RX FIFO
|
||||
^^^^^^^
|
||||
|
||||
@@ -56,6 +56,7 @@ The header file :component_file:`fatfs/vfs/esp_vfs_fat.h` defines convenience fu
|
||||
The convenience function :cpp:func:`esp_vfs_fat_sdmmc_unmount` unmounts the filesystem and releases the resources acquired by :cpp:func:`esp_vfs_fat_sdmmc_mount`.
|
||||
|
||||
.. doxygenfunction:: esp_vfs_fat_sdmmc_mount
|
||||
.. doxygenfunction:: esp_vfs_fat_sdmmc_unmount
|
||||
.. doxygenfunction:: esp_vfs_fat_sdspi_mount
|
||||
.. doxygenstruct:: esp_vfs_fat_mount_config_t
|
||||
:members:
|
||||
|
||||
@@ -99,7 +99,7 @@ This is the set of API functions for working with data in flash:
|
||||
- :cpp:func:`esp_flash_write` writes data from RAM to flash
|
||||
- :cpp:func:`esp_flash_erase_region` erases specific region of flash
|
||||
- :cpp:func:`esp_flash_erase_chip` erases the whole flash
|
||||
- :cpp:func:`esp_flash_get_chip_size` returns flash chip size, in bytes, as configured in menuconfig
|
||||
- :cpp:func:`spi_flash_get_chip_size` returns flash chip size, in bytes, as configured in menuconfig
|
||||
|
||||
Generally, try to avoid using the raw SPI flash functions to the "main" SPI flash chip in favour of :ref:`partition-specific functions <flash-partition-apis>`.
|
||||
|
||||
@@ -108,7 +108,7 @@ SPI Flash Size
|
||||
|
||||
The SPI flash size is configured by writing a field in the software bootloader image header, flashed at offset 0x1000.
|
||||
|
||||
By default, the SPI flash size is detected by esptool.py when this bootloader is written to flash, and the header is updated with the correct size. Alternatively, it is possible to generate a fixed flash size by setting :envvar:`CONFIG_ESPTOOLPY_FLASHSIZE` in project configuration.
|
||||
By default, the SPI flash size is detected by esptool.py when this bootloader is written to flash, and the header is updated with the correct size. Alternatively, it is possible to generate a fixed flash size by setting :ref:`CONFIG_ESPTOOLPY_FLASHSIZE` in project configuration.
|
||||
|
||||
If it is necessary to override the configured flash size at runtime, it is possible to set the ``chip_size`` member of the ``g_rom_flashchip`` structure. This size is used by ``esp_flash_*`` functions (in both software & ROM) to check the bounds.
|
||||
|
||||
@@ -228,7 +228,7 @@ The delay is used by some long operations which requires the master to wait or p
|
||||
|
||||
The top API wraps these the chip driver and OS functions into an entire component, and also provides some argument checking.
|
||||
|
||||
OS functions can also help to avoid a watchdog timeout when erasing large flash areas. During this time, the CPU is occupied with the flash erasing task. This stops other tasks from being executed. Among these tasks is the idle task to feed the watchdog timer (WDT). If the configuration option :ref:`CONFIG_ESP_TASK_WDT_PANIC` is selected and the flash operation time is longer than the watchdog timeout period, the system will reboot.
|
||||
OS functions can also help to avoid a watchdog timeout when erasing large flash areas. During this time, the CPU is occupied with the flash erasing task. This stops other tasks from being executed. Among these tasks is the idle task to feed the watchdog timer (WDT). If the configuration option :ref:`CONFIG_ESP_TASK_WDT_PANIC` is selected and the flash operation time is longer than the watchdog timeout period, the system will reboot.
|
||||
|
||||
It's pretty hard to totally eliminate this risk, because the erasing time varies with different flash chips, making it hard to be compatible in flash drivers. Therefore, users need to pay attention to it. Please use the following guidelines:
|
||||
|
||||
@@ -273,7 +273,9 @@ API Reference - SPI Flash
|
||||
|
||||
.. include-build-file:: inc/esp_flash_spi_init.inc
|
||||
.. include-build-file:: inc/esp_flash.inc
|
||||
.. include-build-file:: inc/esp_spi_flash.inc
|
||||
.. include-build-file:: inc/spi_flash_types.inc
|
||||
.. include-build-file:: inc/esp_flash_err.inc
|
||||
|
||||
.. _api-reference-partition-table:
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ If a function or symbol is not correctly put into IRAM/DRAM, and the interrupt h
|
||||
|
||||
.. note::
|
||||
|
||||
When working with string in ISRs, it is not advised to use ``printf`` and other output functions. For debugging purposes, use :cpp:func:`ESP_DRAM_LOGE` and similar macros when logging from ISRs. Make sure that both ``TAG`` and format string are placed into ``DRAM`` in that case.
|
||||
When working with string in ISRs, it is not advised to use ``printf`` and other output functions. For debugging purposes, use :c:macro:`ESP_DRAM_LOGE` and similar macros when logging from ISRs. Make sure that both ``TAG`` and format string are placed into ``DRAM`` in that case.
|
||||
|
||||
Non-IRAM-Safe Interrupt Handlers
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -140,7 +140,7 @@ A socket VFS driver needs to be registered with the following functions defined:
|
||||
Please see :component_file:`lwip/port/esp32/vfs_lwip.c` for a reference socket driver implementation using LWIP.
|
||||
|
||||
.. note::
|
||||
If you use :cpp:func:`select` for socket file descriptors only then you can disable the :envvar:`CONFIG_VFS_SUPPORT_SELECT` option to reduce the code size and improve performance.
|
||||
If you use :cpp:func:`select` for socket file descriptors only then you can disable the :ref:`CONFIG_VFS_SUPPORT_SELECT` option to reduce the code size and improve performance.
|
||||
You should not change the socket driver during an active :cpp:func:`select` call or you might experience some undefined behavior.
|
||||
|
||||
Paths
|
||||
|
||||
@@ -11,7 +11,7 @@ An application image consists of the following structures:
|
||||
* offset for 2 Segment = offset for 1 Segment + length of 1 Segment + sizeof(:cpp:type:`esp_image_segment_header_t`).
|
||||
* ...
|
||||
|
||||
The count of each segment is defined in the ``segment_count`` field that is stored in :cpp:type:`esp_image_header_t`. The count cannot be more than :cpp:type:`ESP_IMAGE_MAX_SEGMENTS`.
|
||||
The count of each segment is defined in the ``segment_count`` field that is stored in :cpp:type:`esp_image_header_t`. The count cannot be more than :c:macro:`ESP_IMAGE_MAX_SEGMENTS`.
|
||||
|
||||
To get the list of your image segments, please run the following command:
|
||||
|
||||
|
||||
@@ -377,4 +377,5 @@ esptool includes a useful tool for reading/writing {IDF_TARGET_NAME} eFuse bits
|
||||
.. include:: inc/espefuse_summary_{IDF_TARGET_NAME}.rst
|
||||
|
||||
|
||||
.. include-build-file:: inc/esp_efuse.inc
|
||||
.. include-build-file:: inc/components/efuse/{IDF_TARGET_PATH_NAME}/include/esp_efuse.inc
|
||||
.. include-build-file:: inc/components/efuse/include/esp_efuse.inc
|
||||
|
||||
@@ -10,5 +10,5 @@ For the full list of error codes defined in ESP-IDF, see :doc:`Error Code Refere
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/esp_check.inc
|
||||
.. include-build-file:: inc/esp_err.inc
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ The ESP32 can access external SPI RAM transparently, so you can use it as normal
|
||||
space for external memory is limited in size, only the first 4MiB can be used as such. Access to the remaining memory is still possible,
|
||||
however this needs to go through a bankswitching scheme controlled by the himem API.
|
||||
|
||||
Specifically, what is implemented by the himem API is a bankswitching scheme. Hardware-wise, the 4MiB region for external SPI RAM is
|
||||
Specifically, what is implemented by the himem API is a bankswitching scheme. Hardware-wise, the 4MiB region for external SPI RAM is
|
||||
mapped into the CPU address space by a MMU, which maps a configurable 32K bank/page of external SPI RAM into each of the 32K pages in the
|
||||
4MiB region accessed by the CPU. For external memories that are <=4MiB, this MMU is configured to unity mapping, effectively mapping each
|
||||
CPU address 1-to-1 to the external SPI RAM address.
|
||||
|
||||
In order to use the himem API, you have to enable it in the menuconfig using :envvar:`CONFIG_SPIRAM_BANKSWITCH_ENABLE`, as well as set the amount
|
||||
of banks reserved for this in :envvar:`CONFIG_SPIRAM_BANKSWITCH_RESERVE`. This decreases
|
||||
In order to use the himem API, you have to enable it in the menuconfig using :ref:`CONFIG_SPIRAM_BANKSWITCH_ENABLE`, as well as set the amount
|
||||
of banks reserved for this in :ref:`CONFIG_SPIRAM_BANKSWITCH_RESERVE`. This decreases
|
||||
the amount of external memory allocated by functions like ``malloc()``, but it allows you to use the himem api to map any of the remaining memory
|
||||
into the reserved banks.
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ System API
|
||||
intr_alloc
|
||||
log
|
||||
system
|
||||
soc_caps
|
||||
ota
|
||||
:CONFIG_IDF_TARGET_ARCH_XTENSA: perfmon
|
||||
power_management
|
||||
@@ -36,6 +37,7 @@ System API
|
||||
:SOC_ULP_SUPPORTED: ulp
|
||||
:SOC_RISCV_COPROC_SUPPORTED: ulp-risc-v
|
||||
wdts
|
||||
|
||||
|
||||
|
||||
|
||||
Code examples for this API section are provided in the :example:`system` directory of ESP-IDF examples.
|
||||
|
||||
@@ -153,7 +153,7 @@ Knowledge about the regions of memory in the chip comes from the "soc" component
|
||||
|
||||
Each contiguous region of memory contains its own memory heap. The heaps are created using the `multi_heap <API Reference - Multi Heap API>`_ functionality. multi_heap allows any contiguous region of memory to be used as a heap.
|
||||
|
||||
The heap capabilities allocator uses knowledge of the memory regions to initialize each individual heap. Allocation functions in the heap capabilities API will find the most appropriate heap for the allocation (based on desired capabilities, available space, and preferences for each region's use) and then calling :cpp:func:`multi_heap_malloc` or :cpp:func:`multi_heap_calloc` for the heap situated in that particular region.
|
||||
The heap capabilities allocator uses knowledge of the memory regions to initialize each individual heap. Allocation functions in the heap capabilities API will find the most appropriate heap for the allocation (based on desired capabilities, available space, and preferences for each region's use) and then calling :cpp:func:`multi_heap_malloc` for the heap situated in that particular region.
|
||||
|
||||
Calling ``free()`` involves finding the particular heap corresponding to the freed address, and then calling :cpp:func:`multi_heap_free` on that particular multi_heap instance.
|
||||
|
||||
|
||||
@@ -100,10 +100,10 @@ When DFS is enabled, the APB frequency can be changed multiple times within a si
|
||||
|
||||
The following peripherals work normally even when the APB frequency is changing:
|
||||
|
||||
- **UART**: if REF_TICK is used as a clock source. See `use_ref_tick` member of :cpp:class:`uart_config_t`.
|
||||
- **UART**: if REF_TICK is used as a clock source. See cpp:member:`uart_config_t::use_ref_tick`.
|
||||
- **LEDC**: if REF_TICK is used as a clock source. See :cpp:func:`ledc_timer_config` function.
|
||||
- **RMT**: if REF_TICK or XTAL is used as a clock source. See `flags` member of :cpp:class:`rmt_config_t` and macro `RMT_CHANNEL_FLAGS_AWARE_DFS`.
|
||||
- **GPTimer**: if APB is used as the clock source. See :c:member:`clk_src` member of :c:type:`gptimer_config_t`.
|
||||
- **RMT**: if REF_TICK or XTAL is used as a clock source. See :cpp:member:`rmt_config_t::flags` and macro `RMT_CHANNEL_FLAGS_AWARE_DFS`.
|
||||
- **GPTimer**: if APB is used as the clock source. See :cpp:member:`gptimer_config_t::clk_src`.
|
||||
- **TSENS**: XTAL or RTC_8M is used as a clock source. So, APB frequency changing will not influence it.
|
||||
|
||||
Currently, the following peripheral drivers are aware of DFS and will use the ``ESP_PM_APB_FREQ_MAX`` lock for the duration of the transaction:
|
||||
|
||||
@@ -78,7 +78,7 @@ This wakeup mode doesn't require RTC peripherals or RTC memories to be powered o
|
||||
|
||||
RTC IO module contains logic to trigger wakeup when one of RTC GPIOs is set to a predefined logic level. RTC IO is part of RTC peripherals power domain, so RTC peripherals will be kept powered on during deep sleep if this wakeup source is requested.
|
||||
|
||||
Because RTC IO module is enabled in this mode, internal pullup or pulldown resistors can also be used. They need to be configured by the application using :cpp:func:`rtc_gpio_pullup_en` and :cpp:func:`rtc_gpio_pulldown_en` functions, before calling :cpp:func:`esp_sleep_start`.
|
||||
Because RTC IO module is enabled in this mode, internal pullup or pulldown resistors can also be used. They need to be configured by the application using :cpp:func:`rtc_gpio_pullup_en` and :cpp:func:`rtc_gpio_pulldown_en` functions, before calling :cpp:func:`esp_deep_sleep_start`.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@@ -136,7 +136,7 @@ This wakeup mode doesn't require RTC peripherals or RTC memories to be powered o
|
||||
|
||||
.. warning::
|
||||
Before entering light sleep mode, check if any GPIO pin to be driven is part of the {IDF_TARGET_SPI_POWER_DOMAIN} power domain. If so, this power domain must be configured to remain ON during sleep.
|
||||
|
||||
|
||||
For example, on ESP32-WROOM-32 board, GPIO16 and GPIO17 are linked to {IDF_TARGET_SPI_POWER_DOMAIN} power domain. If they are configured to remain high during
|
||||
light sleep, the power domain should be configured to remain powered ON. This can be done with :cpp:func:`esp_sleep_pd_config()`::
|
||||
|
||||
@@ -195,10 +195,10 @@ Some {IDF_TARGET_NAME} IOs have internal pullups or pulldowns, which are enabled
|
||||
.. only:: esp32c3
|
||||
|
||||
In deep sleep mode:
|
||||
- digital GPIOs (GPIO6 ~ 21) are in a high impedance state.
|
||||
- digital GPIOs (GPIO6 ~ 21) are in a high impedance state.
|
||||
- RTC GPIOs (GPIO0 ~ 5) can be in the following states, depending on their hold function enabled or not:
|
||||
- if the hold function is not enabled, RTC GPIOs will be in a high impedance state.
|
||||
- if the hold function is enabled, RTC GPIOs will retain the pin state latched at that hold moment.
|
||||
- if the hold function is enabled, RTC GPIOs will retain the pin state latched at that hold moment.
|
||||
|
||||
UART output handling
|
||||
--------------------
|
||||
|
||||
14
docs/en/api-reference/system/soc_caps.rst
Normal file
14
docs/en/api-reference/system/soc_caps.rst
Normal file
@@ -0,0 +1,14 @@
|
||||
SoC Capabilities
|
||||
================
|
||||
|
||||
This section lists definitions of the {IDF_TARGET_NAME}'s SoC hardware capabilities. These definitions are commonly used in IDF to control which hardware dependent features are supported and thus compiled into the binary.
|
||||
|
||||
.. note::
|
||||
|
||||
These defines are currently not considered to be part of the public API, and may be changed at any time.
|
||||
|
||||
|
||||
API Reference
|
||||
-------------
|
||||
|
||||
.. include-build-file:: inc/soc_caps.inc
|
||||
@@ -204,3 +204,5 @@ API Reference
|
||||
.. include-build-file:: inc/esp_system.inc
|
||||
.. include-build-file:: inc/esp_idf_version.inc
|
||||
.. include-build-file:: inc/esp_mac.inc
|
||||
.. include-build-file:: inc/esp_chip_info.inc
|
||||
.. include-build-file:: inc/esp_cpu.inc
|
||||
|
||||
@@ -114,7 +114,7 @@ To start synchronization via SNTP, just call the following three functions.
|
||||
sntp_setservername(0, "pool.ntp.org");
|
||||
sntp_init();
|
||||
|
||||
An application with this initialization code will periodically synchronize the time. The time synchronization period is determined by :envvar:`CONFIG_LWIP_SNTP_UPDATE_DELAY` (default value is one hour). To modify the variable, set :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` in project configuration.
|
||||
An application with this initialization code will periodically synchronize the time. The time synchronization period is determined by :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` (default value is one hour). To modify the variable, set :ref:`CONFIG_LWIP_SNTP_UPDATE_DELAY` in project configuration.
|
||||
|
||||
A code example that demonstrates the implementation of time synchronization based on the lwIP SNTP library is provided in :example:`protocols/sntp` directory.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user