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

📄 yampp7_boot.asm

📁 yampp 7 USB firmware v 2.44 checked, working, latest
💻 ASM
字号:

/*
  Copyright (C) 2002 Jesper Hansen <jesperh@telia.com>.

  This file is part of the yampp system.

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software Foundation, 
  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/


/*

		yampp-7 USB Bootloader
		
		Jesper Hansen	2002-06-20
		Romuald Bialy	2003-04-05
		
		AVR-GCC 3.3

		Enables the yampp-7 to download new code via USB.

		
				
		Rev.	Date		Name		Comment
		------	----------	-----		-------------------------------
		1.0	2002-06-20	jesper		Initial version
		2.1	2003-04-05	MIS		added exit from bootloader after STOP keypress
		3.0	2004-01-18  	MIS		added compatibility with Mega162 CPU (enabling RWW section)
		5.0	2004-02-13  	MIS		special version for M162 and load at address 0x3F00.
							this make additionally 768 bytes of free space for main code
		6.0	2005-03-21	MIS		added LED (backlight) blinking during bootloader active

		

*/

#define __ASSEMBLER__ 1
#define __SFR_OFFSET 0

#include        "avr/io.h"


	.org	0	; actually this will be at 0x1F80 (word address)
	
; SPM Control/Status Register bits
#define BLBSET 	3
#define PGWRT 	2	
#define PGERS 	1
#define SPMEN 	0	 


#define USB_PORT	PORTD
#define USB_TXRDY	PD3
#define USB_RXRDY	PD2
#define USB_ADDR	0x8000

;
; version number to report to USB loader program or to YL
;
#define VERSION	'6'


;
; start of code
;

boot:
	;
	; init I/O pins
	;
		sbi	PORTD,PD4		; needed for compatibility with main firmware
						; and detection of bootloader version
		ser	r25
		out	PORTB,r25		; enable all pullups
		out	PORTD,r25		; enable all pullups
		cbi	USB_PORT-1,USB_RXRDY	; set pins as inputs
		cbi	USB_PORT-1,USB_TXRDY

	; check for boot enable
	; run the application if PD4 or PD5 (two top buttons) 
	; is high (not pressed)

		sbic 	PIND,PD4		; skip if bit is low
		rjmp 	jump_app		; pin was high

		; test next pin

		sbic 	PIND,PD5		; skip if bit is high
		rjmp	jump_app		; pin was high, go to main app
		rjmp	do_boot			; pin was low, goto boot loader


;
; send an ACK to the USB host - moved here for code size decrease
;		
usb_ack:
		ldi	r24,'A'
		;fall trought

;
; send the byte in r24 over the USB link
;
usb_putbyte:
		sbic 	PIND,USB_TXRDY			; while flag is set
 		rjmp 	usb_putbyte			; wait for bit to be cleared
 		st	Y,r24
		ret


	;
	; bootloader code
	;

	.org 0x20			; fixed offset so we can jump here from application
	
do_boot:	
		cli				; no interrupts, thank you

	; 
	; setup the stack
	;
		ldi 	r16, 0x04	 	; stack at 0x0404 (anywhere high address in internal RAM)
		out 	SPL, r16
		out 	SPH, r16

	;
	; enable external memory
	;
		ldi	r25,(1<<SRE) | (1<<SRW10)
		out	MCUCR,r25

	;
	; init rest of I/O pins
	;
		sbi	DDRB,PB0			; LED (backlight) pin as output
		sbi	DDRB,PB1			; set RST as output and high
  		ldi 	r29,hi8(USB_ADDR)
 		ldi 	r28,lo8(USB_ADDR)		; USB adress in Y (for whole bootloader code)


	;
	; wait for USB start tag
	;
do_boot_2:
		clr	r30			; clear LED blink counter
		clr	r31
do_boot_3:
		sbiw	r30,1			; decrament blink counter
		brne	do_boot_4
		rcall	led_blink
do_boot_4:
		sbis 	PIND,PD1		; skip if STOP key not pressed
		rjmp	jump_app		; exit from bootloader

;
; check RXF pin to see if the USB chip
; have some data to send us
;
		sbic 	PIND,USB_RXRDY		; if flag is clear, the usb have an y data, skip next
		rjmp	do_boot_3		; no, loop until something

		rcall	usb_getbyte1		; get the byte

		cpi	r24,'?'			; check for status command
		breq	tell_version
		
		cpi	r24,'!'			; check for download command
		breq	do_download
		
		cpi	r24,'E'		
		brne	do_boot_3		; check if "ESC" sequence

		rcall	usb_getbyte
		cpi	r24,'S'
		brne	do_boot_2

		rcall	usb_getbyte
		cpi	r24,'C'
		brne	do_boot_2


	;
	; jump to application
	;
jump_app:
		jmp	0x0000			; Jump to Application start.			

		
tell_version:

	;
	; send version info over USB
	;
		ldi		r24,'y'
		rcall	usb_putbyte
		ldi		r24,'b'
		rcall	usb_putbyte
		ldi		r24,'o'
		rcall	usb_putbyte
;		ldi		r24,'o'		; not needed second load of 'o'...
		rcall	usb_putbyte
		ldi		r24,'t'
		rcall	usb_putbyte
		
		ldi		r24,VERSION
		rcall	usb_putbyte		; send the version number
		
		rjmp	do_boot_2

	
do_download:	
	;
	; check for "AB" tag
	;
		rcall	usb_getbyte
		cpi	r24,'A'
		brne	do_download

		rcall	usb_getbyte
		cpi	r24,'B'
		brne	do_download
	;
	; tag received, get data length (in 128 byte blocks)
	;
		rcall	usb_getbyte
		mov	r10,r24				; save length in r10
		clr	r8				; block counter
boot_loop:
	;
	;	read a USB 128 byte block of data to internal SRAM
	;	starting at address 0x100
	;
		rcall	usb_ack				; start transmission

		ldi	r31,hi8(0x100)
		ldi	r30,lo8(0x100)			; pointer in Z
		
		ldi	r26,lo8(128)			; count in X

usb_gb2:
		rcall	usb_getbyte			; read byte from USB
		st	Z+,r24				; store in ram

		dec	r26				; dec count
		brne	usb_gb2				; loop


	;
	; program the block 
	;
		rcall	program_block
				
		inc	r8				; inc block number				
				
		dec	r10				; dec number of blocks
		brne	boot_loop			; keep going if not 0


	; send the last ack
		rcall	usb_ack		

	; back to loop
		rjmp	do_boot_2



;
;	read an USB byte to r25/r24
;
usb_getbyte:
		sbic 	PIND,USB_RXRDY			; while flag is set
 		rjmp 	usb_getbyte			; wait for bit to be cleared
usb_getbyte1:	ld	r24,Y
		ret
	
;*******************************************

;
; program the block in r8 from SRAM at 0x100
;
program_block:

		mov	r31,r8
		clr	r30
		lsr	r31			; shift page number down one bit 
		ror	r30
		
		
		movw	r4,r30			; save page pointer

	; erase the page

		ldi	r18,(1<<PGERS) | (1<<SPMEN)
		rcall	do_spm


	; fill buffer with data
	; page number is already set as the address 
	; that the temp buffer need

		ldi	r27,hi8(0x100)		; X is pointer to RAM
		ldi	r26,lo8(0x100)
		
		ldi	r17,64			; number of words
prog_1:		
		ld	r0,X+
		ld	r1,X+
		ldi	r18,(1<<SPMEN)
		rcall	do_spm

		adiw	r30,2
		
		dec	r17			; dec word count
		brne	prog_1
		
		movw	r30,r4			; restore page pointer

	; write the page	

		ldi	r18,(1<<PGWRT) | (1<<SPMEN)
		rcall	do_spm


	; re-enable the RWW section
rww_ena:
		ldi	r18,(1<<RWWSRE) | (1<<SPMEN)
		rcall	do_spm

		in	r18, SPMCR
		sbrc 	r18, RWWSB 		; If RWWSB is set, the RWW section is not ready yet
		rjmp	rww_ena			; continue trying enable RWW section

		;fall trought to blinking proc

led_blink:	ldi	r25,1
		in	r24,PORTB
		eor	r24,r25			; change LED output state
		out	PORTB,r24
		ret


	
;
; perform a SPM operation
;	
do_spm: 	; check for previous SPM complete 
		in 	r16, SPMCR		; get status register
		sbrc 	r16, SPMEN		; skip next if SPM ready
		rjmp 	do_spm			; else loop and wait for it

wait_ee:	; check that no EEPROM write access is present
		sbic 	EECR, EEWE 		; skip next if EEPROM ready
		rjmp 	wait_ee			; else loop and wait for it
	
		out 	SPMCR, r18 		; set the SPM mode
		spm	 			; do the magic boogie
		ret				; done


;
; end of file
;

⌨️ 快捷键说明

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