The AVR Assembler Site

HOME
AVR ASM TUTOR
ASM FORUM
AVR BEGINNERS NET
TUTORIAL #2
MUL & DIV
FAST MUL & DIV
16 BIT MUL
16 BIT ADD & SUB
32 BIT MATH
16 BIT MATH
16 BIT DIV
24 BIT DIV
32 BIT DIV
FLOAT MATH
SQRT16
BCD CONVERSIONS
16 BIT BCD
DEC TO ASCII
INTEGER TO ASCII
HEX TO ASCII
MOVING AVG
FAST FOURIER
BLOCK COPY
LOAD PROG MEM
EPROM STORAGE
SERIAL EPROM
AT45 DATAFLASH
FLASH CARD
VFX SMIL
VFX MEM
BUBBLE SORT
CRC CHECK
XMODEM REC
UART 304
UART 305
UART 128
UART BUFF
USB TO RS232
AVR ISP
ISP 2313
ISP 1200
AVR SPI
I2C 300
I2C 302
I2C TWI26
I2C/TWI 128
I2C/TWI AT8
DALLAS-1W
DALLAS CRC
ETHERNET DRIVER
TEA PROTOCOL
ADC
10 BIT ADC
CHEAP ADC
PRECISION 8 BIT ADC
THERMOMETER
INFARED DECODER
LCD DRIVER FOR HD44xxx
LCD DRIVER FOR HD44780
LCD DRIVER FOR HD44780 #2
4x4 KEYPAD
KEYPAD LED MUX
AT/PS2 KEYBOARD
AT KEYBOARD
PS2 KEYBOARD
MEGA 8 BOOTLOADER
BOOTLOADER
ALARM CLOCK
REAL TIME CLOCK
90 DAY TIMER
DELAY ROUTINE
CALLER ID
DTMF GENERATOR
6 CHAN PWM
PWM 10K
ENCODER
STH-11
ATMEL CORP
AVR BUTTERFLY
AVR BOOK

MEGA 8 BOOTLOADER

                                    ;----------------------------------------------------------------------------------------
                                    ;
                                    ;	Program:	Bootloader_Mega8.asm 
                                    ;
                                    ;	Writer:		Herbert Dingfelder, DL5NEG
                                    ;				for contact information visit WWW.DL5NEG.DE
                                    ;
                                    ;	Based on:	AVR-Freaks Design Note #32
                                    ;
                                    ;	Function:	Bootloader for ATmega8, works via the UART with the normal 
                                    ;				AVRProg PC-Software
                                    ;
                                    ;	Hardware:	ATmega8 with a 7.3728MHz crystal
                                    ;
                                    ;	History:	
                                    ;
                                    ;	13.07.2004	- Source code adapted for Mega8, assembles without errors
                                    ;
                                    ;	15.07.2004	- Used crystal is not 7.3 but 3.686 MHz -> UART setting adapted
                                    ;				- Red LED on PORTB 0 is switched on within the boot section, 
                                    ;				  tested in Hardware and works -> processor starts correctly 
                                    ;				  within the boot section
                                    ;
                                    ;	18.07.2004	- Problem how to download the bootloader is solved: Simply use
                                    ;				  the AVRProg in the "mega8" mode, not in "mega8boot" mode.
                                    ;				  Since the Intel-Hex Format contains the address for the code
                                    ;				  in each line, the programmers recognizes that the code has to
                                    ;				  go to the bootrom part of the flash (provided that the
                                    ;				  ".org MY_BOOTSTART" is put at the beginning of the source code)
                                    ;				- UART communication between bootloader and host PC works
                                    ;				  (echo mode and character recognition tested and works)
                                    ;				- Crystal changed to 7.3728MHz in an attempt to fight "flushing"
                                    ;				  problems in AVRProg (without success), UART setting adapted
                                    ;				- AVRProg is able to read the flash correctly (tested, works)
                                    ;				- Reading and writing to EEPROM on host commands 'D' and 'd' works.
                                    ;				- Flash erase did not work in the NRWR section (the last 1024
                                    ;				  words of the flash) The original version from DesignNote #32
                                    ;				  was for ATmega163 which does not have  RWR/NRWR sections.
                                    ;				  Problem solved by implementing the wait_for_spm function that
                                    ;				  makes sure that a new SPM does only start when the previous one
                                    ;				  is completed. (tested, works now)
                                    ;				- function to reenable the RWW section implemented ->
                                    ;				  loading data into the application section tested and works fine
                                    ;				  (Still some problems with sync on the interface between AVRProg
                                    ;				  and the boot loader, messagebox "flushing" appears, fuse bits are
                                    ;				  read differently many times and software download needs to be
                                    ;				  started twice sometimes. As it is known that AVRProg is very sensible
                                    ;				  command/answer sync, this does not point towards real bootloader problems.
                                    ;				  It has to be tracked on the interface.)
                                    ;				  -> Good enough to work with temporarily, Version 1.0 released.
                                    ;				- Startup-function implemented for 10 second wait after power-on. If
                                    ;				  no ASCII(27) is received via UART within that time, the application starts.
                                    ;				  If the application section is empty (all cells are $FF) e.g. directly
                                    ;				  after uploading the bootloader itself, then software will wait forever
                                    ;				  for a ESC via the UART to start the bootloader software
                                    ;				  (while waiting for the ESC the LED blinks)
                                    ;				- Function pause implemented for delays in steps of 10ms (tested works)
                                    ;				- Command 'E' implemented for leaving the bootloader mode and start the 
                                    ;				  application
                                    ;				- With that entry end exit function the bootloader is fully usable, starting
                                    ;				  the downloaded application is tested and works perfectly
                                    ;				  -> Version 1.1 released
                                    ;				- Still known problem: the above mentioned sync problem in combination
                                    ;				  with AVRProg have to be identified and solved. 
                                    ;				- Only 2 Words are left in the bootloader memory. If Bugfixing needs more,
                                    ;				  the erease counter within the EEPROM can be skipped
                                    ;
                                    ;	24.07.2004	- Debug Session with Andy, DG9NDZ to find why AVRProg 1.37 still has some
                                    ;				  problems with the bootloader, especially in the "Advanced" Window. 		
                                    ;				  - Command 'v' for Hardware Version was not implemented -> fixed
                                    ;				  - Command ':' for tranparent command setting was not implemented
                                    ;					-> is now implemented in simple version, always returning \0
                                    ;				    By monitoring the PC/AVR interface it was found that AVRProg1.37 does 
                                    ;				    not use the defined commands r/F/N for reading the lock and fuse bits,
                                    ;				    but uses the universal command ':' to send the programming instructions
                                    ;				    directly. Additionally the calibration byte is read by the ':' command.
                                    ;				  - Command 'b' is send by AVRProg1.37 but is not implemented. It was found that
                                    ;				    it is fatal for the programming mode to implement 'b' to return 'Y'.
                                    ;				    To simply leave it out (returns ? for unknow command) works perfectly.
                                    ;
                                    ;	25.07.2004	- To implement all improvements found on 24.07.2004 without skipping lots of
                                    ;				  of other code made it necessary to increase the boot loader size to 512words
                                    ;				  (=1kByte). Code adapted.
                                    ;				- Command ':' enlarged to map r/F/N functionality
                                    ;				- Tested, current status: Works well in AVRProg both for flash reading and writing
                                    ;				  and also in the Advance window the lock and fuse bits are display correctly.
                                    ;				  Only week point remaining to press "write" in advance window, that causes a
                                    ;				  loose of sync between host and bootloader. No harm is done to the target device.
                                    ;				  -> Version 1.2 released.
                                    ;
                                    ;	26.07.2004	- Monitoring of interface from host reveals the root cause of the sync problem when
                                    ;				  writing the the lock and fuse bits. AVRProg1.37 uses the "new universal command"
                                    ;				  which is "." + 4 data bytes. This command was not implemented. As changing the 
                                    ;				  fuse bits is dangerous when the device is remote (one could lock himself out
                                    ;				  forever), the command is now implemented simply to ignore the inputs but correctly
                                    ;				  serve the interface to the host to avoid sync problems. Tested and works perfectly.
                                    ;				  -> Version 1.3 released
                                    ;
                                    ;	07.04.2005	- The code contained the "call" command, which is not supported by ATmega8. Obviously
                                    ;				  the AVR implementation is in a way that lets the software work anyhow. All "call"
                                    ;				  commands are now replaced by the supported "rcall" command now.
                                    ;				- The definition of E2END was missing in the mega8 definition file of the old 
                                    ;				  assembler, so it was included within this source file. Now the definition is
                                    ;				  available in the include file, so it is taken out of this file.
                                    ;				- Intended Assembler Version is now:
                                    ;				  AVR macro assembler 2.0.28 (build 121 Jan 11 2005 10:28:51)
                                    ;				- Configuration block implemented for easier user-defining of parameters like
                                    ;				  the number of wait cycles at power on or the LED pin.
                                    ;				- Code and Comments clean up
                                    ;				- Version 1.4 decleared which will be used for testing on hardware together with
                                    ;				  AVRProg Version 1.40.
                                    ;
                                    ;	09.04.2005	- Goodbye-Message implemented to inform user via UART that bootloader is left 
                                    ;				  when command 'E' was sent
                                    ;				- Tests on hardware successful
                                    ;				  -> Version 2.0 released
                                    ;
                                    ;
                                    ;
                                    ;
                                    ;	Before or after programming a new ATmega8 with this Boot Loader the fuse bits must
                                    ;	be set like this: 
                                    ;
                                    ;		The ATmega8 Fuse High bits must be programmed to configure the Boot size to 512 words
                                    ;		and to move the Reset Vector to word address 0xE00. (BOOTSZ1=0, BOOTSZ0=1)
                                    ;		
                                    ;		I.e. set the check box for BOOTRST in AVR-Prog-Advanced and set the
                                    ;		selector to 512 words, then press "write". It is important that this selected
                                    ;		size of the bootrom fits to the .org command within this source code, otherwise
                                    ;		the processor will not correctly start at the first line of this code after reset.
                                    ;		(Settings can be checked now or	later with "read").
                                    ;
                                    ;	Optional:
                                    ;
                                    ;		The Lock bits can be programmed to 0xEF to protect the Boot Flash Section from
                                    ;		unintentional changes and to allow accessing the Application Flash Section.
                                    ;
                                    ;		I.e. the setting for BLB0 and BLB1 in AVR-Prog-Advance:
                                    ;
                                    ;		BLB0 (sets the protection for the application section) must be set to 
                                    ;		Mode 1 (no protection) to allow full access of LPM and SPM commands within 
                                    ;		the application section.
                                    ;
                                    ;		BLB1 (sets the protection for the boot loader section) can be set to Mode 2
                                    ;		(SPM cannot write to boot section) or can be left to Mode 1 (no protection).
                                    ;
                                    ;		The Fuse bits must be programmed before programming the Lock bits.
                                    ;
                                    ;
                                    ; 	AVRProg Commands as defined by Atmel
                                    ;
                                    ;										Host Writes 	Host Reads
                                    ;										ID 		Data 	Data
                                    ;	Enter Programming Mode 				'P' 					13d		(implemented to ignore)
                                    ;	Auto Increment Address 				'a' 			dd				(fully implemented)
                                    ;	Set Address 						'A' 	ah al 			13d		(fully implemented)			
                                    ;	Write Program Memory, Low Byte 		'c' 	dd 				13d		(fully implemented)
                                    ;	Write Program Memory, High Byte 	'C' 	dd 				13d		(fully implemented)
                                    ;	Issue Page Write 					'm' 					13d		(fully implemented)
                                    ;	Read Lock Bits 						'r' 			dd				(fully implemented)
                                    ;	Read Program Memory 				'R' 			2*dd			(fully implemented)
                                    ;	Read EEPROM Memory 					'd' 			dd				(fully implemented)
                                    ;	Write EEPROM Memory					'D' 	dd 				13d		(fully implemented)
                                    ;	Chip Erase 							'e' 					13d		(implemented, erases appl. area only)
                                    ;	Write Lock Bits 					'l' 	dd 				13d		(implemented to ignore)
                                    ;	Read Fuse Bits 						'F' 			dd				(fully implemented)
                                    ;	Read High Fuse Bits 				'N' 			dd				(fully implemented)
                                    ;	Read Extended Fuse Bits 			'Q' 			dd				(not implemented)
                                    ;	Leave Programming Mode 				'L' 					13d		(implemented to ignore)
                                    ;	Select Device Type 					'T' 	dd 				13d		(implemented to ignore)
                                    ;	Read Signature Bytes 				's' 			3*dd			(fully implemented)
                                    ;	Return Supported Device Codes 		't' 			n*dd 	00d		(implemented, returns only Mega8)
                                    ;	Return Software Identifier 			'S' 			s[7]			(fully implemented)
                                    ;	Return Software Version 			'V' 			dd dd			(fully implemented)
                                    ;	Return Hardware Version				'v'								(fully implemented)
                                    ;	Return Programmer Type	 			'p' 			dd				(fully implemented)
                                    ;	Set LED 							'x' 	dd 				13d		(implemented to ignore)
                                    ;	Clear LED 							'y' 	dd 				13d		(implemented to ignore)
                                    ;	Exit Bootloader 					'E' 					{13d} 	(implemented 'E' is not confirmed)
                                    ;	Check Block Support 				'b' 			'Y' 2*dd		(implemented to return no)
                                    ;	Start Block Flash Load 				'B' 	2*dd 'F'		13d		(not implemented)
                                    ;												n*dd
                                    ;	Start Block EEPROM Load 			'B' 	2*dd 'E'		13d		(not implemented)	
                                    ;												n*dd
                                    ;	Start Block Flash Read 				'g' 	2*dd 'F'  n*dd			(not implemented)
                                    ;	Start Block EEPROM Read 			'g' 	2*dd 'E'  n*dd			(not implemented)
                                    ;	Universal Command (3 data bytes)	':'		3*dd	dd		13d		(implemented to ignore)
                                    ;	New Universal Command (4 data bytes)'.'		4*dd	dd		13d		(implemented to ignore)
                                    ;
                                    
                                    
                                    ;------------------------------- definition and includes --------------------------------
                                    
                                    .INCLUDE "m8def.inc" 				; Include Register/Bit Definitions for the mega8
                                    
                                    .def dummy   = r18					; Use Reg. R18 for temporary stuff
                                    .def pa_10ms = r19					; used for selecting the pause time in steps of 10ms
                                    
                                    .def uni_cmd1 = r20					; Universal command ':' send three bytes. These
                                    .def uni_cmd2 = r21					; are stored for futher usage in r20, r21, r28
                                    .def uni_cmd3 = r10
                                    
                                    .equ VER_H = '2' 					; bootloader software version higher number
                                    .equ VER_L = '0' 					; bootloader software version lower number
                                    
                                    .equ VERH_H = '1' 					; bootloader hardware version higher number
                                    .equ VERH_L = '0' 					; bootloader hardware version lower number
                                    
                                    .equ DT  = 0x76 					; Device Type = 0x76 (ATmega8)
                                    
                                    .equ SB1 = 0x07 					; Signature byte 1
                                    .equ SB2 = 0x93 					; Signature byte 2
                                    .equ SB3 = 0x1e 					; Signature byte 3
                                    
                                    .equ UBR = 23 						; Baud rate = 19.2 kbps with fCK = 7.3728 MHz
                                    
                                    .equ ESC = 27						; Ascii 27 = Escape
                                    
                                    ;	.equ E2END = 1FF				; This definition is missing in the m8def.inc file
                                    									; that came with the older Assembler. In "Assembler2"
                                    									; it is correct, so it is not required any more.
                                    
                                    .equ MY_BOOTSTART = THIRDBOOTSTART	; here we define where the bootloader starts in the flash
                                    
                                    ;------------------------------ configuration parameters --------------------------------
                                    
                                    .equ STUP_WT_CKL	= 10			; number of waiting loops (LED flashes) at power on
                                    									; before the main application starts automatically
                                    
                                    .equ LED_PORT		= PORTB			; Port B is used for the LED
                                    .equ LED_DIR		= DDRB			; Direction register for LED Port is DDRB
                                    .equ LED_PIN 		= 1				; LED is connected to pin 1 of Port B
                                    
                                    
                                    
                                    
                                    ;------------------------------------- here we go ---------------------------------------
                                    
                                    .org MY_BOOTSTART					; The code of this bootloader has to be located in
                                    									; the bootloader area at the end of the flash. With
                                    									; this .org it can be loaded into the device just 
                                    									; like any other software (normal ATmega8 setting).
                                    
                                    ; ------------------------------- init stackpointer -------------------------------------
                                    
                                    	ldi R24, low(RAMEND)			; SP = RAMEND
                                    	ldi R25, high(RAMEND)
                                    	out SPL, R24
                                    	out SPH, R25 					
                                    
                                    ; ---------------------------------- init UART ------------------------------------------
                                    
                                    	ldi R24, UBR 					; Baud rate = 19.2 bps
                                    	out UBRRL, R24
                                    
                                    	ldi R24,(1<<RXEN)|(1<<TXEN)		; Enable receiver & transmitter, 8-bit mode
                                    	out UCSRB,R24 					
                                    
                                    ; -------------------------- check for action on UART -----------------------------------
                                    ; After power-on, the processor starts with the bootloader section. Ususally the user
                                    ; want the application to start automatircally. Only in special cases, a software update
                                    ; is required. So if no ESC (ASCII(27)) is received within the defined number of wait
                                    ; cycles after power-on, the application starts.
                                    
                                    
                                    	sbi LED_PORT, LED_PIN			; Switch PortB to output to drive an LED (active low)
                                    	ldi R17, STUP_WT_CKL			; Preset the number of LED-flashes (=number of loops) 
                                    									; for the waiting periode
                                    
                                    start_wait:
                                    	
                                    	sbi LED_PORT, LED_PIN			; switch off the LED
                                    	ldi pa_10ms, 20
                                    	rcall pause						; wait a moment
                                    
                                    	cbi LED_PORT, LED_PIN			; switch on the LED
                                    	ldi pa_10ms, 20
                                    	rcall pause						; wait a moment
                                    
                                    	sbis UCSRA,RXC 					; check for incoming data (if RXC==1)
                                    	rjmp Lwait						; if not, continue at Lwait
                                    
                                    	;--- some character was received ---
                                    	in R16, UDR 					; fetch received character and put it into R16
                                    
                                    	cpi R16, ESC					; if the received character was ESC
                                    	breq bootload_start				; start the bootloader main loop
                                    									; LED stays switched on (all other incomming characters
                                    									; are simply ignored)
                                    
                                    Lwait:
                                    	dec R17							; decrement the loop counter
                                    	brne start_wait					; and leave loop if counter has reached zero 
                                    
                                    	sbi LED_PORT, LED_PIN			; switch off the LED
                                    
                                    	rjmp FLASHEND+1					; Start the application program 
                                    									; (flashend+1) = Address 0
                                    
                                    
                                    ;------------------- here starts the real bootloader functionality ----------------------
                                    bootload_start:
                                    
                                    	; To indicate to the user that the attemt to start the bootloader functionality
                                    	; was successful, we send a message back on the UART.	
                                    
                                    	ldi ZL,low( 2*uart_msg)			; load the start-address of the startup message 
                                    	ldi ZH,high(2*uart_msg)			;	into the Z-Register
                                    
                                    str_output: 
                                    	lpm R16,Z+						; read one character of the string and increment 
                                    									; string pointer (the Z-register)
                                    	
                                    	tst R16
                                    	breq L10 						; exit the character output loop if character was '\0' 
                                    
                                    	rcall uartSend 					; send the read character via the UART
                                    
                                    	rjmp str_output					; go to start of loop for next character
                                    	
                                    
                                    ;---------------------------------- start of main loop ----------------------------------
                                    
                                    
                                    ;-------------------- wait for a character from UART other than ESC ---------------------
                                    L10:	
                                    	rcall uartGet 					; repeat (R16 = uartGet)
                                    	cpi R16, ESC					; while (R16 == ESCAPE)
                                    	breq L10
                                    
                                    ;--------- Command 'E' leaves the bootloader mode and starts the application ------------
                                    
                                    	cpi R16, 'E' 					; if(R16=='E') 'E' = Exit bootloader
                                    	brne L11
                                    
                                    	; Send goodbye-message on UART	
                                    
                                    	ldi ZL,low( 2*goodbye_msg)		; load the start-address of the startup message 
                                    	ldi ZH,high(2*goodbye_msg)		;	into the Z-Register
                                    
                                    goodbye_output: 
                                    	lpm R16,Z+						; read one character of the string and increment 
                                    									; string pointer (the Z-register)
                                    	
                                    	tst R16
                                    	breq leave_bootloader			; exit the character output loop if character was '\0' 
                                    
                                    	rcall uartSend 					; send the read character via the UART
                                    
                                    	rjmp goodbye_output				; go to start of loop for next character
                                    	
                                    
                                    leave_bootloader:
                                    
                                    	sbi LED_PORT, LED_PIN			; switch off the LED
                                    
                                    	rjmp FLASHEND+1					; Start the application program 
                                    									; (flashend+1) = Address 0
                                    
                                    
                                    ;--------- Command 'a' is question from host for autoimcrement capability----------------
                                    ;				simple anser is 'Y' for yes, autoincrement is done
                                    L11:
                                    
                                    	cpi R16, 'a' 					; if(R16=='a') 'a' = Autoincrement?
                                    	brne L12
                                    
                                    	ldi R16,'Y' 					; Yes, autoincrement is quicker
                                    	rjmp L70 						; uartSend(R16) Send the 'Y' and go up for next command
                                    
                                    
                                    ;--------- Command 'A' is setting the address for the next operation --------------------
                                    ; 		two bytes (in total) for high and low address are sent from the host
                                    L12: 
                                    
                                    	cpi R16,'A' 					; else if(R16=='A') write address
                                    	brne L14
                                    
                                    	rcall uartGet
                                    	mov R27,R16 					; address high byte is stored in R27
                                    
                                    	rcall uartGet
                                    	mov R26,R16 					; address low byte is stored in R26
                                    	
                                    	lsl R26 						; address=address<<1
                                    	rol R27 						; convert from byte address to word address
                                    	
                                    	rjmp L68 						; uartSend('\r') send CR and go up for next command
                                    
                                    
                                    ;--------- Command 'c' is write low byte to program memory ------------------------------
                                    ; the low byte is simply stored in a register, the actual writing to the flashes
                                    ; page-buffer is done later, after the high byte was received
                                    L14: 
                                    	cpi R16,'c' 					; else if(R16=='c') write program memory, low byte
                                    	brne L16
                                    
                                    	rcall uartGet					; read the byte to be written from host
                                    
                                    	mov R22,R16 					; store data low byte in R22
                                    
                                    	rjmp L68 						; uartSend('\r') send CR and go up for next command
                                    
                                    
                                    ;--------- Command 'C' is write high byte to program memory -----------------------------
                                    ; together with the (already received) low byte, the highbyte is writen to the flashes
                                    ; page buffer. When the page buffer is completely written, it can be transfered into
                                    ; the real flash by the "page write" command.
                                    ;
                                    ; If only SPMEN is written, the following SPM instruction will store the value in R1:R0 
                                    ; in the temporary page buffer addressed by the Z pointer. 
                                    
                                    L16: 
                                    
                                    	cpi R16,'C' 					; else if(R16=='C') write program memory,high byte
                                    	brne L18
                                    	
                                    	rcall uartGet					; read the high byte from the host
                                    	mov R23,R16 					; store the data high byte in R23
                                    
                                    	movw ZL,R26 					; load the Z pointer with the current address
                                    	
                                    	movw R0,R22 					; transfer the data word (data high and low byte)
                                    									; into registers R0 and R1
                                    	
                                    	rcall wait_for_spm				; make sure SPM is ready to accept a new task
                                    
                                    	ldi R24, (1<<SPMEN)				; set SPMEN in SPMCR
                                    	out SPMCR,R24 					; page load (fill temporary buffer)
                                    
                                    	spm 							; Store program memory
                                    
                                    	adiw R26,2 						; address=address+2
                                    	rjmp L68 						; uartSend('\r') send CR and go up for next command
                                    
                                    
                                    ;-------------------------- Command 'e' is chip erase -----------------------------------
                                    ; "chip erase" for the boot loader means to erase all flash pages othen than the
                                    ; boot loader sector itself
                                    L18: 
                                    
                                    	cpi R16,'e' 					; else if(R16=='e') Chip erase
                                    	brne L28
                                    
                                    	; the loop that has to be performed to clear the application section is:
                                    	; for(address=0; address < (2*MY_BOOTSTART); address += (2*PAGESIZE))
                                    	; the "address" variable to be used are the registers R26 and R27
                                    	
                                    	clr R26 						; start with address 0
                                    	clr R27
                                    
                                    	rjmp L24						; continue the loop at the check for
                                    									; "end-criteria reached"
                                    
                                    ;......... beginning of erase loop ............
                                    L20: 
                                    
                                    ; If the PGERS bit is written to one at the same time as SPMEN, the next SPM 
                                    ; instruction within four clock cycles executes page erase. The page address 
                                    ; is taken from the high part of the Z pointer.
                                    
                                    	rcall wait_for_spm				; make sure SPM is ready to accept a new task
                                    
                                    	movw ZL,R26 					; load the Z-pointer with the address of the 
                                    									; page to be erased
                                    
                                    	ldi R24, (1<<PGERS) | (1<<SPMEN); simultaniously set PGERS and SPMEN in SPMCR
                                    	out SPMCR,R24 					; 	to prepare for the page_erase
                                    
                                    	spm 							; Store program memory
                                    	nop
                                    
                                    	subi R26,low(-2*PAGESIZE) 		; increment the address by the size of a page
                                    	sbci R27,high(-2*PAGESIZE)		
                                    
                                    	; this is the check for end-criteria reached, i.e. has the address already 
                                    	; reached the beginning of the boot-loader section
                                    L24: 
                                    	ldi R24,low( 2*MY_BOOTSTART)	; load R24, R25 with the address where the boot-loader
                                    	ldi R25,high(2*MY_BOOTSTART)	;	section starts
                                    
                                    	cp R26,R24 						; do a word-compare to check if the address is still
                                    	cpc R27,R25						; smaller than the address where the bootloader starts
                                    
                                    	brlo L20						; if that is the case, go to the beginning of the erase loop
                                    
                                    ; ..... remember the number of flash-erases in the EEPROM .....
                                    	ldi R26,low( E2END -1) 			; increment Chip Erase Counter located
                                    	ldi R27,high(E2END -1) 			; at address 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
                                    ; ..........................................................
                                    
                                    	rcall wait_for_spm				; make sure SPM is ready to accept a new task
                                    
                                    	rcall enable_rww				; reenable the RWW section so it can be accessed again
                                    
                                    	rjmp L68 						; uartSend('\r') send CR and go up for next command
                                    
                                    ;---------------------------- Command 'm' is write page ---------------------------------
                                    ; To execute page write, set up the address in the Z pointer, write 'X0000101' to SPMCR
                                    ; and execute SPM within four clock cycles after writing SPMCR. The data in R1 and R0
                                    ; is ignored. The page address must be written to PCPAGE. Other bits in the Z pointer will
                                    ; be ignored during this operation.
                                    L28: 
                                    	cpi R16,'m' 					; else if(R16== 'm') Write page
                                    	brne L34
                                    
                                    	rcall wait_for_spm				; make sure SPM is ready to accept a new task
                                    		
                                    	movw ZL,R26 					; load Z-pointer with address
                                    	
                                    	ldi R24, (1<<PGWRT) | (1<<SPMEN); set PGWRT and SPMEN in SPMCR to prepare for Write page
                                    	out SPMCR,R24
                                    	
                                    	spm 							; Store program memory
                                    	
                                    	nop
                                    
                                    	rcall enable_rww				; reenable the RWW section so it can be accessed again
                                    
                                    L32: 
                                    	rjmp L68 						; uartSend('\r') send CR and go up for next command
                                    
                                    
                                    ;--------------------- Command 'P' is enter programming mode ----------------------------
                                    ; nothing is done here, only the command is confirmed to host by sending CR
                                    L34: 
                                    	cpi R16,'P' 					; else if(R16=='P') Enter programming mode
                                    	breq L32 						; uartSend('\r') Send CR to host and go up for next command
                                    
                                    
                                    ;--------------------- Command 'L' is leave programming mode ----------------------------
                                    ; nothing is done here, only the command is confirmed to host by sending CR
                                    	cpi R16,'L' 					; else if(R16=='L') Leave programming mode
                                    	breq L32 						; uartSend('\r') Send CR to host and go up for next command
                                    
                                    
                                    ;--------------------- Command 'p' is Return programmer type ----------------------------
                                    ; simply return an 'S' to indicate to host that this is a serial programmer
                                    	
                                    	cpi R16,'p' 					; else if (R16=='p') return programmer type
                                    	brne L38
                                    
                                    	ldi R16,'S' 					; uartSend('S') for type is serial
                                    	rjmp L70 						; uartSend(R16) and go up for next command
                                    
                                    
                                    ;--------------------- Command 'R' is "Read one word from program memory" ---------------
                                    ; reads one word from the 'current' address that is stored in R26 and increments R26
                                    L38: 
                                    	cpi R16,'R' 					; else if(R16=='R') Read program memory
                                    	brne L40
                                    
                                    	movw ZL,R26 					; load Z-pointer with address of memory to be read
                                    
                                    	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) write back MSB to host
                                    
                                    	movw R26,ZL 					; increment the 'current' address += 2
                                    
                                    	mov R16,R24 					; LSB stored in R16
                                    
                                    	rjmp L70 						; uartSend(R16) write back the LSB to host and go
                                    									; up for next command
                                    
                                    ;--------------------- Command 'D' is "write data to EEPROM" ----------------------------
                                    L40: 
                                    	cpi R16,'D' 					; else if (R16=='D') Write data to EEPROM
                                    	brne L41
                                    	rcall uartGet					; fetch the data to write from the UART
                                    	out EEDR,R16 					; EEDR = uartGet() 
                                    	ldi R17,6 						; write EEPROM
                                    	rcall EepromTalk
                                    	rjmp L68 						; uartSend('\r') Confirm the command to host with CR
                                    
                                    
                                    ;--------- Command 'b' is question from host for block mode capability-------------------
                                    ;		   simple anser is 'N', no bootloader does not support blockmode
                                    L41:
                                    
                                    	cpi R16, 'b' 					; if(R16=='b') 'b' = Blockmode?
                                    	brne L42
                                    
                                    	ldi R16,'N' 					; send 'N'
                                    	rcall uartSend
                                    
                                    	ldi R16,'N' 					; send 'N'
                                    	rjmp L70 						; uartSend(R16) Send the 'N' and go up for next command
                                    
                                    ;--------------------- Command 'd' is "read data from EEPROM ----------------------------
                                    L42: 
                                    	cpi R16,'d' 					; else if (R16=='d') Read data from EEPROM
                                    	brne L43
                                    	ldi R17,1 						; read EEPROM
                                    	rcall EepromTalk 				; R16 = EEPROM data
                                    	rjmp L70 						; uartSend(R16)
                                    
                                    
                                    ;-------------------------- Command ':' is universal command ----------------------------
                                    ; Host sends 3 more bytes which must be used to determine the required action. AVRProg
                                    ; uses the ':' with parameters to do things that could simply be done by r/F/N. 
                                    ; We have to map recognized parameters to the refering action.
                                    
                                    L43: 
                                    	cpi R16,':' 					; else if(R16==':') Universal Command
                                    	brne L44
                                    	
                                    
                                    	;.............. read in the parameters ...............................
                                    
                                    	rcall uartGet 					; R16 = uartGet()
                                    	mov uni_cmd1, r16				; store the read byte
                                    
                                    	rcall uartGet 					; R16 = uartGet()
                                    	mov uni_cmd2, r16				; store the read byte
                                    
                                    	rcall uartGet 					; R16 = uartGet()
                                    	mov uni_cmd3, r16				; store the read byte
                                    
                                    	;.....................................................................
                                    
                                    	clr r16							; preset r16 with zero, if parameters are not
                                    									; recognized, zero will be returned to host
                                    
                                    	;.....................................................................
                                    
                                    	cpi uni_cmd1, 0x58				; check if 1st paramter is 0x58 
                                    	brne cmd1_not_0x58
                                    
                                    	cpi uni_cmd2, 0x00				; check if 2nd paramter is 0x00
                                    	brne cmd2_not_0x00_1
                                    
                                    	; -> 58 00 is read lock bits,
                                    	ldi ZL,1 						; Z pointer = 0001 (-> readFuseAndLock will read lock)
                                    	rcall readFuseAndLock			; go get the requested bits
                                    
                                    cmd2_not_0x00_1:
                                    
                                    	cpi uni_cmd2, 0x08				; check if 2nd paramter is 0x08
                                    	brne cmd2_not_0x08
                                    
                                    	; -> 58 08 is read fuse high bits,
                                    	ldi ZL,3 						; Z pointer = 0003 (-> readFuseAndLock will read high fuse)
                                    	rcall readFuseAndLock			; go get the requested bits
                                    
                                    cmd2_not_0x08:
                                    
                                    cmd1_not_0x58:
                                    
                                    	cpi uni_cmd1, 0x50				; check if 1st paramter is 0x50 
                                    	brne cmd1_not_0x50
                                    
                                    	cpi uni_cmd2, 0x00				; check if 2nd paramter is 0x00
                                    	brne cmd2_not_0x00_2
                                    
                                    	; -> 50 00 is read fuse bits,
                                    	clr ZL 							; Z-pointer = 0000 (-> readFuseAndLock will read fuse)
                                    	rcall readFuseAndLock			; go get the requested bits
                                    
                                    cmd2_not_0x00_2:
                                    
                                    cmd1_not_0x50:
                                    	
                                    	rcall uartSend 					; uartSend(bits) send the read lock/fuse bits
                                    
                                    	rjmp L68 						; uartSend('\r') and go up for next command
                                    
                                    
                                    
                                    ;--------------------- Command 'F' is "read fuse bits" ----------------------------------
                                    L44: 
                                    	cpi R16,'F' 					; else if(R16=='F') Read fuse bits
                                    	brne L46
                                    	clr ZL 							; Z-pointer = 0000 (-> readFuseAndLock will read fuse)
                                    	rjmp L50 						; rcall readFuseAndLock
                                    
                                    
                                    ;--------------------- Command 'r' is "read lock bits" ----------------------------------
                                    L46: 
                                    	cpi R16,'r' 					; else if(R16=='r') Read lock bits
                                    	brne L48
                                    	ldi ZL,1 						; Z pointer = 0001 (-> readFuseAndLock will read lock)
                                    	rjmp L50 						; rcall readFuseAndLock
                                    
                                    
                                    ;--------------------- Command 'N' is "read fuse high bits" -----------------------------
                                    L48: 
                                    	cpi R16,'N' 					; else if(R16=='N') Read high fuse bits
                                    	brne L52
                                    	ldi ZL,3 						; Z-pointer = 0003 (-> readFuseAndLock will read high fuse)
                                    
                                    
                                    ;-------- for all previous commands F,r,N hear we rcall the readFuseAndLock --------------
                                    ;		function that will read the bits that are indicated by the Z-register	
                                    L50: 
                                    	rcall readFuseAndLock
                                    	rjmp L70 						; uartSend(R16)
                                    
                                    
                                    ;--------------------- Command 't' is Return supported devices code ---------------------
                                    ;				obviously we return only the device code of the mega8 here
                                    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 of Mega8
                                    
                                    	clr R16							; command set of AVRProg requires the termination of
                                    									; the t-command with a \0 not with a CR as other commands
                                    	rjmp L70 						; uartSend(0) and go up for next command
                                    
                                    ; ---------------- ignored commands that are not sensible for boot loader ---------------
                                    ; The following 4 commands only make sense for a general programmer, not for a bootloader.
                                    ; As theres commands come with an additional byte as parameter, with have to fetch that
                                    ; byte from the UART to avoid messing up the UART reading.
                                    L54: 								
                                    
                                    	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()
                                    	rjmp L68 						; uartSend('\r') and go up for next command
                                    
                                    
                                    ;--------------------- Command 'S' is Return software identifier ------------------------
                                    L60: 
                                    	cpi R16,'S' 					; else if(R16=='S') Return software identifier
                                    	brne L62
                                    	
                                    	ldi ZL,low(2*Soft_Id)			; load address of String into Z-Register
                                    	ldi ZH,high(2*Soft_Id)
                                    
                                    L61: 
                                    	lpm R16,Z+						; read one character of the string and increment string pointer
                                    	
                                    	tst R16
                                    	breq L72 						; exit the character output loop charcter was '\0' 
                                    
                                    	rcall uartSend 					; send the read character via the UART
                                    
                                    	rjmp L61						; go to start of loop for next character
                                    
                                    
                                    ;--------------------- Command 'V' is Return software Version ---------------------------
                                    L62: 
                                    	cpi R16,'V' 					; else if (R16=='V') Return Software Version
                                    	brne L63
                                    
                                    	ldi R16, VER_H 					; send bootloader software version higher number
                                    	rcall uartSend
                                    
                                    	ldi R16, VER_L 					; send bootloader software version lower number
                                    	rjmp L70 						; uartSend and go up for next command
                                    
                                    ;--------------------- Command 'v' is Return hardware Version ---------------------------
                                    L63: 
                                    	cpi R16,'v' 					; else if (R16=='v') Return hardware Version
                                    	brne L64
                                    
                                    	ldi R16, VERH_H 				; send bootloader software version higher number
                                    	rcall uartSend
                                    
                                    	ldi R16, VERH_L 				; send bootloader software version lower number
                                    	rjmp L70 						; uartSend and go up for next command
                                    
                                    
                                    ;--------------------- Command 's' is Return Signature Byte -----------------------------
                                    L64: 
                                    	cpi R16,'s' 					; else if (R16=='s') Return Signature Byte
                                    	brne L65
                                    
                                    	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 and go up for next command
                                    
                                    
                                    ;--------------------- Command '.' is new universal command -----------------------------
                                    ; this command will be ignored, only the inteface will be handled correctly
                                    L65: 
                                    	cpi R16,'.' 					; else if (R16=='.') New Universal Command
                                    	brne L66
                                    
                                    	;.............. read in the 4 parameters ...............................
                                    
                                    	rcall uartGet 					; R16 = uartGet()
                                    	rcall uartGet 					; R16 = uartGet()
                                    	rcall uartGet 					; R16 = uartGet()
                                    	rcall uartGet 					; R16 = uartGet()
                                    	
                                    	; ......................................................................
                                    
                                    	clr R16 						; uartSend(/0)
                                    	rcall uartSend
                                    
                                    	rjmp L68 						; uartSend('\r') and go up for next command
                                    
                                    
                                    ;++++++++++++++ handling the different commands is done till here +++++++++++++++++++++++
                                    ;			      only general completion for all commands below
                                    
                                    
                                    ;---------------------- failed commands can end up here ---------------------------------
                                    ;	an '?' is send via the UART to indicate fail host, then main loop starts again
                                    
                                    L66: 
                                    	ldi R16,'?' 					; else uartSend('?')
                                    	rjmp L70 						; uartSend(R16)
                                    
                                    ;--------- successfully completed commands without return value can end up here ---------
                                    ;	an CR is sent via the UART to confirm execution to host, then main loop starts again
                                    
                                    L68: 
                                    	ldi R16,13 						; uartSend('\r')
                                    
                                    ;------------ successfully completed commands with return value can end up here ---------
                                    ;	         the return value is sent via the UART to confirm execution to host 
                                    ;							then main loop starts again
                                    L70: 
                                    	rcall uartSend 					; uartSend(R16)
                                    
                                    L72: 
                                    	rjmp L10						; jump up to beginning of main loop
                                    
                                    ;-------------------------- end of main loop --------------------------------------------
                                    
                                    
                                    
                                    ;================= end of main program, only subroutines from here on ===================
                                    
                                    
                                    
                                    ;------------------ reads fuse or lock bits (depending on Z-Reg.) -------------
                                    readFuseAndLock:
                                    
                                    	; An LPM instruction within three cycles after BLBSET and SPMEN are set in the SPMCR
                                    	; Register, will read either the Lock bits or the Fuse bits 
                                    	; (depending on Z0 in the Z pointer) into the destination register.
                                    
                                    	rcall wait_for_spm				; make sure SPM is ready to accept a new task
                                    
                                    	clr ZH 							; Z pointer high byte = 0
                                    
                                    	ldi R24,(1<<BLBSET)|(1<<SPMEN)	; set BLBSET and SPMEN in SPMCR 
                                    	out SPMCR,R24 					; read fuse and lock
                                    	lpm R16,Z 						; read program memory
                                    
                                    	ret
                                    
                                    ;------------- does an read or write on the EEPROM (depending on R17) ---------
                                    ; 					 if R17 == 6 then Write, if R17 == 1 then Read
                                    EepromTalk: 					
                                    	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
                                    
                                    ;---------------- send one character via UART (parameter is r16) --------------
                                    uartSend: 							
                                    	sbis UCSRA,UDRE 				; wait for empty transmit buffer (until UDRE==1)
                                    	rjmp uartSend
                                    	out UDR,R16 					; UDR = R16, start transmission
                                    
                                    	ret
                                    
                                    ;---------------- read one character from UART (returned in r16) --------------
                                    uartGet:
                                    	
                                    	sbis UCSRA,RXC 					; wait for incoming data (until RXC==1)
                                    	rjmp uartGet
                                    	in R16,UDR 						; return received data in R16
                                    	
                                    	ret
                                    
                                    ;-------------------- wait for SPM to be ready for new tasks ------------------
                                    ; while( SPMCR_REG & (1<<SPMEN) )
                                    wait_for_spm:
                                    	
                                    	in r16, SPMCR					; read the content of SPMCR into register
                                    	andi r16, (1<<SPMEN)			; check if bit SPMEN is set
                                    	brne wait_for_spm				; and do more loops if bit not yet cleared
                                    
                                    Wait_ee:
                                    	sbic EECR, EEWE					; check that no EEPROM write access is present
                                    	rjmp Wait_ee
                                    
                                    	ret
                                    
                                    
                                    ; ---------------------------- re-enable the RWW section ----------------------
                                    ; When programming (page erase or page write) to the RWW section, the RWW section
                                    ; is blocked for reading (the RWWSB will be set by hardware). To re-enable the RWW
                                    ; section, the user software must wait until the programming is completed (SPMEN will be
                                    ; cleared). Then, if the RWWSRE bit is written to one at the same time as SPMEN, the
                                    ; next SPM instruction within four clock cycles re-enables the RWW section.
                                    ; If this is not done, all addresses will read $FF even if they contain other values.
                                    enable_rww:
                                    
                                    	rcall wait_for_spm				; make sure SPM is ready to accept a new task 
                                    
                                    	ldi r16, (1<<RWWSRE) | (1<<SPMEN) 	; set rwwsre and spmen in SPMCR to prepare
                                    	out SPMCR, r16						; for reenabling the rww section
                                    
                                    	spm								; initiate the reenabling
                                    
                                    	ret
                                    
                                    ;---------------------------------- Pause -------------------------------------
                                    ; Delays the CPU the selected periode, parameter pa_10ms is in 10ms steps
                                    
                                    pause:
                                    	ldi dummy, 0b00000101			; set prescaler to 1024
                                    	out TCCR0, dummy
                                    	
                                    	ldi dummy, 184					; preset the counter for 72 remaining
                                    	out TCNT0, dummy				;	cycles till overflow
                                    
                                    	in dummy, TIFR					; reset the overflow flag 
                                    	sbr dummy, (1<<TOV0)	
                                    	out TIFR, dummy
                                    
                                    pw:	in dummy, TIFR					; check if overflow flag is set
                                    	sbrs dummy, TOV0	
                                    	rjmp pw							; if not, wait more
                                    
                                    	;--- do this 10ms as often as requested in parameter pa_10ms
                                    	dec pa_10ms						; decrement the counter
                                    	brne pause						; and do the loop again if not zero yet
                                    
                                    	ret
                                    	
                                    ;-------------------------- data for identifier string ----------------------------------
                                    Soft_Id: 
                                    
                                    	.db "AVRB_M8", 0
                                    
                                    ;--------------- data for message on UART when bootloader starts ------------------------
                                    uart_msg:
                                    
                                    	.db "+--------------------------------------------------+",10,13
                                    	.db "|   Bootloader for ATmega8, Version ", VER_H, '.',VER_L, " by DL5NEG  |",10,13
                                    	.db "|       Use AVRProg to download new software.      |",10,13
                                    	.db "| Press E to leave the bootloader and to start the |",10,13
                                    	.db "|    application software from the flash memory.   |",10,13
                                    	.db "+--------------------------------------------------+ ",10,13,10,13,0
                                    
                                    ;------------- data for message on UART when leaving the bootloader ---------------------
                                    goodbye_msg:
                                    
                                    	.db "Thanks for using DL5NEGs bootloader. ",10,13,10,13,0
                                    
                                    
                                    
                                    
                                 

