⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 megabootloaderblips.asm

📁 butterfly avrisp for atmel atmega
💻 ASM
📖 第 1 页 / 共 3 页
字号:

L24: 	ldi 	R24,low(2*MYORG)
		ldi 	R25,high(2*MYORG)
		cp 		R26,R24 			; address < Boot Flash address(byte address) 0x3E00 ?
		cpc 	R27,R25
		brlo 	L20					; loop for all flash blocks up to the bootloader area
#endif
;===========================================

;=======
#ifdef EEPROM_ERASE_e	; this legacy code doesn't loop, doesn't work, isn't useful
; erase EEPROM
		ldi 	R26,low(E2END-1) 		; increment Chip Erase Counter located at address E2END-1
		ldi 	R27,high(E2END-1) 		; 
		movw 	R22,R26 			; Save Chip Erase Counter Address in R22
		
		ldi 	R17,1 				; read EEPROM
		rcall 	EepromTalk
		
		mov 	R24,R16 			; R24 = Chip Erase Counter low byte
		rcall 	EepromTalk
		mov 	R25,R16 			; R25 = Chip Erase Counter high byte
		adiw 	R24,1 				; counter ++
		out 	EEDR,R24 			; EEDR = R24 Chip Erase Counter low byte
		movw 	R26,R22 			; R26 = Chip Erase Counter Address
		
		ldi 	R17,6 				; write EEPROM
		rcall 	EepromTalk
		out 	EEDR,R25 			; EEDR = R25 Chip Erase Counter high byte
		rcall 	EepromTalk
		rjmp 	send_cr				; uartSend('\r')
#endif
;=======




;--- command: page write for byte-at-a-time mode
L28: 	cpi 	R16,'m' 			; else if(R16== 'm') Write page
		brne 	L34
		movw 	R30,R26 			; Z-pointer = address

; !!note: 'B' command shares this code too
L30:	ldi 	R17,5 				; SPMCR = 0x05 Write page
		OUTREG	SPMCSR,R17
		spm 					; Store program memory
		rcall	wait_spm
L32: 	rjmp 	send_cr 			; uartSend('\r')
				

;--- enter programming mode
L34:	cpi 	R16,'P' 			; else if(R16=='P') Enter programming mode
		breq 	L32 				; uartSend('\r')

		cpi 	R16,'L' 			; else if(R16=='L') Leave programming mode
		breq 	L32 				; uartSend('\r')

;--- Exit boot loader to user program
		cpi		R16, 'E'			; leave bootloader
		brne 	L36

		;ldi	R16,(1<<UTXC)	; not necessary per data sheet on TXC status but
		;OUTREG	USTAT,R16
		ldi 	R16,0x0D			; uartSend('\r')
 		rcall 	uartSend 			; uartSend(R16)
 		
L35:	INREG	R16,USTAT
		sbrs 	R16,UTXC 			; wait for char to have been transmitted (see Data Sheet on TXC bit)
		rjmp 	L35		
		rjmp	boot_r_0			; EXECUTE USER PROGRAM

L36:
;--- return programing type
		cpi 	R16,'p' 			; else if (R16=='p') Return programmer type
		brne 	L38

		ldi 	R16,'S' 			; uartSend('S') Serial
		rjmp 	L70 				; uartSend(R16)

;--- read program memory for byte-at-a-time mode
L38: 	cpi 	R16,'R' 			; else if(R16=='R') Read program memory
		brne 	L40

		movw 	R30,R26 			; Z-pointer <= address
.ifdef RAMPZ
		elpm 	R24,Z+ 				; read program memory LSB; store LSB in R24 and Z pointer ++
		elpm	R16,Z+ 				; read program memory MSB; store MSB in R16 and Z pointer ++
.else
		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 ++
.endif
		rcall 	uartSend 			; uartSend(R16) MSB

		movw 	R26,R30 			; address from Z register (incremented now)
		mov 	R16,R24 			; LSB stored in R16
		rjmp 	L70 				; uartSend(R16) LSB


