☰
基于炬芯ATS308X内置音乐铃声与扫频音频功能实现
2026/10/14 3:33:25 网站建设 项目流程

# 内置音乐铃声与扫频音频

当前版本包含 **score51-v1 四首方波歌曲 + sweep-v1 内置 WAV 扫频**。用户已确认四首旋律正常;本次针对音量过大,将功放改为 **spk-v6 / AW87390 21 dB / AGC1 防削顶开启**,比上版降低 3 dB。第 6~12 节保留历史排查记录,当前使用方法以第 1~5 节为准。

## 1. 曲目及操作

| 串口命令 | 曲目 | 音符/休止符数量 | 一轮时长(含末尾等待) |
| --- | --- | --- | --- |
| `app ringtone play 1` | 葬花吟 | 75 | 36.150 秒 |
| `app ringtone play 2` | 逍遥游 | 79 | 43.310 秒 |
| `app ringtone play 3` | 枉凝眉 | 92 | 40.615 秒 |
| `app ringtone play 4` | 两只蝴蝶 | 118 | 52.465 秒 |
| `app ringtone play 5` | 用户提供的 100 Hz~8 kHz 扫频 WAV | 32,000 个 PCM 采样点 | 3.950 秒(2 秒音频 + 1.95 秒等待) |

这四首使用用户提供的完整片段,替换原先的梁祝、枉凝眉、美丽的神话三首简化曲谱。每首单独循环,`start` 与 `play` 等效;不带编号时播放当前选中的歌曲。

```text
app ringtone start
app ringtone stop
app ringtone next
app ringtone status
```

K2 单击按 **1 → 2 → 3 → 4 → 5 → 1** 切换。播放时立即切换,停止时只选择下一首。双击、三击及长按仍打印原有按键事件。命令使用原控制台串口,不是 GPIO20/21 的串口测试输出。

铃声播放期间执行 `app pcm_play /NAND:/rec.pcm 16` 会先等待铃声轨道关闭再回放。PCM 回放期间不再打开另一条铃声轨道,K2 只改下一次选曲。

## 2. 51 程序的移植对应关系

| 原 51 程序 | ATS3089P 实现 |
| --- | --- |
| `music[][2]` | `{tone, ticks}` 两字节结构,逐条保留音高编号和时值 |
| `T[m]` 装入 TH0/TL0 | 以同一重装值换算音高,不再按调式重新解释音符 |
| 定时器中断翻转 `beepIO` | 合成正负交替的方波 PCM,经 DAC、AW87390 输出到喇叭 |
| `m == 0` | 输出对应时长的静音 PCM |
| `delay(n)` | 默认 `n × 65 ms`,按采样数计时 |
| 相邻同音执行 `pause()` | 两个相同非零音符之间额外输出 45 ms 静音 |
| `0xFF,0xFF` 后 `delay(30)` | 每首到达数组边界后等待 1950 ms,再从该首开头循环 |

原程序未给晶振、12T/1T 设置及编译器优化选项。本版暂按 **12 MHz / 12T**,即定时器 1 MHz,音高为:

```text
frequency = 1000000 / (2 × (65536 - T[m]))
```

`T[33]` 原文是 `0xFE02`,会在相邻半音中突然降到约 980 Hz;按前后的 `0xFEC0`、`0xFEE3` 修正为 **`0xFED2`**,约 1656 Hz,已加 `//zk+-`。其余 48 项原样保留。曲谱各个音符、休止符和时值均未改写。

65 ms 和 45 ms 是对原空循环延时的移植假设,无法仅凭 C 源码准确还原旧机器的绝对速度。后续确认晶振或试听速度后,可调整 `RINGTONE_TIMER_CLOCK_HZ`、`RINGTONE_TICK_MS`、`RINGTONE_REPEAT_GAP_MS`。所有曲目的相对时值保持原样。

音频为 16 kHz、单声道、16-bit PCM。方波峰值取 23170,使稳定段有效值约等于此前峰值 32767 的正弦波;保留 8 ms 淡入和 25 ms 淡出,减轻音符边界的突变。方波包含谐波,音色本身更接近蜂鸣器;这不能据此认定实板的功放或喇叭破音问题已解决。