Programming the AVR Microcontrollers in Assember Machine Language

This site is a member of WebRing.
To browse visit Here.

Atmel AVR From Wikipedia, the free encyclopedia (Redirected from Avr) Jump to: navigation, search The AVRs are a family of RISC microcontrollers from Atmel. Their internal architecture was conceived by two students: Alf-Egil Bogen and Vegard Wollan, at the Norwegian Institute of Technology (NTH] and further developed at Atmel Norway, a subsidiary founded by the two architects. Atmel recently released the Atmel AVR32 line of microcontrollers. These are 32-bit RISC devices featuring SIMD and DSP instructions, along with many additional features for audio and video processing, intended to compete with ARM based processors. Note that the use of "AVR" in this article refers to the 8-bit RISC line of Atmel AVR Microcontrollers. The acronym AVR has been reported to stand for Advanced Virtual RISC. It's also rumoured to stand for the company's founders: Alf and Vegard, who are evasive when questioned about it. Contents [hide] 1 Device Overview 1.1 Program Memory 1.2 Data Memory and Registers 1.3 EEPROM 1.4 Program Execution 1.5 Speed 2 Development 3 Features 4 Footnotes 5 See also 6 External Links 6.1 Atmel Official Links 6.2 AVR Forums & Discussion Groups 6.3 Machine Language Development 6.4 C Language Development 6.5 BASIC & Other AVR Languages 6.6 AVR Butterfly Specific 6.7 Other AVR Links [edit] Device Overview The AVR is a Harvard architecture machine with programs and data stored and addressed separately. Flash, EEPROM, and SRAM are all integrated onto a single die, removing the need for external memory (though still available on some devices). [edit] Program Memory Program instructions are stored in semi-permanent Flash memory. Each instruction for the AVR line is either 16 or 32 bits in length. The Flash memory is addressed using 16 bit word sizes. The size of the program memory is indicated in the naming of the device itself. For instance, the ATmega64x line has 64Kbytes of Flash. Almost all AVR devices are self-programmable. [edit] Data Memory and Registers The data address space consists of the register file, I/O registers, and SRAM. The AVRs have thirty-two single-byte registers and are classified as 8-bit RISC devices. The working registers are mapped in as the first thirty-two memory spaces (000016-001F16) followed by the 64 I/O registers (002016-005F16). The actual usable RAM starts after both these sections (address 006016). (Note that the I/O register space may be larger on some more extensive devices, in which case memory mapped I/O registers will occupy a portion of the SRAM.) Even though there are separate addressing schemes and optimized opcodes for register file and I/O register access, all can still be addressed and manipulated as if they were in SRAM. [edit] EEPROM Almost all devices have on-die EEPROM. This is most often used for long-term parameter storage to be retrieved even after cycling the power of the device. [edit] Program Execution Atmel's AVRs have a single level pipeline design. The next machine instruction is fetched as the current one is executing. Most instructions take just one or two clock cycles, making AVRs relatively fast among the eight-bit microcontrollers. The AVR family of processors were designed for the efficient execution of compiled C code. The AVR instruction set is more orthogonal than most eight-bit microcontrollers, however, it is not completely regular: Pointer registers X, Y, and Z have addressing capabilities that are different from each other. Register locations R0 to R15 have different addressing capabilities than register locations R16 to R31. I/O ports 0 to 31 have different addressing capabilities than I/O ports 32 to 63. CLR affects flags, while SER does not, even though they are complementary instructions. CLR set all bits to zero and SER sets them to one. (Note though, that neither CLR nor SER are native instructions. Instead CLR is syntactic sugar for [produces the same machine code as] EOR R,R while SER is syntactic sugar for LDI R,$FF. Math operations such as EOR modify flags while moves/loads/stores/branches such as LDI do not.) [edit] Speed The AVR line can normally support clock speeds from 0-16MHz, with some devices reaching 20MHz. Lower powered operation usually requires a reduced clock speed. All AVRs feature an on-chip oscillator, removing the need for external clocks or resonator circuitry. Because many operations on the AVR are single cycle, the AVR can achieve up to 1MIPS per MHz. [edit] Development AVRs have a large following due to the free and inexpensive development tools available, including reasonably priced development boards and free development software. The AVRs are marketed under various names that share the same basic core but with different peripheral and memory combinations. Some models (notably, the ATmega range) have additional instructions to make arithmetic faster. Compatibility amongst chips is fairly good. See external links for sites relating to AVR development. [edit] Features Current AVRs offer a wide range of features: RISC Core Running Many Single Cycle Instructions Multifunction, Bi-directional I/O Ports with Internal, Configurable Pull-up Resistors Multiple Internal Oscillators Internal, Self-Programmable Instruction Flash Memory up to 256K In-System Programmable using ICSP, JTAG, or High Voltage methods Optional Boot Code Section with Independent Lock Bits for Protection Internal Data EEPROM up to 4KB Internal SRAM up to 8K 8-Bit and 16-Bit Timers PWM Channels & dead time generator Lighting (PWM Specific) Controller models Dedicated I²C Compatible Two-Wire Interface (TWI) Synchronous/Asynchronous Serial Peripherals (UART/USART) (As used with RS-232,RS-485, and more) Serial Peripheral Interface (SPI) CAN Controller Support USB Controller Support Proper High-speed hardware & Hub controller with embedded AVR. Also freely available low-speed (HID) software emulation Ethernet Controller Support Universal Serial Interface (USI) for Two or Three-Wire Synchronous Data Transfer Analog Comparators LCD Controller Support 10-Bit A/D Converters, with multiplex of up to 16 channels Brownout Detection Watchdog Timer (WDT) Low-voltage Devices Operating Down to 1.8v Multiple Power-Saving Sleep Modes picoPower Devices Atmel AVR assembler programming language Atmel AVR machine programming language Atmel AVR From Wikipedia, the free encyclopedia (Redirected from Avr) Jump to: navigation, search The AVRs are a family of RISC microcontrollers from Atmel. Their internal architecture was conceived by two students: Alf-Egil Bogen and Vegard Wollan, at the Norwegian Institute of Technology (NTH] and further developed at Atmel Norway, a subsidiary founded by the two architects. Atmel recently released the Atmel AVR32 line of microcontrollers. These are 32-bit RISC devices featuring SIMD and DSP instructions, along with many additional features for audio and video processing, intended to compete with ARM based processors. Note that the use of "AVR" in this article refers to the 8-bit RISC line of Atmel AVR Microcontrollers. The acronym AVR has been reported to stand for Advanced Virtual RISC. It's also rumoured to stand for the company's founders: Alf and Vegard, who are evasive when questioned about it. Contents [hide] 1 Device Overview 1.1 Program Memory 1.2 Data Memory and Registers 1.3 EEPROM 1.4 Program Execution 1.5 Speed 2 Development 3 Features 4 Footnotes 5 See also 6 External Links 6.1 Atmel Official Links 6.2 AVR Forums & Discussion Groups 6.3 Machine Language Development 6.4 C Language Development 6.5 BASIC & Other AVR Languages 6.6 AVR Butterfly Specific 6.7 Other AVR Links [edit] Device Overview The AVR is a Harvard architecture machine with programs and data stored and addressed separately. Flash, EEPROM, and SRAM are all integrated onto a single die, removing the need for external memory (though still available on some devices). [edit] Program Memory Program instructions are stored in semi-permanent Flash memory. Each instruction for the AVR line is either 16 or 32 bits in length. The Flash memory is addressed using 16 bit word sizes. The size of the program memory is indicated in the naming of the device itself. For instance, the ATmega64x line has 64Kbytes of Flash. Almost all AVR devices are self-programmable. [edit] Data Memory and Registers The data address space consists of the register file, I/O registers, and SRAM. The AVRs have thirty-two single-byte registers and are classified as 8-bit RISC devices. The working registers are mapped in as the first thirty-two memory spaces (000016-001F16) followed by the 64 I/O registers (002016-005F16). The actual usable RAM starts after both these sections (address 006016). (Note that the I/O register space may be larger on some more extensive devices, in which case memory mapped I/O registers will occupy a portion of the SRAM.) Even though there are separate addressing schemes and optimized opcodes for register file and I/O register access, all can still be addressed and manipulated as if they were in SRAM. [edit] EEPROM Almost all devices have on-die EEPROM. This is most often used for long-term parameter storage to be retrieved even after cycling the power of the device. [edit] Program Execution Atmel's AVRs have a single level pipeline design. The next machine instruction is fetched as the current one is executing. Most instructions take just one or two clock cycles, making AVRs relatively fast among the eight-bit microcontrollers. The AVR family of processors were designed for the efficient execution of compiled C code. The AVR instruction set is more orthogonal than most eight-bit microcontrollers, however, it is not completely regular: Pointer registers X, Y, and Z have addressing capabilities that are different from each other. Register locations R0 to R15 have different addressing capabilities than register locations R16 to R31. I/O ports 0 to 31 have different addressing capabilities than I/O ports 32 to 63. CLR affects flags, while SER does not, even though they are complementary instructions. CLR set all bits to zero and SER sets them to one. (Note though, that neither CLR nor SER are native instructions. Instead CLR is syntactic sugar for [produces the same machine code as] EOR R,R while SER is syntactic sugar for LDI R,$FF. Math operations such as EOR modify flags while moves/loads/stores/branches such as LDI do not.) [edit] Speed The AVR line can normally support clock speeds from 0-16MHz, with some devices reaching 20MHz. Lower powered operation usually requires a reduced clock speed. All AVRs feature an on-chip oscillator, removing the need for external clocks or resonator circuitry. Because many operations on the AVR are single cycle, the AVR can achieve up to 1MIPS per MHz. [edit] Development AVRs have a large following due to the free and inexpensive development tools available, including reasonably priced development boards and free development software. The AVRs are marketed under various names that share the same basic core but with different peripheral and memory combinations. Some models (notably, the ATmega range) have additional instructions to make arithmetic faster. Compatibility amongst chips is fairly good. See external links for sites relating to AVR development. [edit] Features Current AVRs offer a wide range of features: RISC Core Running Many Single Cycle Instructions Multifunction, Bi-directional I/O Ports with Internal, Configurable Pull-up Resistors Multiple Internal Oscillators Internal, Self-Programmable Instruction Flash Memory up to 256K In-System Programmable using ICSP, JTAG, or High Voltage methods Optional Boot Code Section with Independent Lock Bits for Protection Internal Data EEPROM up to 4KB Internal SRAM up to 8K 8-Bit and 16-Bit Timers PWM Channels & dead time generator Lighting (PWM Specific) Controller models Dedicated I²C Compatible Two-Wire Interface (TWI) Synchronous/Asynchronous Serial Peripherals (UART/USART) (As used with RS-232,RS-485, and more) Serial Peripheral Interface (SPI) CAN Controller Support USB Controller Support Proper High-speed hardware & Hub controller with embedded AVR. Also freely available low-speed (HID) software emulation Ethernet Controller Support Universal Serial Interface (USI) for Two or Three-Wire Synchronous Data Transfer Analog Comparators LCD Controller Support 10-Bit A/D Converters, with multiplex of up to 16 channels Brownout Detection Watchdog Timer (WDT) Low-voltage Devices Operating Down to 1.8v Multiple Power-Saving Sleep Modes picoPower Devices Atmel AVR assembler programming language Atmel AVR machine programming language Atmel AVR From Wikipedia, the free encyclopedia (Redirected from Avr) Jump to: navigation, search The AVRs are a family of RISC microcontrollers from Atmel. Their internal architecture was conceived by two students: Alf-Egil Bogen and Vegard Wollan, at the Norwegian Institute of Technology (NTH] and further developed at Atmel Norway, a subsidiary founded by the two architects. Atmel recently released the Atmel AVR32 line of microcontrollers. These are 32-bit RISC devices featuring SIMD and DSP instructions, along with many additional features for audio and video processing, intended to compete with ARM based processors. Note that the use of "AVR" in this article refers to the 8-bit RISC line of Atmel AVR Microcontrollers. The acronym AVR has been reported to stand for Advanced Virtual RISC. It's also rumoured to stand for the company's founders: Alf and Vegard, who are evasive when questioned about it. Contents [hide] 1 Device Overview 1.1 Program Memory 1.2 Data Memory and Registers 1.3 EEPROM 1.4 Program Execution 1.5 Speed 2 Development 3 Features 4 Footnotes 5 See also 6 External Links 6.1 Atmel Official Links 6.2 AVR Forums & Discussion Groups 6.3 Machine Language Development 6.4 C Language Development 6.5 BASIC & Other AVR Languages 6.6 AVR Butterfly Specific 6.7 Other AVR Links [edit] Device Overview The AVR is a Harvard architecture machine with programs and data stored and addressed separately. Flash, EEPROM, and SRAM are all integrated onto a single die, removing the need for external memory (though still available on some devices). [edit] Program Memory Program instructions are stored in semi-permanent Flash memory. Each instruction for the AVR line is either 16 or 32 bits in length. The Flash memory is addressed using 16 bit word sizes. The size of the program memory is indicated in the naming of the device itself. For instance, the ATmega64x line has 64Kbytes of Flash. Almost all AVR devices are self-programmable. [edit] Data Memory and Registers The data address space consists of the register file, I/O registers, and SRAM. The AVRs have thirty-two single-byte registers and are classified as 8-bit RISC devices. The working registers are mapped in as the first thirty-two memory spaces (000016-001F16) followed by the 64 I/O registers (002016-005F16). The actual usable RAM starts after both these sections (address 006016). (Note that the I/O register space may be larger on some more extensive devices, in which case memory mapped I/O registers will occupy a portion of the SRAM.) Even though there are separate addressing schemes and optimized opcodes for register file and I/O register access, all can still be addressed and manipulated as if they were in SRAM. [edit] EEPROM Almost all devices have on-die EEPROM. This is most often used for long-term parameter storage to be retrieved even after cycling the power of the device. [edit] Program Execution Atmel's AVRs have a single level pipeline design. The next machine instruction is fetched as the current one is executing. Most instructions take just one or two clock cycles, making AVRs relatively fast among the eight-bit microcontrollers. The AVR family of processors were designed for the efficient execution of compiled C code. The AVR instruction set is more orthogonal than most eight-bit microcontrollers, however, it is not completely regular: Pointer registers X, Y, and Z have addressing capabilities that are different from each other. Register locations R0 to R15 have different addressing capabilities than register locations R16 to R31. I/O ports 0 to 31 have different addressing capabilities than I/O ports 32 to 63. CLR affects flags, while SER does not, even though they are complementary instructions. CLR set all bits to zero and SER sets them to one. (Note though, that neither CLR nor SER are native instructions. Instead CLR is syntactic sugar for [produces the same machine code as] EOR R,R while SER is syntactic sugar for LDI R,$FF. Math operations such as EOR modify flags while moves/loads/stores/branches such as LDI do not.) [edit] Speed The AVR line can normally support clock speeds from 0-16MHz, with some devices reaching 20MHz. Lower powered operation usually requires a reduced clock speed. All AVRs feature an on-chip oscillator, removing the need for external clocks or resonator circuitry. Because many operations on the AVR are single cycle, the AVR can achieve up to 1MIPS per MHz. [edit] Development AVRs have a large following due to the free and inexpensive development tools available, including reasonably priced development boards and free development software. The AVRs are marketed under various names that share the same basic core but with different peripheral and memory combinations. Some models (notably, the ATmega range) have additional instructions to make arithmetic faster. Compatibility amongst chips is fairly good. See external links for sites relating to AVR development. [edit] Features Current AVRs offer a wide range of features: RISC Core Running Many Single Cycle Instructions Multifunction, Bi-directional I/O Ports with Internal, Configurable Pull-up Resistors Multiple Internal Oscillators Internal, Self-Programmable Instruction Flash Memory up to 256K In-System Programmable using ICSP, JTAG, or High Voltage methods Optional Boot Code Section with Independent Lock Bits for Protection Internal Data EEPROM up to 4KB Internal SRAM up to 8K 8-Bit and 16-Bit Timers PWM Channels & dead time generator Lighting (PWM Specific) Controller models Dedicated I²C Compatible Two-Wire Interface (TWI) Synchronous/Asynchronous Serial Peripherals (UART/USART) (As used with RS-232,RS-485, and more) Serial Peripheral Interface (SPI) CAN Controller Support USB Controller Support Proper High-speed hardware & Hub controller with embedded AVR. Also freely available low-speed (HID) software emulation Ethernet Controller Support Universal Serial Interface (USI) for Two or Three-Wire Synchronous Data Transfer Analog Comparators LCD Controller Support 10-Bit A/D Converters, with multiplex of up to 16 channels Brownout Detection Watchdog Timer (WDT) Low-voltage Devices Operating Down to 1.8v Multiple Power-Saving Sleep Modes picoPower Devices Atmel AVR assembler programming language Atmel AVR machine programming language