;--- eeprom write for byte-at-a-time mode
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 read for byte-at-a-time mode
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:
;--- read fuse bits
#ifdef ENABLE_READFUSEANDLOCK 	
		cpi 	R16,'F' 			; else if(R16=='F') Read fuse bits
		brne 	L46

		clr 	R30 				; Z-pointer = 0000
		rjmp 	L50 				; rcall readFuseAndLock

;--- read lock bits
L46: 	cpi 	R16,'r' 			; else if(R16=='r') Read lock bits
		brne 	L48

		ldi 	R30,1 				; Z pointer = 0001
		rjmp 	L50 				; rcall readFuseAndLock

;--- read high fuse bits
L48: 	cpi 	R16,'N' 			; else if(R16=='N') Read high fuse bits
		brne 	L52
		ldi 	R30,3 				; Z-pointer = 0003

;--- read fuse and lock bits
L50: 	rcall 	readFuseAndLock
		rjmp	L70 				; uartSend(R16)
#endif

;--- return supported devices
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'))
#ifdef NONESUCH
		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
#endif

		cpi 	R16,'T' 			; 'T' = Select device type (ignored)
		brne 	L60



L56: 	rcall 	uartGet 			; R16 = uartGet()
; YOU CAN INSERT LEDs CODE HERE
		rjmp 	send_cr				; uartSend('\r')

;--- send return software id
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: 	
; Send ID string on uart from flash
.ifdef RAMPZ	; as on mega128
		ldi		R16,(1 << RAMPZ0)	; 128MB Flash
		out		RAMPZ,R16			; string is in 2nd 64K block
		elpm	R16,Z+	
.else
		lpm 	R16,Z+
.endif
		tst 	R16
		breq 	L72 				; branch is end of string ((Z) == 0)
		rcall 	uartSend 			; else send char
		rjmp 	L61

;--- send version
L62: 	cpi 	R16,'V' 			; else if (R16=='V') Return Software Version
		brne 	L64

		ldi 	R16,'1' 			; uartSend('1')
		rcall 	uartSend
		ldi 	R16,'2' 			; uartSend('2')
		rjmp 	L70 				; uartSend(R16)

;--- send signature bytes
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)

;;; Unsupported command received
cmdUnknown:
L66:	ldi	R16,'?' 			; else uartSend('?')
		rjmp 	L70 				; uartSend(R16)

;--- send cr
send_cr: 	ldi 	R16,13 				; uartSend('\r')

;--- send byte via uart

L70: 		rcall 	uartSend 			; uartSend(R16)
L72: 		rjmp 	b_main

#ifdef ENABLE_READFUSEANDLOCK
readFuseAndLock:
		clr 	R31 				; Z pointer high byte = 0
		ldi 	R24,9 				; SPMCR = 0x09
		WRITEPMCR R24 			; read fuse and lock
		lpm 	R16,Z 				; read program memory
		ret
#endif

; --- EEPROM I/O
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

; --- UART I/O

; ==== UART Send Byte
uartSend: 							; send R16
		INREG	R2,USTAT
		sbrs 	R2,UTXE 			; wait for empty transmit buffer (until UDRE==1)
		rjmp 	uartSend
		OUTREG 	UDATA,R16 			; UDR = R16, start transmission
		ret

; ==== UART Get Byte
uartGet:	
		INREG	R16,USTAT
		sbrs	R16,URXC 			; wait for incoming data (until RXC==1)
		rjmp 	uartGet
		INREG	R16,UDATA 			; return received data in R16
		ret

; --- Wait for previous SPM operation to finish 
;      then send SPM for RWWSRE
;      then do another SPM

; must preserve Carry bit
wait_spm:
		INREG 	R16,SPMCSR
		sbrc	R16,SPMEN		; skip if bit is clear
		rjmp	wait_spm
		ldi		R16,(1<<RWWSRE) | (1<<SPMEN) 
		OUTREG	SPMCSR,R16
		spm
		ret 


Soft_Id: 
	BOOTIDSTRING	; macro

; END OF CODE



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -