单片机/MCU论坛
直播中

三心四意

9年用户 888经验值
私信 关注
[问答]

Aurix TC3xx从HSM写入DFLASH1时出现SQER错误,怎么解决?

我在使用 Aurix TC364 从 HSM 写入 DFLASH1 时遇到 SQER 错误。
使用的顺序如下:
- 验证地址 0xAFC00000、0xAFC10000、0xAFC11000 处的已擦除页面……
- 进入页面模式
- @0xF00400C0 <- 0xAF000000(加载页面开始)
- @0xF00555F0 <- 第一个 32 位值
-@0xF00400C0 <- 0xAF000000
- @0xF00555F4 <- 第二个 32 位值
- @0xF00400C0 <- 0xAF000000(写入页面开始)
-@0xF005AA50 <- 0xAFC10000
-@0xF00400C0 <- 0xAF000000
-@0xF005AA58 <- 0
-@0xF00400C0 <- 0xAF000000
-@0xF005AAA8 <- 0xA0
-@0xF00400C0 <- 0xAF000000
-@0xF005AAA8 <- 0xAA
我尝试仅使用只有一个 32 位值的 Load Page 命令,但结果是一样的。你知道什么地方可能出错吗?

回帖(1)

王飞云

2025-8-13 17:50:56

在 Aurix TC3xx 中,从 HSM 写入 DFLASH1 时出现 SQER (Sequence Error) 通常是由于命令序列不符合闪存控制器的要求。根据您提供的操作序列,以下是问题分析和解决方案:




问题分析




  1. 错误的命令序列



    • DFLASH 编程需要严格的命令序列:Load Page Start (0x40) → 写入 8 个数据字 → Page Write (0x47)

    • 您的序列中:

      • 缺少明确的 0x40(加载页面开始命令)。

      • 未正确写入 8 个数据字到页面缓冲区。

      • 0x47(页面写入命令)的触发地址错误(应为目标 DFLASH 地址,而非寄存器地址)。





  2. 寄存器地址误用



    • 0xF00400C0FLASH1_FSR(状态寄存器),向其写入数据无意义。

    • 0xF00555F00xF005AA50 等地址属于 PFLASH 空间,而不是 DFLASH 的页面缓冲区地址。




  3. 页面缓冲区地址错误



    • DFLASH1 的页面缓冲区基地址应为 0xF0050000(参考 TC3xx 手册)。

    • 您使用的 0xF00555F0 等地址不正确。




  4. 关键命令缺失



    • 未发送 0x40 初始化页面缓冲区。

    • 未发送 0x47 到目标 DFLASH 地址触发写入。






解决方案


1. 正确的命令序列


// 步骤 1: 初始化页面缓冲区 (Load Page Start)
*(volatile uint32_t *)0xF0050000 = 0x40;  // 基地址: DFLASH1 页面缓冲区 (0xF0050000)
while ((*(volatile uint32_t *)0xF00400C0 & 0x1) != 0); // 等待 FSR.BUSY=0

// 步骤 2: 写入 8 个连续数据字(32-bit)到页面缓冲区
*(volatile uint32_t *)0xF0050000 = data0; // 地址偏移 +0
*(volatile uint32_t *)0xF0050004 = data1; // 地址偏移 +4
...
*(volatile uint32_t *)0xF005001C = data7; // 地址偏移 +28 (共 8 个字)
// 每次写入后无需额外命令,但需检查 BUSY(如有必要)

// 步骤 3: 触发页面写入 (Page Write) 到目标 DFLASH 地址
*(volatile uint32_t *)0xAFC10000 = 0x47;  // 目标地址必须是合法的 DFLASH 地址
while ((*(volatile uint32_t *)0xF00400C0 & 0x1) != 0); // 等待 BUSY=0


关键点



  • 页面缓冲区地址:0xF0050000(DFLASH1 专用)。

  • 0x47 必须写入 目标 DFLASH 物理地址(如 0xAFC10000),而非寄存器地址。





2. 其他注意事项



  • 等待 BUSY 清除

    • 每次命令后检查 FSR.BUSY(地址 0xF00400C0 的 bit0),确保前一个操作完成。


  • 地址对齐

    • DFLASH 页面大小为 256 字节(64 个 32 位字)。目标地址(如 0xAFC10000)必须对齐到页面边界。


  • HSM 权限

    • 确保 HSM 固件有权访问 DFLASH1。检查 UCB_DFLASH 权限配置。


  • 错误处理

    • 检查 FSR 寄存器错误标志(如 SQER、PROER):
      if (*(volatile uint32_t *)0xF00400C0 & 0x2) { 
      // 处理 SQER 错误
      *(volatile uint32_t *)0xF00400C0 |= 0x2; // 写 1 清除错误标志
      }





3. 调试建议




  1. 验证 DFLASH 状态



    • 确保目标页面已擦除(全为 0xFFFFFFFF)。

    • 使用 0x71(Verify All One)命令校验:
      *(volatile uint32_t *)0xAFC10000 = 0x71; // 发送校验命令
      while (FSR.BUSY);
      if (FSR.VER) { /* 验证失败 */ }




  2. 简化测试用例



    • 仅写入单页(8 个数据字),避免复杂数据流。

    • 示例数据:{0x12345678, 0x00000000, ..., 0xFFFFFFFF}




  3. 检查寄存器映射



    • 确认 HSM 使用的 DFLASH 控制器寄存器:

      • 命令寄存器:FLASH1_FCR = 0xF00400C4

      • 状态寄存器:FLASH1_FSR = 0xF00400C0


    • 不要直接向 FSR 写入数据(除非清除错误标志)。






修正后的完整示例


#define DFLASH_PAGE_BASE   0xF0050000 // DFLASH1 页面缓冲区
#define DFLASH_TARGET_ADDR 0xAFC10000 // DFLASH 目标地址
#define FSR                (*(volatile uint32_t *)0xF00400C0)

void write_dflash_page(uint32_t *data) {
    // 1. 初始化页面
    *(volatile uint32_t *)DFLASH_PAGE_BASE = 0x40; // Load Page Start
    while (FSR & 0x1); // 等待 BUSY=0

    // 2. 写入 8 个数据字
    for (int i = 0; i < 8; i++) {
        *(volatile uint32_t *)(DFLASH_PAGE_BASE + i*4) = data[i];
        // 可选:添加短延时或检查 BUSY(若需严格时序)
    }

    // 3. 触发写入
    *(volatile uint32_t *)DFLASH_TARGET_ADDR = 0x47; // Page Write
    while (FSR & 0x1); // 等待 BUSY=0

    // 4. 检查错误
    if (FSR & 0x2) {
        // 处理 SQER 错误
        FSR |= 0x2; // 清除错误标志
    }
}

通过遵循正确的命令序列和地址映射,即可解决 SQER 错误。如果问题仍存在,请检查:



  1. HSM 对 DFLASH 的访问权限(UCB 配置)。

  2. 时钟初始化(确保闪存控制器时钟使能)。

  3. 电压稳定性(低电压可能导致闪存操作失败)。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分