From 5d386cedfbc672ae872831efb4bdd5725bea17d7 Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Mon, 21 Sep 2026 03:01:49 +0800 Subject: [PATCH] =?UTF-8?q?GD5F=20=E8=A1=A5=20DMA=20=E5=AE=88=E5=8D=AB?= =?UTF-8?q?=E8=B4=9F=E8=B7=AF=E5=BE=84=E7=94=A8=E4=BE=8B=20TC-704/705?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E5=87=BA=E9=98=88=E5=80=BC=E5=AE=8F=E5=B9=B6?= =?UTF-8?q?=E5=AF=B9=E9=BD=90=E6=B5=8B=E8=AF=95=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c | 13 ++-- Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h | 10 +++ docs/测试说明/GD5F2GQ5UE_Test_Guide.md | 62 ++++++++++++++--- test/gd5f_test_task.c | 93 +++++++++++++++++++++----- 4 files changed, 142 insertions(+), 36 deletions(-) diff --git a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c index afe3e4fb..0d4b92c6 100644 --- a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c +++ b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c @@ -45,13 +45,12 @@ extern SPI_HandleTypeDef hspi1; /* DMA 完成标志(ch395f.c 中的 HAL_SPI_TxRxCpltCallback 会设置此标志) */ volatile uint8_t g_spi1_dma_done; -/* DMA 阈值(字节数超过此值使用 DMA 传输) */ -/* DMA 阈值 1024B(2026-09-20):阈值以下走 CPU 轮询。存在把**栈上小缓冲** - * 直接传进本驱动做收发的大小(dhara meta 读 132B、dhara_nand_is_free 64B), - * 任务栈随 FreeRTOS 堆驻留 CCM(0x10000000),而 DMA1/DMA2 物理上不可达 - * CCM——此类传输必须留在轮询域,否则静默失败(CCM 首次扩容实验实证的根因)。 - * 页级大块传输(2048)仍走 DMA,源/目的全部为文件作用域静态缓冲。 */ -#define GD5F_DMA_THRESHOLD 1024 +/* DMA 阈值(字节数超过此值使用 DMA 传输):取值定义在头文件,理由如下—— + * 阈值以下走 CPU 轮询。存在把**栈上小缓冲**直接传进本驱动做收发的大小 + * (dhara meta 读 132B、dhara_nand_is_free 64B),任务栈随 FreeRTOS 堆驻留 + * CCM(0x10000000),而 DMA1/DMA2 物理上不可达 CCM——此类传输必须留在轮询域, + * 否则静默失败(CCM 首次扩容实验实证的根因)。页级大块传输(2048)仍走 DMA, + * 源/目的全部为文件作用域静态缓冲。 */ /* DMA 可达内存区间:必须与分散加载文件 RW_IRAM1(0x20000000,128KB, * SRAM1+SRAM2)一致。CCM(0x10000000,64KB)DMA1/DMA2 物理不可达, diff --git a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h index 7823a96c..d2e82b06 100644 --- a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h +++ b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h @@ -72,6 +72,16 @@ extern "C" { #define GD5F_TOTAL_BLOCKS 2048 #define GD5F_TOTAL_SIZE (GD5F_TOTAL_BLOCKS * GD5F_BLOCK_SIZE) +/* + * SPI DMA 传输阈值:超过该字节数走 DMA,否则走 CPU 轮询。 + * 取值约束:① 必须 >= 存储路径上可能出现在任务栈的最大缓冲(dhara meta 132B、 + * dhara_nand_is_free 64B)——任务栈随 FreeRTOS 堆驻留 CCM(0x10000000), + * 而 DMA1/DMA2 物理不可达 CCM,栈缓冲一旦进 DMA 即静默失败(2026-09-20 实证); + * ② 必须 < 页大小(2048),页级传输保留 DMA。 + * 公开此宏供测试用例对齐阈值上下界,避免测试取值与驱动漂移。 + */ +#define GD5F_DMA_THRESHOLD 1024 + /* 坏块表持久化:保留块池数量(从 NAND 顶部向下挑选出厂好块存储 BBT) */ #define GD5F_BBT_POOL_COUNT 4 diff --git a/docs/测试说明/GD5F2GQ5UE_Test_Guide.md b/docs/测试说明/GD5F2GQ5UE_Test_Guide.md index 562068c0..07a35868 100644 --- a/docs/测试说明/GD5F2GQ5UE_Test_Guide.md +++ b/docs/测试说明/GD5F2GQ5UE_Test_Guide.md @@ -28,7 +28,7 @@ | 总块数 | 2048 | `GD5F_TOTAL_BLOCKS` | | 总容量 | 256 MB | `GD5F_TOTAL_SIZE` | | 最小擦除单位 | 1 块(128 KB) | 不可按页/字节擦除 | -| DMA 阈值 | 32 B | `GD5F_DMA_THRESHOLD`,>32B 走 `HAL_SPI_*_DMA` | +| DMA 阈值 | 1024 B | `GD5F_DMA_THRESHOLD`,>1024B 走 `HAL_SPI_*_DMA`;非 SRAM 缓冲由运行时守卫回落轮询(见阶段 7) | ### 寄存器与状态位 @@ -422,9 +422,12 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10` --- -## 8. 阶段 7:DMA 边界(阈值 32 字节) +## 8. 阶段 7:DMA 边界与 DMA 可达性守卫(阈值 1024 字节) -> 驱动 `GD5F_DMA_THRESHOLD=32`:`size>32` 走 `HAL_SPI_*_DMA`,否则轮询。两路径结果必须一致。 +> 驱动 `GD5F_DMA_THRESHOLD=1024`:`size>1024` 走 `HAL_SPI_*_DMA`,否则轮询。两路径结果必须一致。 +> **前置约束**:DMA 源/目的缓冲必须落在 SRAM(`RW_IRAM1`,0x20000000~0x2001FFFF)。CCM(0x10000000) +> 为 DMA1/DMA2 物理不可达区,误用会静默不落地;驱动已加运行时守卫 `gd5f_dma_buf_ok()`, +> 越界缓冲自动回落轮询并打印 `[ERR][NAND] … not DMA-reachable … fallback poll`。 ### TC-GD5F-701: 阈值下界(轮询路径) @@ -433,9 +436,9 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10` | **ID** | TC-GD5F-701 | | **优先级** | P1 | | **类型** | 边界测试 | -| **标题** | size=32 走非 DMA 路径,读写正确 | +| **标题** | size=1024(= `GD5F_DMA_THRESHOLD`)走非 DMA 路径,读写正确 | | **前置条件** | 目标块已擦除 | -| **测试步骤** | 写/读 32 字节并比对 | +| **测试步骤** | 写/读 1024 字节并比对 | | **通过标准** | 数据一致 | | **覆盖原则** | `GD5F_DMA_THRESHOLD` 下界 | @@ -446,9 +449,9 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10` | **ID** | TC-GD5F-702 | | **优先级** | P1 | | **类型** | 边界测试 | -| **标题** | size=33 走 DMA 路径,读写正确 | +| **标题** | size=1025(= `GD5F_DMA_THRESHOLD`+1)走 DMA 路径,读写正确 | | **前置条件** | 目标块已擦除 | -| **测试步骤** | 写/读 33 字节并比对 | +| **测试步骤** | 写/读 1025 字节并比对 | | **通过标准** | 数据一致 | | **覆盖原则** | `GD5F_DMA_THRESHOLD` 上界 | @@ -465,6 +468,41 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10` | **通过标准** | 数据一致 | | **覆盖原则** | DMA 大数据路径 | +### TC-GD5F-704: DMA 可达性守卫负路径(读方向) + +| 字段 | 值 | +|------|-----| +| **ID** | TC-GD5F-704 | +| **优先级** | P0 | +| **类型** | 边界/健壮性测试 | +| **标题** | 目的缓冲位于 CCM(不可达区)时守卫应拒绝 DMA 并回落轮询,数据仍正确 | +| **前置条件** | FreeRTOS 堆驻留 CCM(scatter `RW_CCM`);探针缓冲由 `pvPortMalloc(2048)` 取得(堆不在 CCM 时用例跳过) | +| **测试步骤** | 1. 先用 SRAM 静态缓冲参考读同页
2. 探针缓冲预填参考值的反码
3. `gd5f2gq5ue_read()` 整页读入 CCM 探针缓冲
4. 与参考缓冲逐字节比对 | +| **通过标准** | 数据与参考完全一致,且串口出现 `[ERR][NAND] RX DMA buffer not DMA-reachable (p=0x1000xxxx size=2048), fallback poll` | +| **判定依据** | 本板实证 DMA 对 CCM 静默不落地:若误走 DMA,探针缓冲保持预填反码必失配——故"数据一致"即证明回落真实发生,而非仅"未报错" | +| **覆盖原则** | DMA 可达性守卫(读方向);堆缓冲禁入 DMA 的运行时强制(内存分配策略 R3) | + +### TC-GD5F-705: DMA 可达性守卫负路径(写方向) + +| 字段 | 值 | +|------|-----| +| **ID** | TC-GD5F-705 | +| **优先级** | P0 | +| **类型** | 边界/健壮性测试 | +| **标题** | 源缓冲位于 CCM(不可达区)时守卫应拒绝 DMA 并回落轮询,数据仍正确落盘 | +| **前置条件** | 同 TC-GD5F-704;目标块已擦除 | +| **测试步骤** | 1. 探针缓冲填入 `i^0x5A` 图案
2. `gd5f2gq5ue_write()` 整页写入
3. 读回 SRAM 静态缓冲逐字节比对 | +| **通过标准** | 写读一致,且串口出现 `[ERR][NAND] TX DMA buffer not DMA-reachable … fallback poll` | +| **判定依据** | 同 TC-GD5F-704(写方向 DMA 读 CCM 同样不落地) | +| **覆盖原则** | DMA 可达性守卫(写方向);堆缓冲禁入 DMA 的运行时强制(内存分配策略 R3) | + +> ⚠ **卷破坏警告**:阶段 8 会调用 `nand_ftl_format()` 清空 dhara map,阶段 9 会写入文件—— +> 整轮 GD5F 套件(含 Phase 8/9)运行后卷数据即失效,且大写入可能使 dhara 把若干块记为 +> 运行期坏块(2026-09-21 实测:一次整轮运行容量 95248 → 95200,日志见 +> `[ERR][NAND_FTL] program verify: data mismatch, blk 305`,该块由 dhara 自行隔离,测试仍 68/68 通过)。 +> 需要恢复干净态时,启用 `ENABLE_STORAGE_RECOVERY_TESTS` 跑一次 STORAGE 套件的 TC-STO-04 +> (重建 BBT + 重新格式化)。 + ## 9. 阶段 8:FTL 层(nand_ftl) ### TC-GD5F-801: nand_ftl_init 成功 @@ -673,9 +711,11 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10` | TC-GD5F-603 | block_erase 原语 | P1 | PASS | | TC-GD5F-604 | write_enable WEL 位 | P2 | PASS | | TC-GD5F-605 | wait_busy 正常返回 | P2 | PASS | -| TC-GD5F-701 | DMA 阈值下界(32) | P1 | PASS | -| TC-GD5F-702 | DMA 阈值上界(33) | P1 | PASS | +| TC-GD5F-701 | DMA 阈值下界(1024) | P1 | PASS | +| TC-GD5F-702 | DMA 阈值上界(1025) | P1 | PASS | | TC-GD5F-703 | 大块 DMA 一致性 | P1 | PASS | +| TC-GD5F-704 | DMA 守卫负路径(读,CCM) | P0 | PASS | +| TC-GD5F-705 | DMA 守卫负路径(写,CCM) | P0 | PASS | | TC-GD5F-801 | nand_ftl_init | P0 | PASS | | TC-GD5F-802 | nand_ftl_format | P1 | PASS | | TC-GD5F-901 | FatFS 挂载写读 | P2 | PASS | @@ -688,7 +728,7 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10` | TC-STO-03 | 坏块注入下存储写入 | P1 | PASS | | TC-STO-04 | BBT 重建 + 重新格式化(恢复) | P1 | 受 `ENABLE_STORAGE_RECOVERY_TESTS` 控制(默认关) | -> 当前实测:`TEST_SUITE_GD5F` 构建一次运行全部阶段,结尾输出 `=== GD5F2GQ5UE Tests: 65/65 PASSED (failed=0) ===`(65 为各 TC 内部断言总数,含 TC-GD5F-205~207 BBT 持久化用例;TC 覆盖见上表)。`TEST_SUITE_STORAGE` 套件结尾输出 `=== Storage Tests: 11/11 PASSED (failed=0) ===`(TC-STO-01/02/03 各含若干内部断言,且 TC-STO-01 依赖的 `s_cached_lpn` 哨兵 bug 已修复)。两套件均 0 错误 0 警告通过 MDK 编译。 +> 当前实测:`TEST_SUITE_GD5F` 构建一次运行全部阶段,结尾输出 `=== GD5F2GQ5UE Tests: 68/68 PASSED (failed=0) ===`(68 为各 TC 内部断言总数,含 TC-GD5F-205~207 BBT 持久化用例、TC-GD5F-704/705 DMA 守卫负路径;TC 覆盖见上表)。`TEST_SUITE_STORAGE` 套件结尾输出 `=== Storage Tests: 11/11 PASSED (failed=0) ===`(TC-STO-01/02/03 各含若干内部断言,且 TC-STO-01 依赖的 `s_cached_lpn` 哨兵 bug 已修复)。两套件均 0 错误 0 警告通过 MDK 编译。 --- @@ -733,7 +773,7 @@ ECC 状态(`ECCS1:ECCS0`):`00`=无错;`01/10/11`=纠正 1/2/3 bit;`10` | 总块数 / 容量 | 2048 / 256 MB | | ID | MID=0xC8, DID=0x52 | | 擦除最小单位 | 1 块(128 KB,须对齐) | -| DMA 阈值 | 32 B(>32 走 DMA) | +| DMA 阈值 | 1024 B(>1024 走 DMA;非 SRAM 缓冲由守卫回落轮询) | | 状态寄存器 | 0xC0;OIP=0, WEL=1, E_FAIL=2, P_FAIL=3, ECCS=4/5 | | Feature 寄存器 | 0xB0;ECC_EN=4, QE=0 | | Protect 寄存器 | 0xA0;init 后写 0x00 解除保护 | diff --git a/test/gd5f_test_task.c b/test/gd5f_test_task.c index bd5bb685..2bc3b699 100644 --- a/test/gd5f_test_task.c +++ b/test/gd5f_test_task.c @@ -2,8 +2,9 @@ * 模块名称:GD5F2GQ5UE Driver Test Task * 模块功能:GD5F2GQ5UE 驱动全阶段测试入口,统一在 defaultTask 上下文(同步阻塞) * 中运行。各阶段由 gd5f_test.h 中的 ENABLE_GD5F_PHASE*_TESTS 宏独立开关, - * 覆盖 init/read_id/reset、BBT、页读写、块擦除、ECC、SPI 原语、DMA 边界、 - * FTL 与 FatFS。所有结果通过 GD5F_TEST_CHECK / GD5F_TEST_REPORT 输出串口。 + * 覆盖 init/read_id/reset、BBT、页读写、块擦除、ECC、SPI 原语、DMA 边界与 + * DMA 可达性守卫负路径、FTL 与 FatFS。所有结果通过 GD5F_TEST_CHECK / + * GD5F_TEST_REPORT 输出串口。 * 作者:王建锋 * 创建日期:2026-08-26 * @@ -12,6 +13,7 @@ ******************************************************************************/ #include +#include "FreeRTOS.h" #include "test_config.h" #include "gd5f_test.h" #include "nand_ftl.h" @@ -30,6 +32,10 @@ gd5f_test_stats_t g_gd5f_test_stats; static uint8_t s_wbuf[GD5F_PAGE_SIZE * 2]; static uint8_t s_rbuf[GD5F_PAGE_SIZE * 2]; +/* CCM(SRAM3)区间:DMA1/DMA2 物理不可达,用于守卫负路径的前提判定 */ +#define GD5F_TEST_CCM_BASE 0x10000000UL +#define GD5F_TEST_CCM_END 0x10010000UL + /* ------------------------------------------------------------------- * 辅助:从最高块向下寻找连续 n 个好块,返回其中最高块号;找不到返回 GD5F_TOTAL_BLOCKS * ------------------------------------------------------------------- */ @@ -514,7 +520,7 @@ static void gd5f_phase6(void) #endif /* ENABLE_GD5F_PHASE6_TESTS */ /* ------------------------------------------------------------------- - * Phase 7 — DMA 边界(阈值 32 字节) + * Phase 7 — DMA 边界与 DMA 可达性守卫(阈值见 GD5F_DMA_THRESHOLD) * ------------------------------------------------------------------- */ #ifdef ENABLE_GD5F_PHASE7_TESTS static void gd5f_phase7(void) @@ -522,37 +528,42 @@ static void gd5f_phase7(void) uint32_t blk; int32_t base; int32_t ret, ok, i; + uint8_t *p_heap; /* 堆缓冲探针(堆驻留 CCM → DMA 不可达) */ + uintptr_t p_addr; - DBG_INFO("=== GD5F Phase 7: DMA boundary (threshold 32) ==="); + DBG_INFO("=== GD5F Phase 7: DMA boundary (threshold %d) ===", + (int)GD5F_DMA_THRESHOLD); blk = gd5f_find_run(1); base = (int32_t)blk * GD5F_BLOCK_SIZE; - /* TC-GD5F-701: size=32 轮询路径 */ + /* TC-GD5F-701: 阈值下界(= 阈值,轮询路径) */ gd5f2gq5ue_erase(base, GD5F_BLOCK_SIZE); - for (i = 0; i < 32; i++) { + for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD; i++) { s_wbuf[i] = (uint8_t)(i + 0x10); } - ret = gd5f2gq5ue_write(base, s_wbuf, 32); - GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-701 write(32) ret=%d", ret); - memset(s_rbuf, 0, 32); - ret = gd5f2gq5ue_read(base, s_rbuf, 32); + ret = gd5f2gq5ue_write(base, s_wbuf, GD5F_DMA_THRESHOLD); + GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-701 write(%d) ret=%d", + (int)GD5F_DMA_THRESHOLD, ret); + memset(s_rbuf, 0, GD5F_DMA_THRESHOLD); + ret = gd5f2gq5ue_read(base, s_rbuf, GD5F_DMA_THRESHOLD); ok = 1; - for (i = 0; i < 32; i++) { + for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD; i++) { if (s_rbuf[i] != (uint8_t)(i + 0x10)) { ok = 0; break; } } GD5F_TEST_CHECK(ok, "TC-GD5F-701 polling path %s", ok ? "OK" : "MISMATCH"); - /* TC-GD5F-702: size=33 DMA 路径 */ + /* TC-GD5F-702: 阈值上界(= 阈值+1,DMA 路径,缓冲在 SRAM 静态区) */ gd5f2gq5ue_erase(base, GD5F_BLOCK_SIZE); - for (i = 0; i < 33; i++) { + for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD + 1; i++) { s_wbuf[i] = (uint8_t)(i + 0x20); } - ret = gd5f2gq5ue_write(base, s_wbuf, 33); - GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-702 write(33) ret=%d", ret); - memset(s_rbuf, 0, 33); - ret = gd5f2gq5ue_read(base, s_rbuf, 33); + ret = gd5f2gq5ue_write(base, s_wbuf, GD5F_DMA_THRESHOLD + 1U); + GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-702 write(%d) ret=%d", + (int)GD5F_DMA_THRESHOLD + 1, ret); + memset(s_rbuf, 0, GD5F_DMA_THRESHOLD + 1U); + ret = gd5f2gq5ue_read(base, s_rbuf, GD5F_DMA_THRESHOLD + 1U); ok = 1; - for (i = 0; i < 33; i++) { + for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD + 1; i++) { if (s_rbuf[i] != (uint8_t)(i + 0x20)) { ok = 0; break; } } GD5F_TEST_CHECK(ok, "TC-GD5F-702 DMA path %s", ok ? "OK" : "MISMATCH"); @@ -571,6 +582,52 @@ static void gd5f_phase7(void) if (s_rbuf[i] != (uint8_t)(i & 0xFF)) { ok = 0; break; } } GD5F_TEST_CHECK(ok, "TC-GD5F-703 DMA whole page %s", ok ? "OK" : "MISMATCH"); + + /* ================= DMA 可达性守卫(负路径) ================= + * 探针缓冲取自 FreeRTOS 堆:堆驻留 CCM(0x10000000),DMA1/DMA2 不可达。 + * 期望:驱动守卫拒绝该缓冲 → 回落 CPU 轮询 → 数据仍正确落位(轮询可写 CCM)。 + * 判定依据(本板实证):若误走 DMA,CCM 内容不会改变(静默不落地), + * 故"数据与参考一致"即证明回落确实发生——非仅未报错。 + * 堆不在 CCM 时本用例前提不成立(改为验证正路径无意义),跳过并记录。 */ + p_heap = (uint8_t *)pvPortMalloc(GD5F_PAGE_SIZE); + if (p_heap == NULL) { + GD5F_TEST_CHECK(0, "TC-GD5F-704 pvPortMalloc(2048) failed"); + } else { + p_addr = (uintptr_t)p_heap; + if ((p_addr < GD5F_TEST_CCM_BASE) || (p_addr >= GD5F_TEST_CCM_END)) { + DBG_INFO("TC-GD5F-704/705 SKIP: heap buf not in CCM (p=0x%08lX)", + (unsigned long)p_addr); + } else { + /* TC-GD5F-704: 读方向 —— 目的缓冲在 CCM,应回落轮询 */ + memset(s_rbuf, 0, GD5F_PAGE_SIZE); + (void)gd5f2gq5ue_read(base, s_rbuf, GD5F_PAGE_SIZE); /* 参考读(SRAM 静态) */ + for (i = 0; i < GD5F_PAGE_SIZE; i++) { + p_heap[i] = (uint8_t)~s_rbuf[i]; /* 预填参考值反码:未落数必失配 */ + } + ret = gd5f2gq5ue_read(base, p_heap, GD5F_PAGE_SIZE); + ok = (ret == GD5F_OK) && + (memcmp(p_heap, s_rbuf, GD5F_PAGE_SIZE) == 0); + GD5F_TEST_CHECK(ok, "TC-GD5F-704 CCM(heap) rx poll fallback %s", + ok ? "OK" : "MISMATCH"); + + /* TC-GD5F-705: 写方向 —— 源缓冲在 CCM,应回落轮询 */ + gd5f2gq5ue_erase(base, GD5F_BLOCK_SIZE); + for (i = 0; i < GD5F_PAGE_SIZE; i++) { + p_heap[i] = (uint8_t)(i ^ 0x5A); + } + ret = gd5f2gq5ue_write(base, p_heap, GD5F_PAGE_SIZE); + GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-705 write(CCM src) ret=%d", ret); + memset(s_rbuf, 0, GD5F_PAGE_SIZE); + ret = gd5f2gq5ue_read(base, s_rbuf, GD5F_PAGE_SIZE); + ok = 1; + for (i = 0; i < GD5F_PAGE_SIZE; i++) { + if (s_rbuf[i] != (uint8_t)(i ^ 0x5A)) { ok = 0; break; } + } + GD5F_TEST_CHECK(ok, "TC-GD5F-705 CCM(heap) tx poll fallback %s", + ok ? "OK" : "MISMATCH"); + } + vPortFree(p_heap); + } } #endif /* ENABLE_GD5F_PHASE7_TESTS */