23. FLASH 控制器与 ISP 操作
23.1. 概述
SWM221 系列内置FLASH。可以通过调用 IAP 函数或寄存器读写的方式进行 FLASH 操作。
重要
操作FLASH前,需要关闭中断,防止打断造成写入错误。
23.2. 特性
支持FLASH编程
支持ISP(在系统编程)更新用户程序
支持BOOT自定义
支持加密
23.3. 功能描述
23.3.1. FLASH操作
FLASH操作可以通过寄存器进行操作,也可以通过IAP函数进行擦除及写入。
SWM221 系列芯片 FLASH 每一页(PAGE)为 512 个 字节(Bytes)。写入时最小单元为 2 个字(32-bit,Word), 但是系统数据总线只有 32-bit,必须通过连续 2 次对 DATA 寄存器写入 2 个 32-bit 数据来完成一次的写入。 FLASH 写入接口 DATA 寄存器是以 FIFO 方式实现。
23.3.1.1. 寄存器操作
FLASH 擦写操作流程均可在 FLASH 或 SRAM 中执行。
ERASE操作
必须连续依次只对 CFG1 寄存器写入 0x5A5A5A5A,0xA5A5A5A5 解除 FLASH 的只读属性。
FLASH 擦写使能位 CFG0.WREN 置 1。
往 ERASE.ADDR 高 8 位写入 PAGE 地址,低 8 位 写入 0,同时 REQ 写入全 1;进行全片擦除,则往 ERASE.ADDR 写入全 1, 同时 REQ 写入全 1。
查询 STAT.ERASEBUSY 位, 直至状态从 1 变为 0,擦除完成。当 FLASH 完成擦除操作后,方可对 FLASH 进行其他操作。
重复以上两个步骤持续进行擦除其它页。
FLASH 擦写使能位 CFG0.WREN 置 0。
往 CFG1 寄存器写入任意值,恢复 FLASH 只读属性。
PROGRAM 操作
必须连续依次对 CFG1 寄存器写入 0x5A5A5A5A,0xA5A5A5A5 解除 FLASH 的只读属性。
FLASH 擦写使能位 CFG0.WREN 置 1。
地址写入 ADDR 寄存器,必须双字(64-bit)对齐。
DATA 寄存器连续写入 2 个字 (32-bit)。
查询 STAT.FIFOEMPTY 位, 直至状态从 1 变为 0 后,表示数据已经从缓冲区读取,此时可以继续写下一组数据。
重复以上两个步骤持续进行写入, ADDR 地址自动递增。如需要改变地址,则需要重新写 ADDR 寄存器。
查询 STAT.PROGBUSY 位,直至状态从 1 变为 0,写入完成。当 FLASH 完成写入操作后,方可对 FLASH 进行其他操作。
FLASH 擦写使能位 CFG0.WREN 置 0。
往 CFG1 寄存器写入任意值,恢复 FLASH 只读属性。
重要
我司不建议用户通过寄存器直接操作 FLASH 擦写。如有需要请联系技术支持。
请使用芯片内置 IAP 函数进行 FLASH 擦写操作。
23.3.1.2. IAP操作
IAP 函数作为片内驻留程序,其提供了针对 FLASH 的相关操作 IAP 函数为 Thumb 代码,分为擦除函数(驻留地址为 0x1000401)和写入函数(驻留地址为 0x1000461),建议使用如下方式调用:
擦除函数类型定义: |
typedef uint32_t (*IAPFunc1) (uint32_t PageNum); IAPFunc1 FLASH_PageErase = (IAPFunc1) 0x1000401; |
变量定义如下: |
PageNum: FLASH 擦除目标页码,以 PAGE 为单位,0 为首地址,N 为 PAGE * N 对应地址 |
返回值: |
0:擦除成功 1:擦除失败,参数错误 |
调用 |
Result = FLASH_PageErase(10); |
擦除第 10 * PAGE 的内容。Result 返回 0 表示成功。 |
写入函数类型定义: |
typedef void (*IAPFunc2) (uint32_t faddr, uint32_t raddr, uint32_t cnt); IAPFunc2 FLASH_PageWrite = (IAPFunc2) 0x1000461; |
变量定义如下: |
faddr: FLASH 写入目标地址,字对齐 raddr: RAM 写入目标地址,字对齐 cnt: 写入数量,字为单位,长度不超过1page |
返回值: |
0:写入成功 1:写入失败,参数错误 |
调用: |
Result = FLASH_PageWrite(0x400, 0x20000400, 8); |
将 RAM 地址 0x20000400 开始的 8 * 4 个字节写入flash 地址 0x400 起始。Result 返回 0 表示成功。 |
调用 IAP 函数时,应保证栈空间剩余 24 个字节(byte)以上。执行写操作前,需确认对应目标地址已经执行过擦除操作。
备注
详细IAP操作请参阅库函数。
23.3.2. ISP(在系统编程)模式
当芯片上电后检测到 ISP 引脚持续 5ms 以上的高电平后,将会进入 ISP 模式。配合上位机及串口可执行程序更新操作, 具体引脚请参考 SWM221 系列数据手册之管脚定义章节。
注意
ISP方式的串口烧录时,默认使用 C0 (UART1_TX) 以及 C1 (UART1_TX) 作为串口通讯使用。
详细ISP操作请参阅应用文档及库函数。
23.3.3. BOOT 自定义
FLASH 地址空间支持将指定地址的 2KB 数据映射至 0x00000000 空间,通过 REMAP 寄存器实现。将地址(2KB 对齐)写入 REMAP 寄存器 BASEADD,并将 EN 位置1,则指定地址内容将被映射至 0x00000000 空间,可通过此功能实现向量表的重映射。
例如
BOOT: 0x00000000 ~ 0x00004000
USER: 0x00004000 ~ 0x00008000
在 BOOT 中配置 REMAP 寄存器地址为 0x00004000 并使能,并跳转至 USER 执行,当读取 0x00000000 地址时,返回内容为 0x00004000 地址内容。
23.3.4. 加密方式
控制器加密支持以下三种级别:
级别 |
说明 |
关键字值 |
---|---|---|
级别 1 |
不加密,SWD 可正常读写。 |
0x00000000 |
级别 2 |
SWD 读取加密,SWD 无法读取 FLASH,只能执行擦除操作,连接 SWD 后,FLASH 无法执行读操作,读取 FLASH 会进入 Hardfault。 |
0x43211234 |
级别 3 |
SWD 封锁,SWD 无法执行读取及擦除工作,只能通过 ISP 进行擦除。 |
0xABCD1234 |
提示
通过在用户程序中将 0x0000001C 偏移地址配置为指定关键字,即可实现指定级别的加密。程序下载后再次上电后,芯片将处于指定加密级别的状态。
23.4. 寄存器映射
名称 |
偏移 |
复位值 |
---|---|---|
FLASHCTL BASE:0x40045000 |
||
DATA |
0x00 |
- |
ADDR |
0x04 |
0x00000000 |
ERASE |
0x08 |
0x00000000 |
CACHE |
0x0C |
0x00000000 |
CFG0 |
0x10 |
0x00000000 |
CFG1 |
0x14 |
0x00000000 |
CFG2 |
0x18 |
0x00000053 |
STAT |
0x24 |
0x000000A8 |
REMAP |
0x28 |
0x00000000 |
23.5. 寄存器描述
23.5.1. DATA寄存器
偏移: 0x00 |
复位值: N/A |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
DATA |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:0 |
DATA |
WO |
FLASH 写入数据 FIFO 入口。CFG0[9] 为 1 才可以向这个寄存器写入数据。 |
23.5.2. ADDR 寄存器
偏移: 0x04 |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ADDR |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:0 |
ADDR |
WO |
FLASH 写入起始地址 |
23.5.3. ERASE寄存器
偏移: 0x08 |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
ERASE_REQ |
|||||||
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
ADDR[16] |
|||||||
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
ADDR[15:8] |
|||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
ADDR[7:0] |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:24 |
REQ |
R/W |
0xFF: 擦除请求有效 其它值: 擦除请求无效 |
23:17 |
- |
R/W |
保留,必须保持复位值。 |
16:0 |
ADDR |
R/W |
擦除地址,高8位有效,每次擦出512byte空间。全 1 表示全片擦除。 |
23.5.4. CACHE寄存器
偏移: 0x0C |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
CCLR |
|||||||
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
EN |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31 |
CCLR |
R/W |
清空 Cache,写 1 有效,自动清零 |
30:1 |
- |
R/W |
保留, 必须保持复位值。 |
0 |
EN |
R/W |
CACHE 使能,1有效。默认关闭 |
23.5.5. CFG0寄存器
偏移: 0x10 |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
WREN |
|||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:10 |
- |
R/W |
保留,必须保持复位值。 |
9 |
WREN |
R/W |
FLASH 擦除与写入使能,1有效。 |
8:0 |
- |
R/W |
保留,必须保持复位值。 |
23.5.6. CFG1寄存器
偏移: 0x14 |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
CFG1[31:24] |
|||||||
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
CFG1[23:16] |
|||||||
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
CFG1[15:8] |
|||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
CFG1[7:0] |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:0 |
CFG1 |
WO |
连续依次写入0x5A5A5A5A, 0xA5A5A5A5后,解除 FLASH 的只读属性,允许擦除和编程。 写入其它任意值恢复只读属性。 |
23.5.7. CFG2寄存器
偏移: 0x18 |
复位值: 0x00000053 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
CLK_CYC |
|||||||
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:16 |
RO |
保留,必须保持复位值 |
|
15:0 |
CLK_CYC |
R/W |
系统时钟周期,以 ns 为单位,向下取整。比如当系统时钟为 8MHz,则周期配置为 125。 为防止复位阶段因 HRC 频偏导致 FLASH 访问不成功,复位设置为12M频率对应值。 请使库函数提供的 Flash_Param_at_xMHz() 函数操作此寄存器。 |
23.5.8. STAT寄存器
偏移: 0x24 |
复位值: 0x000000a8 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
IDLE |
|||||||
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
READONLY |
FIFOFULL |
FIFOEMPTY |
READBUSY |
PROGBUSY |
ERASEBUSY |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31 |
IDLE |
RO |
0: FLASH 操作进行中。 1: FLASH 空闲。 |
30:8 |
- |
RO |
保留,只读。 |
7 |
READONLY |
RO |
FLASH 只读属性生效。 |
6:5 |
- |
RO |
保留,只读。 |
4 |
FIFOFULL |
RO |
FIFO 满。 |
3 |
FIFOEMPTY |
RO |
FIFO 空。 |
2 |
READBUSY |
RO |
FLASH 读操作进行中。 |
1 |
PROGBUSY |
RO |
FLASH 写入操作进行中。 |
0 |
ERASEBUSY |
RO |
FLASH 擦除操作进行中。 |
23.5.9. REMAP寄存器
偏移: 0x28 |
复位值: 0x00000000 |
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
REMAP_OFFSET |
ON |
位域 |
名称 |
类型 |
描述 |
---|---|---|---|
31:7 |
- |
R/W |
保留,必须保持复位值。 |
6:1 |
REMAP_OFFSET |
R/W |
当 REMAP 打开时,对 0 地址开头的 2KB 地址的访问都映射到 REMAP_OFFSET 基地址对应的 2KB 地址。 |
0 |
ON |
R/W |
置 1 打开 REMAP 功能。REMAP 操作只作用于 FLASH 读取操作。 进入和退出 REMAP 前需关闭 CACHE 功能,并执行一次 CACHE 清除操作。 |