API GUIDE / AIC / API OVERVIEW

AIC API 概述

1. 文档范围

本文档定义 G32S10 AIC 的 LL(Low Level)和 HAL(Hardware Abstraction Layer) 正式接口,面向板级音频驱动、Audio middleware、测试代码和需要直接控制 AIC 的 集成代码。

本文档以当前 SDK 源码为准:

类型 路径
寄存器定义 code/include/drivers/g32s10/aic/aic_regs.h
LL 接口 code/include/drivers/g32s10/aic/ll_aic.h
HAL 接口 code/include/drivers/g32s10/aic/hal_aic.h
LL/HAL 实现 code/drivers/g32s10/aic/hal_aic.c
Kconfig code/drivers/g32s10/aic/Kconfig
CMake code/drivers/g32s10/aic/CMakeLists.txt

补充说明:

  • LL 接口是直接寄存器访问 helper,不校验实例和参数,要求调用方保证寄存器时钟、 pinmux 和运行状态合法。
  • HAL 接口负责实例校验、AIC 状态、FIFO 阈值、复位等待、中断分发和寄存器配置。
  • HAL 不管理 pinmux、外部 codec、PDMA channel、PCM buffer 或 descriptor。
  • AIC 的 Audio middleware 接口见 G32S10 Audio MID 正式接口文档。

2. 分层关系与依赖

Application / Audio Core / Board
              |
              v
          HAL AIC
              |
              v
           LL AIC
              |
              v
        AIC Registers
              |
              +---- CPM AIC gate / CGU I2S TX/RX
              +---- Board pinmux
              +---- External codec or internal codec
              +---- PDMA channel (owned outside HAL)

HAL 层职责:

  • 初始化 caller-owned hal_aic_handle_t。
  • 管理 AIC module gate 和可选 SoC I2S CGU clocks。
  • 配置 4-wire/6-wire、外部/内部 codec、TX/RX clock role。
  • 配置 I2S/MSB format、sample width、signedness、channel 和 endian。
  • 执行硬件 reset 并等待 FIFO reset 完成。
  • 管理 TX/RX/LOOP FIFO 阈值、状态、flush 和错误标志。
  • 管理 playback/capture/loop callback 和 IRQ 分发。
  • 提供 DMA data-port 地址;DMA channel 和 descriptor 由上层管理。

主要依赖:

依赖 用途
DRIVER_CPM HAL_CPM_ID_GATE_AIC、I2S TX/RX CGU
IRQ/PLIC 上层注册 AIC IRQ 并调用 hal_aic_irq_handler()
Board pinmux MCLK、BCLK、LRCK、DI、DO 引脚
External codec 由 BSP 控制 reset、I2C 和 DAI format
DMA middleware 使用 hal_aic_fifo_data_address_get() 得到的 FIFO 地址

3. 构建配置与文件组织

最小配置:

CONFIG_DRIVER_CPM=y
CONFIG_DRIVER_AIC=y

DRIVER_AIC 自动选择 DRIVER_CPM。

文件 说明
aic_regs.h 唯一 AIC 实例、寄存器布局、基地址和位域宏
ll_aic.h 全部 inline 寄存器 helper
hal_aic.h 类型、handle、callback 和 HAL API
hal_aic.c 时钟、配置、复位、FIFO、状态和 IRQ 实现
Kconfig DRIVER_AIC
CMakeLists.txt AIC 组件构建规则

应用或 BSP 包含:

#include "hal_aic.h"

需要直接访问寄存器时再包含:

#include "ll_aic.h"

4. 实例与资源所有权

G32S10 当前只有一个 AIC 实例:

#define AIC ((aic_regs_t *)(uintptr_t)AIC_IOBASE)
资源 所有者
AIC 寄存器块 SoC
AIC/FIFO 配置状态 hal_aic_handle_t
AIC module gate hal_aic_init() / hal_aic_deinit()
I2S TX/RX CGU hal_aic_clock_enable() / hal_aic_clock_disable()
pinmux BSP
AIC IRQ 注册 上层
PDMA channel/descriptor/buffer Audio middleware 或调用方
外部 codec 控制 BSP/codec driver

hal_aic_handle_t 必须由调用方分配并保持到 deinit 完成。不得复制一个正在使用的 handle。

5. 寄存器映射

基地址宏为 AIC_IOBASE。

偏移 寄存器 访问 主要用途
0x000 AICFR RW enable、master/slave、reset、codec route、时钟线模式、FIFO 阈值
0x004 AICCR RW playback/capture/loop enable、DMA、IRQ、数据格式、flush
0x010 I2SCR RW I2S/MSB、LR order、packed LR swap
0x014 AICSR RW FIFO level、service 和 error flags
0x01C I2SSR RO I2S BSY/TBSY/RBSY/CHBSY
0x030 I2SDIV RW I2S IDV/DV divider
0x034 AICDR RW playback TX / capture RX data port
0x038 AICLR RO loop FIFO data port
0x03C AICTFLR RW loop FIFO threshold

FIFO 深度:

FIFO 深度
TX 64 entries
RX 64 entries
LOOP 32 entries

6. 关键运行模型

6.1 Stream

hal_aic_stream_t 的值是按位标志:

值 方向 Data/FIFO
HAL_AIC_STREAM_PLAYBACK DAC/TX AICDR + TX FIFO
HAL_AIC_STREAM_CAPTURE ADC/RX AICDR + RX FIFO
HAL_AIC_STREAM_LOOP TX reference AICLR + LOOP FIFO

