boot.inc
来自「用于DSP中FLASH的擦除和编写程序」· INC 代码 · 共 1,682 行 · 第 1/3 页
INC
1,682 行
STS D_DX,R16
LDS R16,D_Y
ANDI R16,0B00000111
STS D_DY,R16
LDS R16,D_Y
LSR R16
LSR R16
LSR R16
INC R16
STS D_DZ,R16
ELPM R16,Z+
PUSH ZL
PUSH ZH
PUSH R23
CLR R17
CLC
ROL R16
ROL R17
CLC
ROL R16
ROL R17
CLC
ROL R16
ROL R17
CLC
ROL R16
ROL R17
LDI ZL,LOW(BOOT_TABEN*2)
LDI ZH,HIGH(BOOT_TABEN*2)
ADD ZL,R16
ADC ZH,R17
RCALL BOOT_DISPCC
POP R23
POP ZH
POP ZL
LDS R16,D_Y
INC R16
STS D_Y,R16
DEC R23
BRNE BOOT_DISPES1
LDI R16,0
OUT RAMPZ,R16
RET
;*****************************************************
CRESET: ; 复位句柄
LDI R16,HIGH(RAMEND) ;SP SETUP
OUT SPH,R16
LDI R16,LOW(RAMEND)
OUT SPL,R16
LDI R16,0B11111111 ;PORTA CCONFIG
OUT DDRA,R16
LDI R16,0B11110110 ;PORTB CCONFIG
OUT DDRB, R16
SBI PORTB,0 ;
SBI PORTB,3 ;
SBI PORTB,5 ;IRC CTRL 1
CBI PORTB,6 ;MOTOR LITTLE
SBI PORTB,7 ;MOTOR BIG
LDI R16,0B11111111 ;PORTC CCONFIG
OUT DDRC,R16
LDI R16,0B00111111 ;PORTD CCONFIG
OUT DDRD,R16
LDI R16,0B00000111 ;PORTE CCONFIG
OUT DDRE,R16
LDI R16,0B00000000 ;PORTF CCONFIG
STS DDRF,R16
LDI R16,0B00011011 ;PORTG CONFIG
STS DDRG,R16
LDS R16,PORTG ;PORTG INITIAL
ORI R16,0B00010111
STS PORTG,R16
SBI PORTD,PT_EXDCLR
CBI PORTD,PT_EXDCNT
RCALL BOOT_LCDBL_ON
RCALL BOOT_LCD_RST
LDI R16,100
RCALL BOOT_DELAY
RCALL BOOT_LCDINIT
RCALL BOOT_U0INIT
RCALL BOOT_DI_OFF
CBI PORTD,PT_EXDCLR
CLI
;RJMP DRESET
CALL BOOT_KEY
LDS R16,KEYV
CPI R16,32
BREQ DRESET
RCALL BOOT_EEPROM_RD
CPI R16,0X55
BREQ DRESET
JMP ERESET
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DRESET: CLI
CALL BOOT_DI_OFF
LDI ZL,LOW(BOOT_TC_update*2)
LDI ZH,HIGH(BOOT_TC_update*2)
LDI R21,2
LDI R22,22
LDI R23,4
RCALL BOOT_DISPCS
RCALL DISP_FVER
RCALL DISP_PVER
RCALL DISP_MODEL
LDI ZL,LOW(BOOT_TE_3D*2)
LDI ZH,HIGH(BOOT_TE_3D*2)
LDI R21,5
LDI R22,20
LDI R23,12
RCALL BOOT_DISPES
PRGM00: RCALL BOOT_BELL
RCALL BOOT_SHOW_CRLF
RCALL BOOT_SHOW_VID
RCALL BOOT_SHOW_CRLF
RCALL BOOT_SHOW_DID
RCALL BOOT_SHOW_CRLF
BOOTM21:
RCALL BOOT_GETC
CPI R16,0X56 ;'V'
BRNE BOOTM22
RCALL BOOT_SHOW_VID
RCALL BOOT_SHOW_CRLF
RJMP BOOTM21
BOOTM22:
CPI R16,0X44 ;'D'
BRNE BOOTM23
RCALL BOOT_SHOW_DID
RCALL BOOT_SHOW_CRLF
RJMP BOOTM21
BOOTM23:
CPI R16,0X46 ;'F'
BRNE BOOTM24
RCALL BOOT_SHOW_FVER
RCALL BOOT_SHOW_CRLF
RJMP BOOTM21
BOOTM24:
CPI R16,0X50 ;'P'
BRNE BOOTM25
RCALL BOOT_SHOW_PVER
RCALL BOOT_SHOW_CRLF
RJMP BOOTM21
BOOTM25:
CPI R16,0X49 ;'I' IAP
BRNE BOOTM26
LDI R16,0X49 ;
RCALL BOOT_PUTC
LDI R16,0X55
RCALL BOOT_EEPROM_WR
LDI R16,100
RCALL BOOT_DELAY
LDI ZL,LOW(BOOT_TC_update_MIDL*2)
LDI ZH,HIGH(BOOT_TC_update_MIDL*2)
LDI R21,2
LDI R22,20
LDI R23,6
RCALL BOOT_DISPCS
LDI R16,0
STS TEMP0,R16
STS TEMP1,R16
RCALL IAP
RJMP BOOTM99
BOOTM26: LDI R16,0X3F ; ?
RCALL BOOT_PUTC
RCALL BOOT_SHOW_CRLF
RJMP BOOTM21
BOOTM99: LDI R16,0
OUT RAMPZ,R16
LDI R16,0XAA
RCALL BOOT_EEPROM_WR
LDI R16,0X45 ; E
RCALL BOOT_PUTC
LDI ZL,LOW(BOOT_TE_3E*2)
LDI ZH,HIGH(BOOT_TE_3E*2)
LDI R21,5
LDI R22,20
LDI R23,12
RCALL BOOT_DISPES
RCALL DISP_NEWPVER
LDI ZL,LOW(BOOT_TC_update_OK*2)
LDI ZH,HIGH(BOOT_TC_update_OK*2)
LDI R21,2
LDI R22,16
LDI R23,8
RCALL BOOT_DISPCS
RCALL BOOT_BELL
RJMP PC
;-----------------------------------------
IAP: CLI
LDI R16,0X0
OUT RAMPZ,R16
CLR XH
CLR XL
IAP2: LDI YH,HIGH(0X700)
LDI YL,LOW(0X700)
LDI R17,0
IAP3:
LDI R16,0XFF
ST Y+,R16
DEC R17
BREQ IAP3
LDI R16,16
MOV R15,R16
LDI ZH,HIGH(0X700)
LDI ZL,LOW(0X700)
IAP5:
PUSH ZH
PUSH ZL
RCALL RDHEX
LDI YH,HIGH(0X900)
LDI YL,LOW(0X900)
POP ZL
POP ZH
LD R16,Y+
LD R8,Y+
LD R9,Y+
LD R10,Y+
LD R11,Y+
MOV R16,R11
CPI R16,1
BRNE IAP6
RJMP IAP99
IAP6:
LD R16,Y+
ST Z+,R16
DEC R8
BRNE IAP6
DEC R15
BREQ IAP9
RJMP IAP5
IAP9:
MOV ZH,XL
CLR ZL
OUT RAMPZ,XH
LDI YH,HIGH(0X700)
LDI YL,LOW(0X700)
RCALL WRITE_PAGE
ADIW XH:XL,1
//LDS R16,TEMP1
//CPI R16,10
//BRSH IAP10
//INC R16
//STS TEMP1,R16
//RJMP IAP89
IAP10: //LDI R16,0
//STS TEMP1,R16
LDS R16,TEMP0
CPI R16,12
BRLO IAP20
LDI R16,0
STS TEMP0,R16
IAP20: INC R16
STS TEMP0,R16
LDI ZL,LOW(BOOT_TE_3D*2)
LDI ZH,HIGH(BOOT_TE_3D*2)
LDI R21,5
LDI R22,20
LDI R23,12
RCALL BOOT_DISPES
IAP21: LDI ZL,LOW(BOOT_TE_3E*2)
LDI ZH,HIGH(BOOT_TE_3E*2)
LDI R21,5
LDI R22,20
LDS R23,TEMP0
RCALL BOOT_DISPES
IAP89: RJMP IAP2
IAP99:
MOV ZH,XL
CLR ZL
OUT RAMPZ,XH
LDI YH,HIGH(0X700)
LDI YL,LOW(0X700)
RCALL WRITE_PAGE
RET
;--------------------------------------------
RDHEX:
RCALL CLRBM
RDHEX1: LDI R16,0X43 ;'C'
RCALL BOOT_PUTC
RDHEX2: CLR R21 ;RECHEVE
LDI YH,HIGH(0X800)
LDI YL,LOW(0X800)
RDHEX3: RCALL BOOT_GETC
ST Y+,R16
INC R21
CPI R16,0XA
BREQ RDHEX4
RJMP RDHEX3
RDHEX4:
;2ASI TO 1 BIN
LDI YH,HIGH(0X800)
LDI YL,LOW(0X800)
LDI ZH,HIGH(0X900)
LDI ZL,LOW(0X900)
LD R16,Z+
LD R16,Y+
CPI R16,0X3A
BREQ RDHEX5
RJMP RDHEX21
RDHEX5:
LD R16,Y+
CPI R16,0XD
BREQ RDHEX8
RCALL HEXTOBIN
BRTC RDHEX6
RJMP RDHEX21
RDHEX6:
MOV R17,R16
LD R16,Y+
CPI R16,0XD
BREQ RDHEX8
RCALL HEXTOBIN
BRTC RDHEX7
RJMP RDHEX21
RDHEX7:
SWAP R17
ADD R16,R17
ST Z+,R16
RJMP RDHEX5
RDHEX8:
DEC R21
DEC R21
DEC R21
LSR R21
LDI ZH,HIGH(0X901) ;CHECK SUM
LDI ZL,LOW(0X901)
CLR R17
RDHEX9:
LD R16,Z+
ADD R17,R16
DEC R21
BRNE RDHEX9
CPI R17,0
BREQ RDHEX10
RJMP RDHEX21
RDHEX10:
RET
RDHEX21:
RCALL CLRBM
LDI R16,0X52 ; 'R' REPEAT
RCALL BOOT_PUTC
RJMP RDHEX2
;----------------------------------------
CLRBM: LDI YH,HIGH(0X800)
LDI YL,LOW(0X800)
LDI R17,0
CLRBM1:
LDI R16,0
ST Y+,R16
DEC R17
BREQ CLRBM1
LDI YH,HIGH(0X900)
LDI YL,LOW(0X900)
LDI R17,0
CLRBM2:
LDI R16,0
ST Y+,R16
DEC R17
BREQ CLRBM2
RET
;-----------------------------------------
HEXTOBIN:
CLT
CPI R16,0X30
BRSH HEXTOBIN1
SET
RJMP HEXTOBIN9
HEXTOBIN1:
CPI R16,0X3A
BRSH HEXTOBIN2
CLT
SUBI R16,0X30
RJMP HEXTOBIN9
HEXTOBIN2:
CPI R16,0X41
BRSH HEXTOBIN4
SET
RJMP HEXTOBIN9
HEXTOBIN4:
CPI R16,0X47
BRLO HEXTOBIN5
SET
RJMP HEXTOBIN9
HEXTOBIN5:
CLT
SUBI R16,0X37
HEXTOBIN9:
RET
;*******************************************************
;- - - - - - - - - - - - - - - - - - - - - - - - -
; Y 指针指向RAM 的第一个数据单元
;Z 指针指向Flash 的第一个数据单元
;- 本例程没有包括错误处理
;- 该程序必须放置于Boot 区( 至少Do_spm 子程序是如此)
; 在自编程过程中( 页擦除和页写操作) 只能读访问NRWW 区的代码
;- 使用的寄存器:r0、r1、temp1 (r16)、temp2 (r17)、looplo (r24)、
; loophi (r25)、spmcrval (r20)
; 在程序中不包括寄存器内容的保护和恢复
; 在牺牲代码大小的情况下可以优化寄存器的使用
;- 假设中断向量表位于Boot loader 区, 或者中断被禁止。
;PAGESIZEB 是以字节为单位的页大小,不是以字为单位
.equ PAGESIZEB = PAGESIZE*2
Write_page:
; 页擦除
ldi r20,(1<<PGERS) | (1<<SPMEN)
RCALL Do_spm
; 重新使能RWW 区
ldi r20,(1<<ASRE) | (1<<SPMEN)
RCALL Do_spm
; 将数据从RAM 转移到Flash 页缓冲区
ldi r24, low(PAGESIZEB) ; 初始化循环变量
ldi r25, high(PAGESIZEB) ;PAGESIZEB<=256 时不需要此操作
Wrloop:
ld r0, Y+
ld r1, Y+
ldi r20, (1<<SPMEN)
RCALL Do_spm
adiw ZH:ZL, 2
sbiw r25:r24, 2 ;PAGESIZEB<=256 时请使用subi
brne Wrloop
; execute page write
subi ZL, low(PAGESIZEB) ; 复位指针
sbci ZH, high(PAGESIZEB) ;PAGESIZEB<=256 时不需要此操作
ldi r20, (1<<PGWRT) | (1<<SPMEN)
RCALL Do_spm
; 重新使能RWW 区
ldi r20, (1<<ASRE) | (1<<SPMEN)
RCALL Do_spm
; 读回数据并检查,为可选操作
ldi r24, low(PAGESIZEB) ; 初始化循环变量
ldi r25, high(PAGESIZEB) ;PAGESIZEB<=256 时不需要此操作
subi YL, low(PAGESIZEB) ; 复位指针
sbci YH, high(PAGESIZEB)
Rdloop:
Elpm r0, Z+
ld r1, Y+
cpse r0, r1
jmp Return
sbiw r25:r24, 1 ;PAGESIZEB<=256 时请使用subi
brne Rdloop
; 返回到RWW 区
; 确保RWW 区已经可以安全读取
Return:
LDS r16,SPMCR
sbrs r16,ASB ; 若RWWSB 为"1",说明RWW 区还没有准备好
ret
;重新使能RWW 区
ldi r20, (1<<ASRE) | (1<<SPMEN)
RCALL Do_spm
rjmp Return
Do_spm:
; 检查先前的SPM 操作是否已经完成
Wait_spm:
LDS r16, SPMCR
sbrc r16, SPMEN
rjmp Wait_spm
; 输入:r20 决定了SPM 操作
; 禁止中断,保存状态标志
in r17, SREG
cli
; 确保没有EEPROM 写操作
Wait_ee:
sbic EECR, EEWE
rjmp Wait_ee
; SPM 时间序列
STS SPMCR, r20
spm
; 恢复SREG ( 如果中断原本是使能的,则使能中断)
out SREG, r17
ret
;---------------------------------------------
.include "boot_tab.inc"
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?