# 按帧类型自动曝光（IRQ5 / 0xA00C0008、0xA00C000C）待确认问题

> 目的：黑白荧光模式下按「帧类型」区分白光帧 / 荧光帧，分别下发曝光增益。落地前有一批
> 硬件与协议问题需要确认，**§1 请 FPGA 同事解答**，§2 属产品/软件侧（FPGA 可忽略）。
>
> 记录时间：2026-10-15

---

## 0. 需求原文

```
0xa00c000c
0/2

收到pcie中断号5，下发0xa00c0008为0，清理中断；并且读取0xa00c000c的数值，为0说明当前帧为白光帧，
为2说明当前帧为荧光帧，进行自动曝光数据采集，进行一次自动曝光参数计算；
白光帧自动曝光按照正常下发曝光与增益参数，荧光帧下发曝光参数15000，增益7000。
```

理解：PCIe 中断号 5 到达 → 写 `0xa00c0008` = 0 清中断 → 读 `0xa00c000c`（0=白光帧，
2=荧光帧）→ 做一次自动曝光采集与计算 → 白光帧按正常 AE 下发曝光/增益，荧光帧固定下发
曝光 15000、增益 7000。

**地址约定**（本仓库既有约定，见 `docs/开发者维护-FPGA寄存器下发.md` §2）：
XDMA user BAR 偏移 = FPGA AXI 地址去掉 `0xA0` 前缀。故 `0xa00c0008 → 0x000c0008`、
`0xa00c000c → 0x000c000c`；右目 = 左目地址 + `0x1000000`。

---

## 1. 需要 FPGA 同事确认

### 1.1 中断号 5

1. 中断号 5 是否就是 XDMA 的 `user_irq[5]`、对应设备节点 `/dev/xdma0_events_5`？驱动侧还需要
   额外使能吗（FPGA 内是否有中断使能寄存器要先打开）？
2. 触发时机与频率：是**每帧**触发一次吗？白光帧、荧光帧是否**各触发一次**（即交替产生两个
   中断）？帧率是多少？左右目是各自独立触发还是共用这一个中断号？
3. FPGA 侧会不会出现「中断产生快于主机读取」而被合并的情况？现有读取逻辑是 `poll()` 后
   读 4 字节，返回的是 XDMA 累计事件计数（`src/base/xdma.cpp:138` `wait_xdma_poll`），并非
   单次中断编号。若会合并，请说明可靠的计数/去重方式。
4. 该中断产生是否需要 x86 先做某些配置（例如某种 trigger / 交替帧模式已使能）？请给出产生
   IRQ5 的前置条件。

### 1.2 清中断寄存器 `0xA00C0008`

1. 确认「写 0 即清中断」的语义，以及有无其它副作用；是否需要回读确认已清、或写后需要延时？
2. 该地址目前在代码里被命名为**按键（KEY）事件地址**：`src/base/xdma.h:69`
   `#define KEY_EVENT_ADDR 0x000c0008`（该宏从未被使用，按键相关函数均为空桩）。
   而寄存器手册第 4 节把 `0xA00C_0000` / `0xA00C_0004` 写成「按键信息识别位 / 统计位」，
   但代码 `src/middle/function/light.cpp`（`:665`、`:711`、`:766`、`:821`）又把
   `0x00c0000` / `0x00c0004` 当**光源通路选择**在写。
   → 请给出 `0xA00C0000` 这一段**最新**的寄存器定义（尤其 `+0x8`、`+0xC` 两个），并说明
   「按键」相关定义是否已废弃或搬迁。
3. 右目是否有镜像地址 `0x10c0008`？清中断需要左右目都写吗？

### 1.3 帧类型寄存器 `0xA00C000C`（重点）

1. 确认取值：**0 = 白光帧，2 = 荧光帧**。取值 1、3 或其它值是否可能出现？含义是什么？读到
   未知值时应如何处理？
2. 读的是「当前正在采集的这一帧」还是「刚完成的上一帧」？从收到中断到主机实际读取之间会有
   一段软件延时（含清中断、调度），这段时间内帧类型会不会已经翻转为下一帧？有无**配套的帧
   序号寄存器**可一起读，用来和中断做一致性校验？
3. 右目是否有镜像 `0x10c000c`？左右目帧类型是否保证始终一致？
4. **地址冲突**：同一地址 `0x000c000c` 现在被用作 **AU15 版本号回读**——代码在
   `src/middle/function/misc.cpp:49`（`get_au15_version`：先写 `0x10e0030` 触发，再读
   `0x000c000c`）和 `src/middle/function/sensor.cpp:174`（sensor 回读）都读它。
   → 这两个用途真的共用同一寄存器吗？若共用，请说明如何区分；若 AU15 回读应读**另一个地址**，
   请一并纠正正确地址。（注：当前这两处走 `common_read_right`，该函数在
   `src/base/xdma.cpp:400` 为空桩恒返回 0，所以运行时暂未觉察问题。）

### 1.4 帧数据与中断的绑定

1. 收到 IRQ5 后，如何取到「这一帧」的 YUV 数据？是否就是现有 AE 使用的那条 DDR 路径？
2. 前端从 FPGA 侧有帧计数寄存器（`docs/A2-研发样机寄存器空间.md` §7.2，
   `0xA00E0000` 的 `Bayer_frm_cnt` / `Yuv_frm_cnt`）。这两个计数器是否与本次中断**一一对应**？
   是否有寄存器能直接读到「当前写入的 buffer 地址 / 序号」，用来把中断绑定到正确的帧缓冲？
   请给出推荐的「中断 → 取对应帧」流程。

### 1.5 时序与吞吐

1. 从收到 IRQ5 到写清中断之间，FPGA 侧对时序有无要求（例如必须在 X us 内清）？超时未清会怎样
   （中断丢失、反复触发、还是状态卡死）？
2. 白光/荧光帧交替的周期是多少（us / ms）？主机在两次中断之间需要完成「清中断 + 读帧类型 +
   AE 计算 + 串口下发曝光增益（CMD 0x48，毫秒级往返）」这一串动作，请确认留给主机的处理窗口
   是否足够、以及跟不上时 FPGA 侧的行为。

---

## 2. 需要产品/软件侧确认（FPGA 可忽略）

1. **增益 7000 的单位与落点（最关键）**。现有链路都对不上：手柄 sensor 增益上限为
   **1550**（0.01x，即 15.5x，博盛文档；见 `src/middle/isp/exposure.cpp:18`
   `BW_FLUO_GAIN_MAX`），而正常 AE 通道 `handler_set_exposure_and_gain()`
   （CMD 0x48，`src/middle/function/handler_serial.cpp:859`）又把增益钳位在 **100~4000**——
   7000 两条路都进不去。可能的落点：荧光 sensor 的 IIC 增益寄存器
   （`config_fluo_sensor_gain()`，`src/middle/function/sensor.cpp:366`，`write_16bit_reg`
   为 16 位可写 0~65535；但该链路现有量纲是 UI 1~10 → ×10 = 10~100）、ISP 荧光通道增益
   （`0x00020010`，现为 `2048 + (n-1)*512` → 2048~6656），或新协议新地址。
   → 请明确 7000 的**单位、目标寄存器、下发链路**（手柄串口 CMD 0x33？荧光 sensor IIC？
   还是 ISP 荧光通道增益寄存器？）。
2. **曝光 15000** 的单位是 us 吗？走哪条链路——手柄串口 CMD 0x32（原值下发、不钳位，
   现有 `LIGHT_INIT_EXPOSURE_US` 也是 15000，`src/middle/function/light.cpp:516`），还是荧光
   sensor 的 IIC 曝光寄存器？是否**替换**现有黑白荧光的 16383us
   （`BW_FLUO_EXPOSURE`，`src/middle/isp/exposure.cpp:19`）？
3. **作用范围**：这套按帧分叉逻辑是只对「黑白荧光」（`LIGHT_MODE_BW_FLUO`）模式生效，还是所有
   模式都按 `0xa00c000c` 分帧处理？是**替换** `config_ae` 现有的 BW_FLUO 分支
   （`src/middle/isp/exposure.cpp:43-59`）还是新增一条并列链路？
4. **「白光帧按正常下发」**是否等同于现有 CMD 0x48 那条路（含曝光 ×5、增益 ×3 映射与
   `100~15000` / `100~4000` 钳位）？还是按 CMD 0x32/0x33 原值下发 AE 内部值？
5. **AE 在哪些帧上算**：荧光帧既然是固定值，还要不要跑 AE 计算？需求是「读取帧类型 → 进行
   采集与计算 → 按帧分叉下发」，若荧光帧也算，算出的结果是否丢弃？
6. **生效门控**：是否仍要求「自动曝光开关已打开」且手柄已插入（`handle_plug_flag()==1`）？
   自动曝光关闭时，荧光帧的固定 15000 / 7000 还要不要下发？

---

## 3. 现状与依据（附录）

| 事项 | 现状 | 位置 |
|---|---|---|
| 地址约定 | BAR 偏移 = AXI 地址去 `0xA0` 前缀 | `docs/开发者维护-FPGA寄存器下发.md` §2 |
| 清中断先例 | 视频中断（号 1）写 `0xa0091000` = 0 清中断 | `docs/视频存储地址.md:23`、`src/base/xdma.cpp:362` |
| 清中断先例 | raw VDMA（号 4）写基址 `+0x34` = `0xffffffff` | `src/base/xdma.cpp:320` 附近 |
| IRQ5 节点 | `/dev/xdma0_events_5` 仅出现在被注释的右目 KEY 映射 | `src/base/xdma.cpp:38`、`:251` |
| 节点打开处 | 需在此新增打开 events_5 | `src/base/xdma.cpp:205` `xdma_init_left()` |
| `0xA00C0008` | 已定义为 `KEY_EVENT_ADDR`，从未使用 | `src/base/xdma.h:69` |
| `0xA00C000C` | 现用作 AU15 版本号回读 | `src/middle/function/misc.cpp:49`、`src/middle/function/sensor.cpp:174` |
| `0xA00C0000/4` | 代码当光源通路选择写（手册写的是按键位） | `src/middle/function/light.cpp:665,711,766,821` |
| 黑白荧光现状 | 整模式固定：增益 1550（CMD 0x33）、曝光 16383us（CMD 0x32），不分帧 | `src/middle/isp/exposure.cpp:18-19,43-59` |
| 正常 AE 通道 | CMD 0x48，曝光 ×5 钳位 100~15000、增益 ×3 钳位 100~4000 | `src/middle/function/handler_serial.cpp:859` |
| AE 计算入口 | `getExposureConfig(cv::Mat yuv, int &time, int &gain)`，一次调用 = 一次迭代 | `src/middle/algorithm/algorithm_AE.cpp:637` |
| 荧光 sensor 增益 | IIC `write_16bit_reg`，16 位；现量纲 UI 1~10 → ×10 | `src/middle/function/sensor.cpp:366` |
| 帧计数寄存器 | `0xA00E0000` `Bayer_frm_cnt` / `Yuv_frm_cnt` | `docs/A2-研发样机寄存器空间.md` §7.2 |
