# SD2506_RTC 测试指南

> 对应驱动：`Drivers/BSP/SD2506/sd2506.c`
> 测试代码：`test/sd2506_test_task.c` + `test/sd2506_test.h`

## 1. 概述

本测试套件对 `sd2506.c` 做**黑盒功能自测**，只调用公共 API，不触碰驱动内部函数。
每个用例通过 `SD2506_TEST_CHECK` 记录 pass/fail，最终由 `SD2506_TEST_REPORT` 汇总。

历史背景：本驱动曾出现“时间写不进”问题，根因是寄存器宏写成 `0x0FH`（KEIL/ARMCC
不识别 `H` 整数后缀，被编译为 0），导致 `SD2506_REG_CTR1` 实际等于 0（秒寄存器），
`sd2506_write_enable()` 把 WRTC 写错地址、写保护永不解除。修正为 `0x0FU` 后恢复。
详见 `docs/SD2506_Trap_Records.md`。

## 2. 启用与编译

`test/test_config.h` 中一次只能启用一个 `TEST_SUITE_*`（互斥）：

```c
//#define TEST_SUITE_CH395F
//#define TEST_SUITE_STORAGE
//#define TEST_SUITE_GD5F
#define TEST_SUITE_RTC          /* 启用 RTC 测试套件 */
```

`test/sd2506_test.h` 中控制各阶段（默认全开）：

```c
#define ENABLE_RTC_BASIC_TESTS  /* Phase 1: 基本读写 / 走时 */
#define ENABLE_RTC_API_TESTS    /* Phase 2: 全功能 API 覆盖 */
```

编译（要求 0 错误 0 警告）：

```bat
MDK-ARM\build.bat
```

烧录后在串口（USART1, 115200bps）观察 `[RTC_TEST]` 日志。

## 3. 测试用例

| 编号 | 目标 | 覆盖函数 | 判定 |
|------|------|----------|------|
| TC-RTC-001 | 初始化并读取当前时间 | `sd2506_init` / `sd2506_get_time` | init 返回 0；get 返回 0 |
| TC-RTC-002 | 写固定时间立即回读一致 | `sd2506_set_time` / `sd2506_get_time` | set==readback（允许 +1s 进位） |
| TC-RTC-003 | 走时验证 | `sd2506_get_time` | 延时 3s 后秒数前进 2~5s |
| TC-RTC-010 | BCD↔DEC 互转 | `sd2506_dec_to_bcd` / `sd2506_bcd_to_dec` | 10 组样本双向一致 |
| TC-RTC-011 | 内部温度读取 | `sd2506_get_temperature` | 返回 0；值 ∈ [-40, 85] |
| TC-RTC-012 | 电池电压（mV） | `sd2506_get_battery_voltage` | 返回 0；值 ∈ (2000, 5000) |
| TC-RTC-013 | 芯片 8 字节 ID | `sd2506_get_id` | 返回 0；读出 8 字节 |
| TC-RTC-014 | 用户 SRAM 回环 | `sd2506_write_sram` / `sd2506_read_sram` | 写入 8 字节后回读一致 |
| TC-RTC-015 | 报警设置 + 清除 | `sd2506_set_alarm` / `sd2506_clear_alarm` | 两者均返回 0 |

## 4. 覆盖矩阵

| 公共 API | 是否覆盖 | 用例 |
|----------|----------|------|
| `sd2506_init` | ✅ | TC-RTC-001 |
| `sd2506_get_time` | ✅ | TC-RTC-001/002/003 |
| `sd2506_set_time` | ✅ | TC-RTC-002 |
| `sd2506_get_temperature` | ✅ | TC-RTC-011 |
| `sd2506_get_battery_voltage` | ✅ | TC-RTC-012 |
| `sd2506_get_id` | ✅ | TC-RTC-013 |
| `sd2506_read_sram` | ✅ | TC-RTC-014 |
| `sd2506_write_sram` | ✅ | TC-RTC-014 |
| `sd2506_set_alarm` | ✅ | TC-RTC-015 |
| `sd2506_clear_alarm` | ✅ | TC-RTC-015 |
| `sd2506_read_ctr1` | △（诊断） | run() 内打印 CTR1 |
| `sd2506_bcd_to_dec` / `sd2506_dec_to_bcd` | ✅ | TC-RTC-010 |

> 未覆盖（需专项验证，不在本自测范围）：倒计时寄存器、温度报警历史、
> 跨重启持久化（原 Phase 3 已废弃，依赖实际掉电/上电，建议手动或另写用例）。

## 5. 运行与判定

- `sd2506_test_run()` 由测试调度器调用，先 init 并记录原始时间，最后用
  `sd2506_set_time` 把板子时间**恢复**为测试前的值（不污染真实时钟）。
- 输出形如：
  ```
  [RTC_TEST] === SD2506 Phase 1: basic read/write (public API) ===
  [RTC_TEST] [PASS] sd2506_init() ret=0 (expect 0)
  ...
  [RTC_TEST] === Phase 1 basic: 6/6 PASSED (failed=0) ===
  [RTC_TEST] === SD2506 Phase 2: full API coverage ===
  ...
  [RTC_TEST] === Phase 2 API: 9/9 PASSED (failed=0) ===
  ```
- 通过标准：所有 Phase 的 `failed=0`，且总量 `X/Y PASSED` 中 Y 与 PASS 数相等。

## 6. 失败排查

- **TC-RTC-002 FAIL（set≠readback）**：优先查 `sd2506.h` 中各寄存器宏是否被写成
  `0xNNH`（H 后缀陷阱）。例如 `SD2506_REG_CTR1` 必须是 `0x0FU` 而非 `0x0FH`。
- **init/get/set 返回 -2（I2C 错误）**：查 I2C1 接线（PB6-SCL / PB7-SDA）、
  上拉电阻、芯片供电与器件地址 `0x32`。
- **温度/电压越界**：多为芯片未上电或 I2C 读到全 0xFF，按 I2C 链路排查。

## 7. 已知限制

- TC-RTC-015 会让 `sd2506_set_alarm` 置 `CTR2.INTAE=1`（报警中断允许）。
  测试固件未挂 INT 中断处理，且 INT 引脚在板上未连接，对运行无影响；
  若要完全复位，可手动再调用一次 `set_alarm(..., mask=0)`。
- SRAM 回环会在 `addr=0` 写入测试数据（8 字节），属用户 SRAM 区域，不影响时间/控制寄存器。
