在 Aurix TC3xx 中,从 HSM 写入 DFLASH1 时出现 SQER (Sequence Error) 通常是由于命令序列不符合闪存控制器的要求。根据您提供的操作序列,以下是问题分析和解决方案:
错误的命令序列:
Load Page Start (0x40) → 写入 8 个数据字 → Page Write (0x47)。0x40(加载页面开始命令)。0x47(页面写入命令)的触发地址错误(应为目标 DFLASH 地址,而非寄存器地址)。寄存器地址误用:
0xF00400C0 是 FLASH1_FSR(状态寄存器),向其写入数据无意义。0xF00555F0、0xF005AA50 等地址属于 PFLASH 空间,而不是 DFLASH 的页面缓冲区地址。页面缓冲区地址错误:
0xF0050000(参考 TC3xx 手册)。0xF00555F0 等地址不正确。关键命令缺失:
0x40 初始化页面缓冲区。0x47 到目标 DFLASH 地址触发写入。// 步骤 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),而非寄存器地址。
FSR.BUSY(地址 0xF00400C0 的 bit0),确保前一个操作完成。0xAFC10000)必须对齐到页面边界。FSR 寄存器错误标志(如 SQER、PROER):if (*(volatile uint32_t *)0xF00400C0 & 0x2) {
// 处理 SQER 错误
*(volatile uint32_t *)0xF00400C0 |= 0x2; // 写 1 清除错误标志
}验证 DFLASH 状态:
0xFFFFFFFF)。0x71(Verify All One)命令校验:*(volatile uint32_t *)0xAFC10000 = 0x71; // 发送校验命令
while (FSR.BUSY);
if (FSR.VER) { /* 验证失败 */ }简化测试用例:
{0x12345678, 0x00000000, ..., 0xFFFFFFFF}。检查寄存器映射:
FLASH1_FCR = 0xF00400C4FLASH1_FSR = 0xF00400C0FSR 写入数据(除非清除错误标志)。#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 错误。如果问题仍存在,请检查:
举报
更多回帖