;**** A P P L I C A T I O N   N O T E   A V R 1 0 0  ************************
;*
;* Title:		Accessing the EEPROM
;* Version:		2.0
;* Last updated:	98.06.15
;* Target:		AT90Sxxxx (All AVR Devices)
;*
;* Support E-mail:	avr@atmel.com
;*
;* DESCRIPTION
;* This Application note shows how to read data from and write data to the
;* EEPROM. Both random access and sequential access routines are listed.
;* The code is written for 8515, to modify for 4414,2313,2323... apply the 
;* following changes:
;*	- Remove all entries to EEARH
;*	- Rename EEARL to EEAR
;*
;* To modify for 1200, apply the changes above, and change the code
;* as commented inside the routines	
;*
;*
;***************************************************************************
.include "8515def.inc"

	rjmp	RESET		;Reset Handle
	
;***************************************************************************
;* 
;* EEWrite
;*
;* This subroutine waits until the EEPROM is ready to be programmed, then
;* programs the EEPROM with register variable "EEdwr" at address "EEawr:EEawr"
;*
;* Number of words	:1200 ; 5 + return
;*			:8515 ; 7 + return
;* Number of cycles	:1200 ; 8 + return (if EEPROM is ready)
;*			:8515 ; 11 + return (if EEPROM is ready)
;* Low Registers used	:None
;* High Registers used:	;3 (EEdwr,EEawr,EEawrh)
;*
;***************************************************************************

;***** Subroutine register variables

.def	EEdwr	=r16		;data byte to write to EEPROM
.def	EEawr	=r17		;address low byte to write to
.def	EEawrh	=r18		;address high byte to write to

;***** Code

EEWrite:
	sbic	EECR,EEWE	;if EEWE not clear
	rjmp	EEWrite		;    wait more

;	out	EEAR,EEawr	;output address for 1200, commented out !

; the two following lines must be replaced with the line above if 1200 is used
	out 	EEARH,EEawrh	;output address high for 8515
	out	EEARL,EEawr	;output address low for 8515
		

	out	EEDR,EEdwr	;output data
	sbi 	EECR,EEMWE	;set master write enable, remove if 1200 is used	
	sbi	EECR,EEWE	;set EEPROM Write strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	ret

;***************************************************************************
;* 
;* EERead
;*
;* This subroutine waits until the EEPROM is ready to be programmed, then
;* reads the register variable "EEdrd" from address "EEardh:EEard"
;*
;* Number of words	:1200 ; 5 + return
;*			:8515 ; 6 + return
;* Number of cycles	:1200 ; 8 + return (if EEPROM is ready)
;*			:8515 ; 9 + return (if EEPROM is ready)
;* Low Registers used	:1 (EEdrd)
;* High Registers used:	:2 (EEard,EEardh)
;*
;***************************************************************************

;***** Subroutine register variables

.def	EEdrd	=r0		;result data byte
.def	EEard	=r17		;address low to read from
.def	EEardh	=r18		;address high to read from

;***** Code

EERead:
	sbic	EECR,EEWE	;if EEWE not clear
	rjmp	EERead		;    wait more
;	out	EEAR,EEard	;output address for 1200, commented out !

; the two following lines must be replaced with the line above if 1200 is used
	out 	EEARH,EEardh	;output address high for 8515
	out	EEARL,EEard	;output address low for 8515


	sbi	EECR,EERE	;set EEPROM Read strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	in	EEdrd,EEDR	;get data
	ret

		
;***************************************************************************
;* 
;* EEWrite_seq
;*
;* This subroutine increments the EEPROM address by one and waits until the 
;* EEPROM is ready for programming. It then programs the EEPROM with 
;* register variable "EEdwr_s".

;* Number of words	:1200 ; 7 + return
;*			:8515 ; 10 + return
;* Number of cycles	:1200 ; 10 + return (if EEPROM is ready)
;*			:8515 ; 15 + return (if EEPROM is ready)
;* Low Registers used	:None
;* High Registers used:	:3 (EEdwr_s,EEwtmp,EEwtmph)
;*
;***************************************************************************

;***** Subroutine register variables

.def	EEwtmp	=r24		;temporary storage of address low byte
.def	EEwtmph	=r25		;temporary storage of address high byte
.def	EEdwr_s	=r18		;data to write

;***** Code

EEWrite_seq:
	sbic	EECR,EEWE	;if EEWE not clear
	rjmp	EEWrite_seq	;   wait more

; Write sequence for 1200
;	in	EEwtmp,EEAR	;get address for 1200, commented out !
;	inc 	EEwtmp		;increment address 1200, commented out !
;	out	EEAR,EEwtmp	;output address 1200

; Write sequence for 8515, must be replaced with the lines above if 1200 is used
	in	EEwtmp,EEARL	;get address low 8515
	in	EEwtmph,EEARH	;get address high 8515	
 	adiw	EEwtmp,0x01	;increment address 8515
	out	EEARL,EEwtmp	;output address 8515
	out	EEARH,EEwtmph	;output address 8515
	

	out	EEDR,EEdwr_s	;output data
	sbi 	EECR,EEMWE	;set master write enable, remove if 1200 is used	
	sbi	EECR,EEWE	;set EEPROM Write strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	ret

;***************************************************************************
;* 
;* EERead_seq
;*
;* This subroutine increments the address stored in EEAR and reads the 
;* EEPROM into the register variable "EEdrd_s".

;* Number of words	:1200 ; 5 + return
;*			:8515 ; 7 + return
;* Number of cycles	:1200 ; 8 + return (if EEPROM is ready)
;*			:8515 ; 11 + return (if EEPROM is ready)
;* Low Registers used	:1 (EEdrd_s)
;* High Registers used:	:2 (EErtmp,EErtmph)
;*
;***************************************************************************

;***** Subroutine register variables

.def	EErtmp	=r24		;temporary storage of low address
.def	EErtmph	=r25		;temporary storage of high address
.def	EEdrd_s	=r0		;result data byte

;***** Code

EERead_seq:
	sbic	EECR,EEWE	;if EEWE not clear
	rjmp	EERead_seq	;   wait more
; The above sequence for EEWE = 0 can be skipped if no write is initiated.

; Read sequence for 1200
;	in	EErtmp,EEAR	;get address for 1200, commented out !
;	inc 	EErtmp		;increment address 1200, commented out !
;	out	EEAR,EErtmp	;output address 1200

; Read sequence for 8515, must be replaced with the lines above if 1200 is used
	in	EErtmp,EEARL	;get address low 8515
	in	EErtmph,EEARH	;get address high 8515	
	adiw	EErtmp,0x01	;increment address 8515
	out	EEARL,EErtmp	;output address 8515
	out	EEARH,EErtmph	;output address 8515


	sbi	EECR,EERE	;set EEPROM Read strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	in	EEdrd_s,EEDR	;get data
	ret



;****************************************************************************
;*
;* Test/Example Program
;*
;****************************************************************************

;***** Main Program Register variables

.def	counter	=r19
.def	temp	=r20

;***** Code

RESET:
;***** Initialize stack pointer
;* Initialize stack pointer to highest address in internal SRAM
;* Comment out for devices without SRAM

	ldi	r16,high(RAMEND) ;High byte only required if 
	out	SPH,r16	         ;RAM is bigger than 256 Bytes
	ldi	r16,low(RAMEND)	 
	out	SPL,r16


;***** Program a random location

	ldi	EEdwr,$aa
	ldi	EEawrh,$00
	ldi	EEawr,$10
	rcall	EEWrite		;store $aa in EEPROM location $0010

;***** Read from a random locations

	ldi	EEardh,$00
	ldi	EEard,$10
	rcall	EERead		;read address $10
	out	PORTB,EEdrd	;output value to Port B

;***** Fill the EEPROM address 1..64 with bit pattern $55,$aa,$55,$aa,...

	ldi	counter,63	;init loop counter
	clr 	temp
	out	EEARH,temp	;EEARH <- $00
	clr	temp		
	out	EEARL,temp	;EEAR <- $00 (start address - 1)

loop1:	ldi	EEdwr_s,$55	
	rcall	EEWrite_seq	;program EEPROM with $55
	ldi	EEdwr_s,$aa		
	rcall	EEWrite_seq	;program EEPROM with $aa
	dec	counter		;decrement counter
	brne	loop1		;and loop more if not done

;***** Copy 10 first bytes of EEPROM to r1-r11

	clr 	temp
	out	EEARH,temp	;EEARH <- $00
	ldi	temp,$00	
	out	EEARL,temp	;EEAR <- $00 (start address - 1)

	clr 	ZH
	ldi	ZL,1		;Z-pointer points to r1

loop2:	rcall	EERead_seq	;get EEPROM data
	st	Z,EEdrd_s	;store to SRAM
	inc	ZL
	cpi	ZL,12		;reached the end?
	brne	loop2		;if not, loop more

forever:rjmp	forever		;eternal loop