数组长度和播放下标使用 16 位计数,按每首实际长度遍历;不把原 51 程序的 8 位 `i` 及混合曲目串播方式直接搬到此平台。

### 第 5 首:内置原 WAV 扫频

原文件 `扫频100hz~8Khz-0db.wav` 为 16 kHz、单声道、16-bit PCM,时长 2 秒,有效 PCM 64,000 字节。已原样复制到 `assets/audio/sweep_100hz_8khz_0db.wav`。构建脚本读取 RIFF 的音频数据,不将尾部 LIST、_PMX 信息块混入声音,也不重新合成或降采样。

生成的 PCM 常量存放于 Flash,沿用 256 采样点工作缓冲逐块播放;无需向 NAND 复制文件。原文件最后一个采样值为 19726,直接接静音可能产生突变,因此播放时对开头 5 ms、末尾 10 ms 做淡入淡出,中间 1985 ms 的采样点逐个保持原值。文件本身保持完整,便于核对和后续替换。

扫频结束后等待 1950 ms 再循环,可随时通过 `app ringtone stop` 停止,或 K2/`app ringtone next` 切换。因原文件采样率是 16 kHz,标称终点 8 kHz 位于奈奎斯特频率,实板高频输出还受 DAC 重建滤波和喇叭影响;本次保留原文件采样率。

### PA 增益调整

`AW87390_DEFAULT_GAIN` 从 `0x10`(24 dB)改为 `0x0E`(21 dB),每次开始播放或切歌均重新配置并读回检查。AGC1 防削顶、6.5 V 升压上限及原功率限制保留。此调整作用于使用 AW87390 的扬声器播放,包括歌曲、扫频和录音回放;不改变 MIC 采集增益。

## 3. 修改位置

| 文件 | 内容 |
| --- | --- |
| `src/main/ringtone_play.c` | 四首曲谱与第 5 首 PCM 扫频,首尾淡化、停止、切换及循环等待 |
| `src/main/ringtone_play.h` | 曲目数改为 5,保留播放、停止、K2 切换和输出交接接口 |
| `src/main/system_app_shell.c` | 命令帮助更新为 `play/start [1-5]`,参数范围自动使用曲目总数 |
| `src/main/CMakeLists.txt`、`tools/generate_ringtone_sweep.py` | 构建时校验 WAV 格式并生成只读 PCM 数组,修改素材会自动重新生成 |
| `assets/audio/sweep_100hz_8khz_0db.wav` | 用户原始 WAV,包含原元数据 |
| `../../zephyr/drivers/audio/phy_external_pa/pa_aw87390.c` | 默认 PA 增益 21 dB,版本日志 spk-v6 |
| `tests/ringtone/score_51_reference.txt` | 保留用户原始音高表与曲谱,用于核对固件数据 |
| `tests/ringtone/run_tests.py` | 从实际 ARM ELF 检查波形和完整播放顺序,并可导出 WAV |

关键改动使用 `//zk+`、`//zk-`、`//zk+-` 标注。Python/CMake 使用对应的 `# zk+`。未自动提交 Git。

## 4. 构建及验证

在 `26A` 下编译并执行回归:

```text
ninja -C application/bt_watch/outdir/ats3089p_dev_watch -j4
python application/bt_watch/tests/ringtone/run_tests.py --wav-dir application/bt_watch/outdir/ringtone_sweep_preview
```

在 `26A/zephyr` 下打包:

```text
python build.py -p -b ats3089p_dev_watch -a bt_watch
```

固件为 `application/bt_watch/outdir/ats3089p_dev_watch/_firmware/ats3089p_dev_watch_261009_debug.fw`,覆盖前备份同名旧包。

验证覆盖:全部 364 个曲谱条目、60 种音符/休止符波形、同音停顿和循环、K2 第 5 首回到第 1 首、非法曲号,以及原有 PA 失败处理和 DAC 互斥用例。新增原 WAV SHA256 核对、Flash 中 32,000 个采样点一致性、实际 ARM 执行扫频时的淡化/完整循环/短写/停止/错误退出验证。

WAV 试听文件在 `outdir/ringtone_sweep_preview/`:

```text
1_zanghuayin.wav
2_xiaoyaoyou.wav
3_wangningmei.wav
4_liangzhihudie.wav
5_sweep_100hz_8khz.wav
```

其中音符 PCM 来自实际固件 ARM 指令执行结果,按已验证的播放顺序拼接,并包含同音停顿和曲尾等待。可先在电脑试听曲调与速度;它们不经过开发板的模拟输出链路。

## 5. 烧录后检查

先执行 `app ringtone play 1`,应看到:

```text
ringtone: play 1/5 Zang Hua Yin (16 kHz square, K2 single-click = next)
ringtone: score51-v1 square amplitude=23170 volume=15 first_note=738 Hz tick=65 ms
```

音量字段以实际策略为准;功放应打印 `spk-v6`、`gain=21dB`、`AGC1=on`,并读回 `PA readback [0x05]=0x0e`。随后执行:

```text
app ringtone play 5
```

应打印:

```text
ringtone: play 5/5 Sweep 100Hz-8kHz (16 kHz WAV PCM, K2 single-click = next)
ringtone: sweep-v1 samples=32000 duration=2000 ms fade=5/10ms volume=15
```

确认每次扫频持续 2 秒,间隔后重复;K2 可从第 5 首切回第 1 首,`app ringtone stop` 可停止。编译与仿真通过后仍需实板确认降低 PA 增益后的持续播放音质。

---

以下为旧版本排查记录,当前功能与操作以第 1~5 节为准。


## 6. 实板无声问题定位与修复

首次烧录后执行:

```text
app ringtone start 1
```

日志中可以看到铃声任务和音频输出链路均已启动:

```text
ringtone: play 1/3 Liang Zhu (16 kHz sine, K2 single-click = next)
[aout][I][1078]: channel@0 type:1 fifo:0 sr:16 opened
[os][I][543]: stream_type : 4
[os][I][550]: output_sr : 16000
[os][I][808]: volume 15
[aw87390_audio][I][146]: aw87390_enable
audio external PA power on
```

因此问题不在串口指令、音频轨道创建、DAC 启停或功放上电,而是最终送入 DAC 的 PCM 波形频率不正确。

原实现使用 32 位相位累加器:

```c
uint32_t phase = 0;
uint32_t phase_step = ((uint32_t)frequency << 16) /
RINGTONE_SAMPLE_RATE_HZ;

sample = ringtone_sine((uint16_t)(phase >> 16));
phase += phase_step;
```

相位步长已经把频率换算为 16 位相位刻度,采样时再次右移 16 位,等于把波形频率再次缩小 65536 倍。结果不是正常的 415 Hz 等音频音高,而是接近直流或极低频信号,所以扬声器基本没有可听声音。

修复方式是直接使用 16 位相位累加器:

```c
uint16_t phase = 0;
uint16_t phase_step = ((uint32_t)frequency << 16) /
RINGTONE_SAMPLE_RATE_HZ;

sample = ringtone_sine(phase);
phase += phase_step;
```

修复后做了数值回归,首音 `G#4` 对应的 16 kHz PCM 在 1 秒内约有 829 次过零,折算约 `414.5 Hz`,与目标 `415 Hz` 一致;采样范围约为 `-32767..32766`。

修复后的固件已重新编译并打包到:

```text
application/bt_watch/outdir/ats3089p_dev_watch/_firmware/ats3089p_dev_watch_261008.fw
application/bt_watch/outdir/ats3089p_dev_watch/_firmware/ats3089p_dev_watch_261008_debug.fw
```

## 7. 注意事项

1. 当前实现的是便于识别的铃声主旋律选段,不是完整歌曲。
2. 实际扬声器音量、音色和破音情况需要在目标板上烧录后试听确认。
3. `app ringtone` 使用的是原有控制台串口 shell,不是 GPIO20/21 上的 UART1 测试口。
4. K2 在铃声停止时只切换选择,不会自动启动播放。

## 8. 2026-10-09:铃声及录音回放音量排查

### 已确认的信息

- `log_26_9_29.txt` 中 10:58 的铃声先按默认音量 8 初始化,随后明确设置为音量 15、DAC 0 dB;初始化时的 -7.125 dB 不是整个播放过程的音量。
- 11:09 的 `app pcm_play /NAND:/rec.pcm 16` 也已是 15/15。用户确认是在开发板扬声器回放时声音小。
- 直接执行原 ELF 的 ARM 合成函数,稳定段峰值接近 32767、RMS 约 23150,频率正确。三首曲目的频率范围分别是 370~831、277~659、247~554 Hz。因此保留原音高,不用升八度或削波改变旋律。
- 用户提供的原理图中,PA-1 XA7191D 标注 DNP,由 GPIO53 控制;PA-2 AW87390 接 I2C1(GPIO51 SCL、GPIO52 SDA),地址 0x58。GPIO53 不是 AW87390 的复位或电源脚。两套功放共用 VOP/VON 输出,板级配置应选择实际安装的一套。
- 原板级配置同时启用了这两套控制。原 AW87390 驱动又使用可复用的栈缓冲异步写 I²C,仅固定等待 1 ms,不检查传输完成结果;当前板未开启 `CONFIG_I2C_ASYNC_MSG_INTERNAL_BUFFER`。因此旧日志中的 successfully / enable 不能证明功放寄存器实际写入成功。

上述内容确认了软件配置和传输缺陷。旧日志没有功放寄存器读回数据,仍需实板确认这些修正对音量的效果,不能把编译或仿真通过等同于响度问题已验证解决。

### 修改内容

1. 根据原理图选择 AW87390,关闭 GPIO53 的备用 XA7191D 控制;修正 CMake,使 AW87390 驱动独立于 GPIO 功放开关参与编译;增加编译检查,防止同时启用两套功放驱动。
2. AW87390 每次开始播放都同步写入完整配置,检查返回值,并读回使能、增益寄存器。初始化阶段只检查总线设备是否存在,播放时的总线错误可重试。
3. 音频输出框架检查 AW87390 配置结果,避免功放配置失败后仍报告播放链路创建成功。
4. 保留 AW87390 原有 18 dB 增益及升压、功率限幅参数,不提高扬声器功率上限。
5. 铃声保留当前满量程设置和原音高,补充波形版本、幅度、音量、首音频率日志;修正短写丢样本及等待期间停止/切歌响应问题。
6. `write_aw87390` 调试命令改为同步读写。不带参数时只读寄存器,不写配置。

### 烧录后检查

```text
app ringtone play 1
app ringtone play 2
app ringtone play 3
app ringtone stop
app pcm_play /NAND:/rec.pcm 16
```

梁祝播放时应看到:

```text
drv_aw87390_regs_init successfully
aw87390_enable: sysctrl=0x07 gain=0x0c (default 0x0c)
ringtone: sine-v2 amplitude=32767 volume=15 first_note=415 Hz
```

不再用 `audio external PA power on` 判断 AW87390 是否正常;该旧提示来自 GPIO53 的备用功放路径。
如果出现 `PA write ... failed`、`PA readback failed` 或 `AW87390 configuration failed`,请保留完整日志,核对实际功放、I²C 连接及 SPK_PWR 供电。
可在播放中执行 `write_aw87390`,只读回 0x00~0x0B 寄存器。

软件验证:

```text
ninja -C application/bt_watch/outdir/ats3089p_dev_watch -j4
python application/bt_watch/tests/ringtone/run_tests.py
```

测试直接执行最终 ELF 的 ARM 代码,覆盖 49 种音符的幅度、频率、时长、休止符和包络,以及短写、停止/切歌、输出错误、功放配置顺序、I²C 失败、重复播放和配置丢失后的恢复。I²C 使用模拟接口,不能代替实板试听。

本次固件为 `ats3089p_dev_watch_261009_debug.fw`,另有完整包 `ats3089p_dev_watch_261009.fw`。未提交 Git。

## 9. 2026-10-09:按官方资料修正 AW87390 扬声器初始化(spk-v3)

### 新日志与配置问题

11:35~11:43 的新日志已读回 `sysctrl=0x07, gain=0x0c`,铃声仍为满量程 PCM、音量 15、DAC 0 dB。用户反馈扬声器声音仍小,因此上一版的同步 I²C 修正并未解决实板响度问题。仅检查使能和增益不能证明升压、AGC 等整套配置正确。

对照艾为官方《AW87390 数据手册 V1.3》第 37~38 页,原配置 `0x0A=0x3A` 和 `0x64=0x48` 改写了保留位;它们也与官方《AW87390 Software Design Guide V1.1》(2025-02)扬声器配置不一致。原驱动还缺少软件复位、参考启动序列中的预充电步骤及启动等待。这些是本次修正的依据,但目前没有测量证明它们就是声音小的唯一原因。

### 本次修改

- 播放前先读芯片 ID,必须为 `0x76`;不匹配时停止配置并打印实际值。
- 执行软件复位 `0x00=0xAA` 并等待至少 5 ms;按官方扬声器 ADP 配置执行预充电、2 ms 等待和完整寄存器序列;完成配置后等待 50 ms。
- 对齐官方 AGC/ADP 相关配置,包含 `0x0A=0x4B`、`0x63=0x09`、`0x64=0x24`。`0xFE` 仅作为软件延时标记,不发送到 I²C。
- 保留板级参数:增益 18 dB、升压上限 6.5 V、AGC3/AGC2 分别为 0.5/0.8 W(这两个功率值以 **8 Ω** 为条件)。照片未提供喇叭阻抗及功率标识,不能把这些数值当作该喇叭的实际输出功率。
- 启动时读回并检查 `0x01/02/03/05/06/08/0A/63/64`;失败时尝试关断功放,返回错误。正常停止按官方关断配置写 `0x01=0x00`。

官方资料:[AW87390 数据手册](https://doc.awinic.com/doc/20230609wm/f360bfdf-21f7-4b5b-9042-d14632350c28.pdf)、[软件设计指南及产品资料入口](https://www.awinic.com/cn/searchAll?keyword=AW87390)。本次采用官方扬声器工作序列,并保留上面列出的板级电压、功率参数,没有直接套用参考方案中的更高输出功率。

### 实板验证

烧录新打包的 `ats3089p_dev_watch_261009_debug.fw`,先执行:

```text
app ringtone play 1
write_aw87390
audio dump_reg dac
```

新固件应打印 `aw87390 spk-v3: id=0x76 ADP speaker, gain=18dB, boost=6.5V`,并逐条输出关键寄存器读回值。随后执行 `app ringtone stop`,用 `app pcm_play /NAND:/rec.pcm 16` 对比同一录音文件回放,再重复启停和切歌。

如仍小声,可在播放期间做一次增益对比(现有命令参数为十进制):

```text
write_aw87390 5 18
write_aw87390 5 12
```

第一条设置寄存器 `0x05=0x12`(27 dB),第二条恢复 `0x0C`(18 dB);不要紧接着输入两条,先试听变化。这是当前播放期间的临时设置,下次播放会恢复默认值。若明显变大,继续评估增益;若几乎不变,则需要结合喇叭规格及 PA 输入、VDD/PVDD、扬声器两端的实测幅度判断限幅或模拟链路问题。不能仅凭寄存器配置正确就认定响度正常。

软件测试覆盖官方序列、复位/预充电/输出等待、芯片 ID、关键寄存器不匹配、每一笔 I²C 事务失败后的处理、完整关断,以及重复播放/掉电后恢复。测试总线为模拟接口,响度改善仍待用户烧录试听确认。打包前已将上一版同日期固件备份到 `_firmware/backup_before_spk_v3_20261009_115704/`;未提交 Git。

## 10. 2026-10-09 12:05:spk-v3 实板读回已确认,响度问题仍未解决

用户反馈本版仍然很小、基本没有变化。新增日志确认:

| 检查项 | 实际读回 | 结论 |
| --- | --- | --- |
| AW87390 身份与模式 | ID `0x76`,SYSCTRL `0x07`,MODECTRL `0x1C` | 功放已使能,ADP 扬声器模式已写入 |
| 功放增益/限幅 | `0x05=0x0C`,`0x06=0x04`,`0x08=0x02` | 18 dB,AGC3/AGC2 配置为 0.5/0.8 W(8 Ω 条件) |
| 官方 AGC/ADP 配置 | `0x0A=0x4B`,`0x63=0x09`,`0x64=0x24` | 本次修改已在实板生效 |
| DAC 数字控制 | `DAC_DIGCTL=0x80020135` | 16 kHz、单声道、FIFO0 混入及数字 DAC 已开启 |
| DAC FIFO | `DAC_FIFOCTL=0x83008093` | FIFO0 为 DMA 输入、16 位传输模式 |
| DAC 音量 | `VOL_LCH/RCH=0x000308BE` | 音量码 `0xBE` 对应 0 dB,音量调节完成 |
| DAC 模拟控制 | `DAC_ANALOG0=0x00001933` | DAC、偏置及模拟输出级开启,PAVOL=4、DARSET=1、差分模式 |

`write_aw87390` 在播放约 8 秒后仍读到正确配置;播放中的 DAC dump 也没有显示数字静音配置。`FIFO0_DAT=0` 是一次数据端口读取,不能用来判断整段 PCM 的幅度;dump 中固定打印的 DMA7 也不一定是此次 DAC 使用的 DMA 通道,不能凭它的 START=0 断言播放 DMA 停止。

结论限于“寄存器配置已生效”,不能推导出实际 DAC 电压、功放输出功率或喇叭响度正常。上面的配置修正没有改善用户听感,下一步应取得增益对比/模拟幅度证据,再决定实际需要调整的环节。

### 当前固件即可执行的对比

1. 按第 9 节,在同一次铃声播放期间比较 `write_aw87390 5 18`(27 dB)与 `write_aw87390 5 12`(18 dB),保留读回及听感。9 dB 是小信号增益变化;若已进入 AGC 限幅,实际响度可能不随之增大。
2. 如仍无法定位,可在录音和其他播放均停止后使用底层测试音,跳过应用音轨与文件读取。先 `app ringtone stop`,再输入以下第一条,试听后单独输入停止命令:

```text
audio play start sr=48 chl_width=16 mono_en=1 reload_en=1
audio play stop
```

这使用 SDK 现有测试波形及 DMA 循环播放,不是新增加的单频校准音。若底层测试音也很小,应测量 AW87390 的 VDD(SPK_PWR)、PVDD 及差分输入/输出,并补充喇叭额定阻抗和功率。使用台式接地示波器时,地夹接板 GND,差分信号用差分探头或双通道相减测量,不能将地夹直接接 VON。

## 11. 2026-10-09:实板增益对比有效,默认改为 27 dB(spk-v4)

用户执行 `write_aw87390 5 18` 后确认声音变大。12:14:57 的日志显示写入、读回均为 `0x05=0x12`,其他主要配置与原先相同。这里命令参数 `18` 是十进制寄存器值,等于十六进制 `0x12`,对应扬声器增益 **27 dB**;旧默认寄存器值 `0x0C` 对应 **18 dB**。因此已有实板证据表明提高功放增益可以改善当前音量,但不能把 9 dB 的增益变化直接当作实际声压变化。

原调试命令只改变当前播放期间的寄存器;重新开始播放会重新加载默认值,恢复旧的 18 dB。这次把 `AW87390_DEFAULT_GAIN` 改为 `0x12`,使每次播放、切歌和重新上电后的播放都自动使用 27 dB,并通过原有读回检查确认。修改作用于经过 AW87390 的扬声器播放,包括铃声与录音文件回放,不改变 MIC 采集增益。

6.5 V 升压上限以及 AGC3/AGC2 的 `0x04/0x02` 功率限制继续保留。关键代码修改已加 `//zk+-` 标识,仿真用例同步检查每次播放及模拟掉电恢复后均配置 `0x05=0x12`。

烧录 `ats3089p_dev_watch_261009_debug.fw` 后执行:

```text
app ringtone play 1
write_aw87390
```

应看到:

```text
PA readback [0x05]=0x12
aw87390 spk-v4: id=0x76 ADP speaker, gain=27dB (reg=0x12), boost=6.5V
r_str_data5=====:12
```

随后停止铃声,再用同一个录音文件回放,确认音量及音质:

```text
app ringtone stop
app pcm_play /NAND:/rec.pcm 16
```

本次验证包括固件编译、现有 ARM 仿真回归、重复播放/掉电后增益恢复及最终包内版本标识检查;新固件的实际听感仍需烧录复核。旧 spk-v3 同日期固件已备份到 `_firmware/backup_before_spk_v4_20261009_121628/`。未提交 Git。

## 12. 2026-10-09:播放一段时间后破音(spk-v5)

用户反馈 27 dB 虽然响度增大,但持续播放后破音。当前日志仍打印 spk-v3,不能据此认为 spk-v4 已烧录。日志提供了以下证据:

- 12:14:57 手动写入 `0x05=0x12`,即 27 dB;同一时间附近出现电池瞬时采样 3512 mV、`VLIM:1`,后续还有 `ILIM:1` 和 DC5V 插拔事件。供电状态需关注,但这些不是 AW87390 的 SPK_PWR 实测,不能直接认定供电是破音根因。
- 12:15:55 执行 `write_aw87390 2 10`,将模式寄存器改成 `0x0A`,清除了扬声器使能位并改动保留位。此命令不是调音量,不能用其后的声音评价正常扬声器模式;重新开始播放会恢复配置。
- 12:17:39 在铃声未停止时执行 `app pcm_play /NAND:/rec.pcm 16`,出现两个 DAC session 使用 FIFO0;第二路启动会重置 PA,结束后又关闭 PA。这是已确认的软件冲突,会破坏正在进行的播放。

本次修正:

1. 默认增益由 27 dB 回退到 **24 dB**(`0x05=0x10`),每次播放、切歌均重新配置并读回检查。
2. `0x0A` 从 `0x4B` 改为 `0x4A`,按芯片手册清除 `PD_AGC1`,开启快速防削顶。此项是针对破音对官方示例的调整;6.5 V 升压上限及 AGC3/AGC2 功率限制保持原值。
3. Leopard 平台只允许一个 DAC session,拒绝重复打开时不再重置正在使用的 PA。PA 配置放到资源锁和 session 检查之后,DAC 打开失败则关闭本次开启的 PA。
4. PCM 回放先请求铃声退出,等待流清理、DMA 停止和轨道销毁后才开始;超时则返回错误。回放期间铃声启动返回忙,K2 只修改下一次选曲。用请求代数检查防止旧的铃声请求在 PCM 结束后意外重启。
5. DAC FIFO 编号使用实际输出 FIFO,而非 session 数组下标,避免其他音频接口占用 session 0 后选错 FIFO。

关键修改已加 `//zk+`、`//zk-` 或 `//zk+-`。编译及 ARM ELF 仿真已通过:49 个音符波形、部分写入/停止/切歌、PA 配置和全部 I²C 失败注入、重复 DAC 打开无副作用、打开失败清理、PCM 占用与超时恢复、过期铃声请求取消。仿真不验证功放实际输出或扬声器听感。

烧录 `ats3089p_dev_watch_261009_debug.fw` 后先单独播放一分钟以上:

```text
app ringtone play 1
write_aw87390
```

应看到:

```text
PA readback [0x05]=0x10
PA readback [0x0a]=0x4a
aw87390 spk-v5: id=0x76 ADP speaker, gain=24dB (reg=0x10), boost=6.5V, AGC1=on
```

再用 K2 切歌,并在铃声播放时执行 `app pcm_play /NAND:/rec.pcm 16` 验证自动交接:铃声应先关闭,然后才打开录音回放,不能出现两个有效 DAC session。回放结束后可重新执行 `app ringtone play 1`。

先使用新版默认配置试听,不叠加第 9~11 节的历史寄存器写入。如果单独播放仍破音,需要记录出现时间,并核对喇叭额定阻抗/功率、SPK_PWR 与 PVDD 实测供电以及音频差分波形;照片无法确定喇叭额定参数。本次 24 dB 是待实板验证的回退配置,不能仅凭寄存器读回就判定音质问题已解决。

寄存器依据:[AW87390 V1.3 芯片手册](https://doc.awinic.com/doc/20230609wm/f360bfdf-21f7-4b5b-9042-d14632350c28.pdf)。旧 spk-v4 同日期固件已备份到 `_firmware/backup_before_spk_v5_20261009_122553/`,未提交 Git。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询