mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
refactor(i2s): combine separate callback registers into single one
This commit is contained in:
@@ -315,7 +315,9 @@ To satisfy the high quality audio requirement, following advanced APIs are provi
|
||||
|
||||
.. only:: SOC_I2S_SUPPORTS_TX_SYNC_CNT
|
||||
|
||||
- :cpp:func:`i2s_channel_get_sync_count`: Read the TX BCLK/FIFO synchronization counters. This API can also actively clear them through the ``reset`` argument.
|
||||
- :cpp:func:`i2s_channel_get_sync_count`: Read the TX synchronization counters through
|
||||
:cpp:type:`i2s_sync_count_t`. When TX FIFO synchronization is supported, ``diff_count`` is also returned.
|
||||
This API can also actively clear the counters through the ``reset`` argument.
|
||||
|
||||
.. only:: SOC_I2S_SUPPORTS_TX_FIFO_SYNC
|
||||
|
||||
@@ -326,12 +328,15 @@ To satisfy the high quality audio requirement, following advanced APIs are provi
|
||||
|
||||
TX FIFO synchronization related APIs include:
|
||||
|
||||
- :cpp:func:`i2s_channel_get_sync_diff_count`: Read the TX FIFO synchronization difference counter. The value is signed and means ``I2S_TX_FIFO_CNT - I2S_TX_FIFO_IDEAL_CNT``.
|
||||
- :cpp:func:`i2s_channel_get_sync_count`: Read the TX synchronization counters through :cpp:type:`i2s_sync_count_t`.
|
||||
When TX FIFO synchronization is supported, ``diff_count`` is also returned as ``I2S_TX_FIFO_CNT - I2S_TX_FIFO_IDEAL_CNT``.
|
||||
- :cpp:func:`i2s_channel_config_tx_fifo_sync`: Configure the expected count, automatic supplement threshold,
|
||||
manual supplement threshold, and hardware supplement mode. After automatic hardware supplementation is
|
||||
enabled, hardware automatically supplements or deletes data according to ``diff_count`` so that the actual
|
||||
count approaches ``ideal_cnt``.
|
||||
- :cpp:func:`i2s_channel_register_intr_event_callback`: Register the manual supplement threshold interrupt callback. When
|
||||
manual supplement threshold, and hardware supplement mode.
|
||||
- :cpp:func:`i2s_channel_enable_tx_fifo_sync`: Enable or disable TX FIFO synchronization. When enabled,
|
||||
both automatic hardware data supplementation and manual interrupt are activated simultaneously.
|
||||
When disabled, both are deactivated. This API must be called after
|
||||
:cpp:func:`i2s_channel_config_tx_fifo_sync`.
|
||||
- :cpp:func:`i2s_channel_register_event_callback`: Register the manual supplement threshold interrupt callback. When
|
||||
``diff_count`` exceeds the manual supplement threshold, the driver calls this callback in the ISR and provides
|
||||
``diff_count`` through :cpp:type:`i2s_sync_event_data_t`.
|
||||
|
||||
@@ -340,18 +345,15 @@ To satisfy the high quality audio requirement, following advanced APIs are provi
|
||||
1. Create and initialize an I2S TX channel.
|
||||
2. Call :cpp:func:`i2s_channel_config_tx_fifo_sync` to configure :cpp:type:`i2s_tx_fifo_sync_config_t`. ``ideal_cnt``
|
||||
is the expected number of transmitted data units at each ETM synchronization check. ``auto_suppl_thresh`` is
|
||||
the automatic hardware supplement threshold: set it to ``0`` to disable automatic hardware supplementation, or
|
||||
set it to a value greater than ``0`` and smaller than ``manual_suppl_thresh`` to enable automatic hardware
|
||||
supplementation. ``manual_suppl_thresh`` is the threshold for triggering the callback for manual handling. Once
|
||||
enabled, if the difference exceeds the automatic supplement threshold but has not reached the manual supplement
|
||||
threshold, hardware automatically supplements or deletes the corresponding amount of data to synchronize with
|
||||
``ideal_cnt``.
|
||||
3. To handle severe out-of-sync conditions, call :cpp:func:`i2s_channel_register_intr_event_callback` to register a callback.
|
||||
After the callback is registered, the driver enables the TX synchronization interrupt. If the difference exceeds
|
||||
the manual supplement threshold, the driver calls this callback in the ISR and provides ``diff_count`` through
|
||||
:cpp:type:`i2s_sync_event_data_t`.
|
||||
4. Call :cpp:func:`i2s_new_etm_task` to create the ``I2S_ETM_TASK_SYNC_FIFO`` task, and connect an external ETM event to this task.
|
||||
5. Enable the ETM channel and I2S TX channel, so that ETM events periodically trigger synchronization checks.
|
||||
the automatic hardware supplement threshold and must be smaller than ``manual_suppl_thresh``.
|
||||
``manual_suppl_thresh`` is the threshold for triggering the callback for manual handling. If the difference
|
||||
exceeds the automatic supplement threshold but has not reached the manual supplement threshold, hardware
|
||||
automatically supplements or deletes the corresponding amount of data to synchronize with ``ideal_cnt``.
|
||||
3. To handle severe out-of-sync conditions, call :cpp:func:`i2s_channel_register_event_callback` to register a callback.
|
||||
4. Call :cpp:func:`i2s_channel_enable_tx_fifo_sync` with ``enable`` set to ``true`` to activate both automatic
|
||||
hardware supplementation and manual interrupt simultaneously.
|
||||
5. Call :cpp:func:`i2s_new_etm_task` to create the ``I2S_ETM_TASK_SYNC_FIFO`` task, and connect an external ETM event to this task.
|
||||
6. Enable the ETM channel and I2S TX channel, so that ETM events periodically trigger synchronization checks.
|
||||
|
||||
The following example shows how to use a GPTimer alarm event to trigger the I2S TX FIFO synchronization check, and
|
||||
get ``diff_count`` in the manual supplement threshold interrupt:
|
||||
@@ -372,7 +374,7 @@ To satisfy the high quality audio requirement, following advanced APIs are provi
|
||||
const i2s_sync_event_data_t *event,
|
||||
void *user_ctx)
|
||||
{
|
||||
// event->diff_count = I2S_TX_FIFO_CNT - I2S_TX_FIFO_IDEAL_CNT
|
||||
// Applications can use event->diff_count to adjust the data source, choose a compensation policy, or report it to upper layers.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -382,11 +384,12 @@ To satisfy the high quality audio requirement, following advanced APIs are provi
|
||||
.auto_suppl_thresh = 32,
|
||||
.suppl_mode = I2S_TX_FIFO_SYNC_SUPPL_MODE_LAST_DATA,
|
||||
};
|
||||
i2s_intr_event_callbacks_t intr_cbs = {
|
||||
.on_tx_sync = i2s_tx_sync_callback,
|
||||
i2s_event_callbacks_t cbs = {
|
||||
.on_tx_sync_evt = i2s_tx_sync_callback,
|
||||
};
|
||||
i2s_channel_config_tx_fifo_sync(tx_handle, &sync_cfg);
|
||||
i2s_channel_register_intr_event_callback(tx_handle, &intr_cbs, NULL);
|
||||
i2s_channel_register_event_callback(tx_handle, &cbs, NULL);
|
||||
i2s_channel_enable_tx_fifo_sync(tx_handle, true);
|
||||
|
||||
i2s_etm_task_config_t i2s_task_cfg = {
|
||||
.task_type = I2S_ETM_TASK_SYNC_FIFO,
|
||||
|
||||
@@ -315,7 +315,9 @@ I2S 的数据传输(包括数据发送和接收)由 DMA 实现。在传输
|
||||
|
||||
.. only:: SOC_I2S_SUPPORTS_TX_SYNC_CNT
|
||||
|
||||
- :cpp:func:`i2s_channel_get_sync_count`:用于读取 TX BCLK/FIFO 同步计数器。该 API 也可通过 ``reset`` 参数主动清零计数器。
|
||||
- :cpp:func:`i2s_channel_get_sync_count`:通过 :cpp:type:`i2s_sync_count_t` 读取
|
||||
TX 同步计数器。当支持 TX FIFO 同步时,也会返回 ``diff_count``。
|
||||
该 API 也可通过 ``reset`` 参数主动清零计数器。
|
||||
|
||||
.. only:: SOC_I2S_SUPPORTS_TX_FIFO_SYNC
|
||||
|
||||
@@ -326,25 +328,32 @@ I2S 的数据传输(包括数据发送和接收)由 DMA 实现。在传输
|
||||
|
||||
TX FIFO 同步相关 API 包括:
|
||||
|
||||
- :cpp:func:`i2s_channel_get_sync_diff_count`:读取 TX FIFO 同步差值计数器。该值为有符号数,含义为 ``I2S_TX_FIFO_CNT - I2S_TX_FIFO_IDEAL_CNT``。
|
||||
- :cpp:func:`i2s_channel_config_tx_fifo_sync`:配置期望计数、自动补偿阈值、手动补偿阈值以及硬件补偿方式。
|
||||
启用硬件自动补偿后,硬件会根据 ``diff_count`` 自动补充或删除数据,使实际计数靠近 ``ideal_cnt``。
|
||||
- :cpp:func:`i2s_channel_register_intr_event_callback`:注册手动补偿阈值中断回调。当 ``diff_count`` 超过手动补偿阈值时,
|
||||
驱动会在 ISR 中调用该回调,并通过 :cpp:type:`i2s_sync_event_data_t` 提供 ``diff_count``。
|
||||
- :cpp:func:`i2s_channel_get_sync_count`:通过 :cpp:type:`i2s_sync_count_t` 读取 TX 同步计数器。
|
||||
当支持 TX FIFO 同步时,也会返回 ``diff_count``,其含义为 ``I2S_TX_FIFO_CNT - I2S_TX_FIFO_IDEAL_CNT``。
|
||||
- :cpp:func:`i2s_channel_config_tx_fifo_sync`:配置期望计数、自动补偿阈值、
|
||||
手动补偿阈值以及硬件补偿方式。
|
||||
- :cpp:func:`i2s_channel_enable_tx_fifo_sync`:使能或关闭 TX FIFO 同步功能。使能后,
|
||||
硬件自动补偿和手动补偿中断同时激活。
|
||||
关闭后,两者同时停用。该 API 必须在
|
||||
:cpp:func:`i2s_channel_config_tx_fifo_sync` 之后调用。
|
||||
- :cpp:func:`i2s_channel_register_event_callback`:注册手动补偿阈值中断回调。当
|
||||
``diff_count`` 超过手动补偿阈值时,驱动会在 ISR 中调用该回调,并通过
|
||||
:cpp:type:`i2s_sync_event_data_t` 提供 ``diff_count``。
|
||||
|
||||
使用该功能的一般步骤如下:
|
||||
|
||||
1. 创建并初始化 I2S TX 通道。
|
||||
2. 调用 :cpp:func:`i2s_channel_config_tx_fifo_sync` 配置 :cpp:type:`i2s_tx_fifo_sync_config_t`。其中 ``ideal_cnt``
|
||||
为每次 ETM 同步检查时期望发送的数据个数;``auto_suppl_thresh`` 为硬件自动补偿阈值,设置为 ``0`` 表示
|
||||
关闭硬件自动补偿,设置为大于 ``0`` 且小于 ``manual_suppl_thresh`` 表示开启硬件自动补偿;
|
||||
``manual_suppl_thresh`` 为触发回调并交由软件手动处理的阈值。开启后,如果偏差超过自动补偿阈值但尚未达到
|
||||
手动补偿阈值,硬件会自动补充或删除相应数量的数据,以实现与 ``ideal_cnt`` 同步。
|
||||
3. 如需处理严重不同步场景,调用 :cpp:func:`i2s_channel_register_intr_event_callback` 注册回调。注册回调后,驱动会使能
|
||||
TX 同步中断;如果偏差超过手动补偿阈值,驱动会在 ISR 中调用该回调,并通过
|
||||
:cpp:type:`i2s_sync_event_data_t` 提供 ``diff_count``。
|
||||
4. 调用 :cpp:func:`i2s_new_etm_task` 创建 ``I2S_ETM_TASK_SYNC_FIFO`` 任务,并将外部 ETM 事件连接到该任务。
|
||||
5. 使能 ETM 通道和 I2S TX 通道,由 ETM 事件周期性触发同步检查。
|
||||
2. 调用 :cpp:func:`i2s_channel_config_tx_fifo_sync` 配置 :cpp:type:`i2s_tx_fifo_sync_config_t`。``ideal_cnt``
|
||||
为每次 ETM 同步检查时期望发送的数据个数;``auto_suppl_thresh`` 为
|
||||
硬件自动补偿阈值,必须小于 ``manual_suppl_thresh``。
|
||||
``manual_suppl_thresh`` 为触发回调并交由软件手动处理的阈值。如果偏差
|
||||
超过自动补偿阈值但尚未达到手动补偿阈值,硬件会自动补充或删除相应数量的数据,
|
||||
以实现与 ``ideal_cnt`` 同步。
|
||||
3. 如需处理严重不同步场景,调用 :cpp:func:`i2s_channel_register_event_callback` 注册回调。
|
||||
4. 调用 :cpp:func:`i2s_channel_enable_tx_fifo_sync` 并将 ``enable`` 设为 ``true``,同时激活硬件自动补偿
|
||||
和手动补偿中断。
|
||||
5. 调用 :cpp:func:`i2s_new_etm_task` 创建 ``I2S_ETM_TASK_SYNC_FIFO`` 任务,并将外部 ETM 事件连接到该任务。
|
||||
6. 使能 ETM 通道和 I2S TX 通道,由 ETM 事件周期性触发同步检查。
|
||||
|
||||
以下示例展示了如何使用 GPTimer alarm event 触发 I2S TX FIFO 同步检查,并在手动补偿阈值中断中获取
|
||||
``diff_count``:
|
||||
@@ -365,7 +374,7 @@ I2S 的数据传输(包括数据发送和接收)由 DMA 实现。在传输
|
||||
const i2s_sync_event_data_t *event,
|
||||
void *user_ctx)
|
||||
{
|
||||
// event->diff_count = I2S_TX_FIFO_CNT - I2S_TX_FIFO_IDEAL_CNT
|
||||
// 应用可根据 event->diff_count 决定是否调整数据源、补偿策略或上报给上层处理
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -375,11 +384,12 @@ I2S 的数据传输(包括数据发送和接收)由 DMA 实现。在传输
|
||||
.auto_suppl_thresh = 32,
|
||||
.suppl_mode = I2S_TX_FIFO_SYNC_SUPPL_MODE_LAST_DATA,
|
||||
};
|
||||
i2s_intr_event_callbacks_t intr_cbs = {
|
||||
.on_tx_sync = i2s_tx_sync_callback,
|
||||
i2s_event_callbacks_t cbs = {
|
||||
.on_tx_sync_evt = i2s_tx_sync_callback,
|
||||
};
|
||||
i2s_channel_config_tx_fifo_sync(tx_handle, &sync_cfg);
|
||||
i2s_channel_register_intr_event_callback(tx_handle, &intr_cbs, NULL);
|
||||
i2s_channel_register_event_callback(tx_handle, &cbs, NULL);
|
||||
i2s_channel_enable_tx_fifo_sync(tx_handle, true);
|
||||
|
||||
i2s_etm_task_config_t i2s_task_cfg = {
|
||||
.task_type = I2S_ETM_TASK_SYNC_FIFO,
|
||||
|
||||
Reference in New Issue
Block a user