📄 boot2.asm
字号:
; 读program memory
;****************************************************
L38: cpi R16,'R' ; else if(R16=='R') Read program memory
brne L40
movw R30,R26 ; Z-pointer <= address
lpm R24,Z+ ; read program memory LSB; store LSB in R24 and Z pointer ++
lpm R16,Z+ ; read program memory MSB; store MSB in R16 and Z pointer ++
rcall uartSend ; uartSend(R16) MSB
movw R26,R30 ; address += 2
mov R16,R24 ; LSB stored in R16
rjmp L70 ; uartSend(R16) LSB
;****************************************************
; 写EEPROM
;****************************************************
L40: cpi R16,'D' ; else if (R16=='D') Write data to EEPROM
brne L42
rcall uartGet
out EEDR,R16 ; EEDR = uartGet()
ldi R17,6 ; write EEPROM
rcall EepromTalk
rjmp Send_CR ; uartSend('\r')
;****************************************************
; 读EEPROM
;****************************************************
L42: cpi R16,'d' ; else if (R16=='d') Read data from EEPROM
brne L44
ldi R17,1 ; read EEPROM
rcall EepromTalk ; R16 = EEPROM data
rjmp L70 ; uartSend(R16)
;****************************************************
; 读熔断位和锁定位
;****************************************************
L44: cpi R16,'F' ; else if(R16=='F') Read fuse bits
brne L46
clr R30 ; Z-pointer = 0000
rjmp L50 ; rcall readFuseAndLock
;****************************************************
; 读锁定位
;****************************************************
L46: cpi R16,'r' ; else if(R16=='r') Read lock bits
brne L48
ldi R30,1 ; Z pointer = 0001
rjmp L50 ; rcall readFuseAndLock
;****************************************************
; 读熔断位高位
;****************************************************
L48: cpi R16,'N' ; else if(R16=='N') Read high fuse bits
brne L52
ldi R30,3 ; Z-pointer = 0003
;****************************************************
; 读熔断位和锁定位
;****************************************************
L50: rcall readFuseAndLock
rjmp L70 ; uartSend(R16)
;****************************************************
; 返回支持的芯片
;****************************************************
L52: cpi R16,'t' ; else if(R16=='t') Return supported devices code
brne L54
ldi R16,DT ; Device Type
rcall uartSend ; uartSend(DT) send Device Type
clr R16
rjmp L70 ; uartSend(0)
;--- grab another char and ignore
L54: ; else if ((R16=='l')||(R16=='x')||(R16=='y')||(R16=='T'))
cpi R16,'l' ; 'l' = Write Boot Loader lockbits
breq L56
cpi R16,'x' ; 'x' = Set LED
breq L56
cpi R16,'y' ; 'y' = Clear LED
breq L56
cpi R16,'T' ; 'T' = Select device type
brne L60
L56: rcall uartGet ; R16 = uartGet()
; YOU CAN INSERT LEDs CODE HERE
rjmp Send_CR ; uartSend('\r')
;********************************************************
;* 返回一个7字节ASCII字符串说明编程器类型,我的为"AVRZLM8" :)
;********************************************************
L60: cpi R16,'S' ; else if (R16=='S') Return software identifier
brne L62
Boot_ID: ldi R30,low(2*Soft_ID)
ldi R31,high(2*Soft_ID)
L61: lpm R16,Z+
tst R16
breq L72 ; branch is end of string ((Z) == 0)
rcall uartSend ; else send char
rjmp L61
;****************************************************
;* 发送两个字节的版本信息
;****************************************************
L62: cpi R16,'V' ; else if (R16=='V') Return Software Version
brne L64
ldi R16,'1' ; uartSend('1')
rcall uartSend
ldi R16,'3' ; uartSend('2')
rjmp L70 ; uartSend(R16)
;****************************************************
;* 发送电子标签
;****************************************************
L64: cpi R16,'s' ; else if (R16=='s') Return Signature Byte
brne L66
ldi R16,SB1 ; uartSend(SB1) Signature Byte 1
rcall uartSend
ldi R16,SB2 ; uartSend(SB2) Signature Byte 2
rcall uartSend
ldi R16,SB3 ; uartSend(SB3) Signature Byte 3
rjmp L70 ; uartSend(R16)
L66: ldi R16,'?' ; else uartSend('?')
rjmp L70 ; uartSend(R16)
;****************************************************
;* 发送一个“回车”字符(CR)
;****************************************************
Send_CR: ldi R16,13 ; uartSend('\r')
;****************************************************
;* 发送一个Ascii字符
;****************************************************
L70: rcall uartSend ; uartSend(R16)
L72: rjmp Boot_Main
readFuseAndLock:
clr R31 ; Z pointer high byte = 0
ldi R24,9 ; SPMCR = 0x09
out SPMCR,R24 ; read fuse and lock
lpm R16,Z ; read program memory
ret
EepromTalk: ; if R17 == 6 then Write, if R17 == 1 then Read
out EEARL,R26 ; EEARL = address low
out EEARH,R27 ; EEARH = address high
adiw R26,1 ; address++
sbrc R17,1 ; skip if R17 == 1 (read Eeprom)
sbi EECR,EEMWE ; EEMWE = 1 (write Eeprom)
out EECR,R17 ; EECR = R17 (6 write, 1 read)
L90: sbic EECR,EEWE ; wait until EEWE == 0
rjmp L90
in R16,EEDR ; R16 = EEDR
ret
uartSend: ; send R16
sbis UCSRA,UDRE ; wait for empty transmit buffer (until UDRE==1)
rjmp uartSend
out UDR,R16 ; UDR = R16, start transmission
ret
uartGet: sbis UCSRA,RXC ; wait for incoming data (until RXC==1)
rjmp uartGet
in R16,UDR ; return received data in R16
ret
;****************************************************
;* 关键是这个子程序!!
;* Design Note #032上的程序,是为写的,在上不能正常运行。
;* 主要问题是在页写和擦除以后,不能再重新访问RWW。
;* 现在以改正这个bug!
;****************************************************
wait_spm: in R16,SPMCR
sbrc R16,SPMEN
rjmp wait_spm
ldi R16,(1<<RWWSRE) | (1<<SPMEN)
out SPMCR,R16
spm
ret
Soft_ID: .DB "AVRZLM8", 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -