refactor(i2s): combine separate callback registers into single one

This commit is contained in:
Chen Chen
2026-07-13 14:43:55 +08:00
parent c27bd91874
commit b8218f4fe1
11 changed files with 263 additions and 197 deletions
+25 -22
View File
@@ -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,
+30 -20
View File
@@ -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,