虽然枚举值可组合,HAL 的 start/stop 每次只接受一个 stream。

6.2 LOOP reference path

HAL_AIC_STREAM_LOOP 提供播放参考数据:

playback PCM -> TX FIFO -> codec
                    |
                    +-> LOOP FIFO -> AICLR

hal_aic_stream_start(..., HAL_AIC_STREAM_LOOP, mode) 使能 ETFL,并设置 LOOP FIFO 的 DMA request。LOOP 读取的是 TX FIFO 的数字副本,不经过扬声器、空气和 麦克风。

主要资源:

项目 值
FIFO LOOP FIFO,32 entries
数据端口 AICLR
阈值 AICTFLR.TFLTH
状态 AICSR.TFLL/TFLS/TFLOR
DMA request HAL_DMA_REQUEST_AIC_RX_LOOPBACK

使用约束:

  1. LOOP 与 playback 使用相同的 format、sample width、rate 和 channel。
  2. playback 必须已经启动,LOOP 才能获得有效数据。
  3. LOOP 使用独立 PCM buffer,不能与 playback/capture 共享 ring。
  4. HAL 只负责 AIC FIFO 和 request;DMA buffer、channel 和 cache 由 Audio middleware 管理。

6.3 Transfer mode

模式 AIC 侧动作
HAL_AIC_TRANSFER_POLLING 只开 stream,数据由 CPU 轮询 FIFO
HAL_AIC_TRANSFER_INTERRUPT 开对应 FIFO service IRQ
HAL_AIC_TRANSFER_DMA 开对应 DMA request

HAL 不创建 DMA channel,也不搬运 descriptor。DMA 模式下,外部 DMA 必须先就绪。

6.4 4-wire 与 6-wire

4-wire:

TX 和 RX 共用 TX clock source。
设置采样率时 TX/RX divider 同步更新。

默认要求 playback/capture clock role 相同。ICOD LOOP 参考通路的合法组合是
external TX 作为共享时钟 master、internal RX 作为 slave。

6-wire:

TX 和 RX 使用独立时钟。
只允许 external codec。
设置采样率时只更新目标方向的 divider。

内部 codec 模式要求对应方向为 HAL_AIC_CLOCK_SLAVE。

6.5 Clock role

HAL role 含义
HAL_AIC_CLOCK_MASTER AIC 输出 BIT_CLK/LRCK
HAL_AIC_CLOCK_SLAVE AIC 接收外部 codec/FPGA 提供的 BIT_CLK/LRCK

hal_aic_clock_enable() 始终同时准备 TX/RX CGU,但实际 divider 由 hal_aic_clock_set_sample_rate() 按 wire mode 更新。生成 MCLK 为:

MCLK = sample_rate_hz * 256

启用 CONFIG_CPM_ENABLE_STUB=y 时,HAL 不写 CGU,外部必须提供音频时钟。真实 SoC 板通常不应启用 CPM stub。

6.6 Reset

hal_aic_reset() 触发 AIC 核心 reset:

  • playback 等待 TX FIFO reset 位清零。
  • capture 等待 RX FIFO reset 位清零。
  • LOOP 根据 master 配置等待对应 FIFO。
  • 调用前必须有 BIT_CLK 和有效的微秒时基。
  • 非 stub CPM 下,reset 期间临时把 TX/RX 切成 master,以产生内部时钟。
  • reset 成功会清除 FIFO error,并把 handle 置回 READY。
  • reset 失败会把 handle 置 ERROR,并记录 HAL_AIC_ERROR_RESET_TIMEOUT。
  • 硬件 reset 保留 AICFR 和 I2SDIV,但会使 frame format/stream 配置失效。

6.7 FIFO threshold

hal_aic_fifo_threshold_configure() 使用实际 entry 数,且必须为偶数:

Stream 可用值
PLAYBACK 0, 2, 4, ..., 62
CAPTURE 2, 4, ..., 64
LOOP 2, 4, ..., 32

配置 threshold 不会自动开启 IRQ、DMA 或 stream。

7. 常见错误与检查项

现象 检查项
hal_aic_init() 失败 CONFIG_DRIVER_CPM、AIC gate、时钟树
clock_enable() 返回 NOT_READY 是否已 init 和 configure connection
clock_set_sample_rate() 失败 CGU parent、divider 能否产生 fs*256
reset timeout BIT_CLK/LRCK 是否运行、pinmux、CPM stub、clock role
stream start busy 同一方向是否已 active
DMA 无请求 hal_aic_stream_start(..., DMA)、FIFO threshold、外部 PDMA
采到全零 DI pinmux、外部 codec clock/data、codec ADC path
放音无声 DO pinmux、codec DAI、codec enable、功放 enable
capture overrun 上层读取不及时、FIFO threshold 或 CPU 阻塞
playback underrun TX FIFO 未预填、DMA 供数过慢
I2S/MSB 不启动 FIRSTCHN_LEFT、复位顺序、clock role

8. 推荐约束

  1. 普通板级音频优先使用 HAL,不要直接展开 LL 初始化序列。
  2. 任何 reset 前必须保证 BIT_CLK 可用。
  3. 运行中不得修改 PRESCALE、wire mode、codec route、frame format 等 reset-sensitive 或格式相关字段。
  4. 同一寄存器的 LL read-modify-write 与 ISR 访问必须串行化。
  5. DMA buffer、descriptor 和 cache 维护不归 AIC HAL 管理。
  6. callback 内只允许 FIFO 操作、清状态和唤醒任务,不得执行阻塞型 codec I2C。