;******************************************************************************
; 文件名:IAPTEST.S
; 功能:LPC2200的IAP功能测试。
; 1. 选择扇区,命令代码50
; 2. 复制RAM数据到FLASH,即FLASH编程,命令代码51
; 3. 擦除扇区,命令代码52
; 4. 查空扇区,命令代码53
; 5. 读取器件ID,命令代码54
; 6. 读取boot代码版本号,命令代码55
; 7. 校验数据,命令代码56
; 说明:使用JTAG调试,观察操作返回值及操作结果。
;******************************************************************************
INCLUDE LPC2294.INC
EXPORT MAIN
IAP_Enter EQU 0x7FFFFFF0 ; IAP入口地址定义
IAP_ParIn EQU 0x40003E00 ; 定义IAP入口参数地址(缓冲区0x40003E00-0x40003E10)
IAP_ParOut EQU 0x40003D00 ; 定义IAP出口参数地址(缓冲区0x40003D00-0x40003D10)
; 定义IAP命令字
IAP_SELSECTOR EQU 50
IAP_RAMTOFLASH EQU 51
IAP_ERASESECTOR EQU 52
IAP_BLANKCHK EQU 53
IAP_READPARTID EQU 54
IAP_BOOTCODEID EQU 55
IAP_COMPARE EQU 56
; 定义CCLK值大小,单位为KHz
IAP_FCCLK EQU 11059
AREA IAPTESTC, CODE, READONLY
ENTRY
; 使用IAP功能时,RAM的顶端的32字节保留给IAP操作使用;
; IAP入口为THUMB状态,所以调用时使用BX指令(切换处理器状态)。
MAIN LDR SP,=0x40003F00 ; 设置堆栈指针
LDR R0,=MAMCR
MOV R1,#0x00 ; 关闭MAM
STR R1,[R0]
LDR R0,=PLLCON
MOV R1,#0x00 ; 关闭PLL
STR R1,[R0]
LDR R0,=PLLFEED
MOV R1,#0xAA
STR R1,[R0]
MOV R1,#0x55
STR R1,[R0]
; 读取器件ID
BL ReadParID
; 读取boot代码版本号
BL BootCodeID
; 选择扇区1
MOV R2,#1 ; 设置入口参数,起始扇区号
MOV R3,#1 ; 终止扇区号(要大于等于起始扇区)
BL SelSector ; 选择操作扇区
; 擦除扇区1
MOV R2,#1
MOV R3,#1
BL EraseSector
; 查空扇区1
MOV R2,#1
MOV R3,#1
BL BlankCHK
; 选择扇区1
MOV R2,#1 ; 设置入口参数,起始扇区号
MOV R3,#1 ; 终止扇区号(要大于等于起始扇区)
BL SelSector ; 选择操作扇区
; 写数据到扇区1
MOV R2,#0x00002000
MOV R3,#0x40000000
MOV R4,#512
BL RamToFlash
; 选择扇区1
MOV R2,#1 ; 设置入口参数,起始扇区号
MOV R3,#1 ; 终止扇区号(要大于等于起始扇区)
BL SelSector ; 选择操作扇区
; 查空扇区1
MOV R2,#1
MOV R3,#1
BL BlankCHK
; 比较数据
MOV R2,#0x00002000
MOV R3,#0x40000000
MOV R4,#512
BL Compare
HALT B HALT
;******************************************************************************
; 名称:SelSector
; 功能:IAP操作扇区选择,命令代码50
; 入口参数:R2 起始扇区
; R3 终止扇区
; 出口参数:IAP返回值
; 说明:使用了R0、R1指向的缓冲区作为IAP参数传送缓冲区。
;******************************************************************************
SelSector
STMFD SP!,{R0-R7,LR}
LDR R0,=IAP_ParIn
LDR R1,=IAP_ParOut
MOV R4,#IAP_SELSECTOR ; 设置命令字
STR R4,[R0]
STR R2,[R0,#4] ; 参数设置,起始扇区
STR R3,[R0,#8] ; 终止扇区
ADR LR,SelSrExt
LDR R5,=IAP_Enter+1
BX R5
SelSrExt LDMFD SP!,{R0-R7,PC}
;******************************************************************************
; 名称:RamToFlash
; 功能:复制RAM的数据到FLASH,命令代码51
; 入口参数:R2 目标地址,即FLASH起始地址。以512字节为分界
; R3 源地址,即RAM地址。地址必须字对齐
; R4 复制字节个数,为512/1024/4096/8192
; 出口参数:IAP返回值
; 说明:使用了R0、R1指向的缓冲区作为IAP参数传送缓冲区。
; 在使用此程序前,要先选择操作扇区。
;******************************************************************************
RamToFlash
STMFD SP!,{R0-R7,LR}
LDR R0,=IAP_ParIn
LDR R1,=IAP_ParOut
MOV R5,#IAP_RAMTOFLASH ; 设置命令字
STR R5,[R0]
STR R2,[R0,#4] ; 参数设置,目标地址
STR R3,[R0,#8] ; 源地址
STR R4,[R0,#12] ; 操作字节数
LDR R4,=IAP_FCCLK
STR R4,[R0,#16] ; CCLK频率
ADR LR,RamTFExt
LDR R5,=IAP_Enter+1
BX R5
RamTFExt LDMFD SP!,{R0-R7,PC}
;******************************************************************************
; 名称:EraseSector
; 功能:扇区擦除,命令代码52
; 入口参数:R2 起始扇区
; R3 终止扇区
; 出口参数:IAP返回值
; 说明:使用了R0、R1指向的缓冲区作为IAP参数传送缓冲区。
; 在使用此程序前,要先选择操作扇区。
;******************************************************************************
EraseSector
STMFD SP!,{R0-R7,LR}
LDR R0,=IAP_ParIn
LDR R1,=IAP_ParOut
MOV R4,#IAP_ERASESECTOR ; 设置命令字
STR R4,[R0]
STR R2,[R0,#4] ; 参数设置,起始扇区
STR R3,[R0,#8] ; 终止扇区
LDR R4,=IAP_FCCLK
STR R4,[R0,#12] ; CCLK频率
ADR LR,EraseSrExt
LDR R5,=IAP_Enter+1
BX R5
EraseSrExt LDMFD SP!,{R0-R7,PC}
;******************************************************************************
; 名称:BlankCHK
; 功能:扇区查空,命令代码53
; 入口参数:R2 起始扇区
; R3 终止扇区
; 出口参数:IAP返回值
; 说明:使用了R0、R1指向的缓冲区作为IAP参数传送缓冲区。
;******************************************************************************
BlankCHK
STMFD SP!,{R0-R7,LR}
LDR R0,=IAP_ParIn
LDR R1,=IAP_ParOut
MOV R4,#IAP_BLANKCHK ; 设置命令字
STR R4,[R0]
STR R2,[R0,#4] ; 参数设置,起始扇区
STR R3,[R0,#8] ; 终止扇区
ADR LR,BlankCKExt
LDR R5,=IAP_Enter+1
BX R5
BlankCKExt LDMFD SP!,{R0-R7,PC}
;******************************************************************************
; 名称:ReadParID
; 功能:读取器件ID,命令代码54
; 入口参数:无
; 出口参数:IAP返回值
; 说明:使用了R0、R1指向的缓冲区作为IAP参数传送缓冲区。
;******************************************************************************
ReadParID
STMFD SP!,{R0-R7,LR}
LDR R0,=IAP_ParIn
LDR R1,=IAP_ParOut
MOV R4,#IAP_READPARTID ; 设置命令字
STR R4,[R0]
ADR LR,ReadPDExt
LDR R5,=IAP_Enter+1
BX R5
ReadPDExt LDMFD SP!,{R0-R7,PC}
;******************************************************************************
; 名称:BootCodeID
; 功能:读取boot代码版本号,命令代码55
; 入口参数:无
; 出口参数:IAP返回值
; 说明:使用了R0、R1指向的缓冲区作为IAP参数传送缓冲区。
;******************************************************************************
BootCodeID
STMFD SP!,{R0-R7,LR}
LDR R0,=IAP_ParIn
LDR R1,=IAP_ParOut
MOV R4,#IAP_BOOTCODEID ; 设置命令字
STR R4,[R0]
ADR LR,BootCDExt
LDR R5,=IAP_Enter+1
BX R5
BootCDExt LDMFD SP!,{R0-R7,PC}
;******************************************************************************
; 名称:Compare
; 功能:校验数据,命令代码56
; 入口参数:R2 目标地址,即RAM/FLASH起始地址。地址必须字对齐
; R3 源地址,即FLASH/RAM地址。地址必须字对齐
; R4 复制字节个数,必须能被4整除
; 出口参数:IAP返回值
; 说明:使用了R0、R1指向的缓冲区作为IAP参数传送缓冲区。
;******************************************************************************
Compare
STMFD SP!,{R0-R7,LR}
LDR R0,=IAP_ParIn
LDR R1,=IAP_ParOut
MOV R5,#IAP_COMPARE ; 设置命令字
STR R5,[R0]
STR R2,[R0,#4] ; 参数设置,目标地址
STR R3,[R0,#8] ; 源地址
STR R4,[R0,#12] ; 操作字节数
ADR LR,CompareExt
LDR R5,=IAP_Enter+1
BX R5
CompareExt LDMFD SP!,{R0-R7,PC}
END