Edit online

关键流程设计

4 Dec 2024
Read time: 2 minute(s)

初始化流程

  1. 释放 reset 和 clock 信号

  2. 注册 i2s 设备

Playback 流程

  • init 流程
    1. 初始化 DMA 传输的起始地址,buf_len 以及 period_len

    2. 注册 hal 层的回调函数

    3. 初始化 codec

    I2S 模块使用 DMA 传输音频数据,DMA 采用环形链表形式,依次将音频数据传送到硬件。所以需要配置 DMA 传输时的起始地址(即 TX buffer 地址)以及 buf_len,period_len。在 driver 层驱动,将 buf_len 配置为 period_len 的 4 倍,DMA 每传输 period_len 长度的数据,触发一次 DMA 中断,通知 CPU 向 TX buffer 中写入数据。

  • start 流程
    1. 填充 TX buffer

    2. 设置 DMA 传输的参数,调用 hal_i2s_playback_start 开始音频数据传输

    3. 调用 codec_start 启用 codec 芯片

    4. 使能 PA

    为保证 DMA 传输音频数据的连续性,需要在 DMA 开始传输前,先向 TX buffer 中填充数据。在 playback 的 driver 层驱动,是将 TX buffer 填充满后,才开始 DMA 的传输。

  • DMA 中断流程

    DMA 每传输完 period_len 长度的数据后,触发一次 DMA 中断,然后通过 DMA 回调函数的逐级调用,最终调用 rt_audio_tx_complete 对 TX buffer 进行填充,每次填充 period_len 长度的音频数据。

Record 流程

  • init 流程
    1. 初始化 DMA 传输的起始地址、buf_len 以及 period_len

      I2S 模块使用 DMA 传输音频数据,DMA 采用环形链表形式,依次将音频数据传送到硬件。所以需要配置 DMA 传输时的起始地址(即 RX buffer 地址)以及 buf_lenperiod_len

    2. 注册 HAL 层的回调函数。

      在 Driver 层驱动,将 buf_len 配置为 period_len 的 2 倍,DMA 每传输 period_len 长度的数据,触发一次 DMA 中断,通知 CPU 向 pipe 设备写入数据。

  • start 流程

    按照 RT-Thread audio 的框架,在执行 rt_device_open 时,就会调用 start 流程,开始音频的录制,然后再通过 rt_device_control 设置音频的格式(采样率,通道数等)。按照这个流程,最开始可能会录制一段不符合设置的音频格式的数据,这显然是不合理的。所以,在 Driver 层的驱动实现中,start 流程并未做任何处理,而是在设置完音频格式后才开始音频的录制。

  • DMA 中断流程

    DMA 每传输完 period_len 长度的数据后,触发一次 DMA 中断,然后通过 DMA 回调函数的逐级调用,最终调用 rt_audio_rx_done,将 RX buffer 的数据写入到 pipe 设备,每次写入 period_len 长度的音频数据。