;**** A P P L I C A T I O N   N O T E   A V R 1 0 0 ************************
;*
;* Title:		Accessing the AT90S1200 EEPROM
;* Version:		1.20
;* Last updated:	97.07.17
;* Target:		AT90S1200
;*
;* Support E-mail:	avr@atmel.com
;*
;* DESCRIPTION
;* This Application note shows how to read data from and write data to the
;* AT90S1200 EEPROM. Both random access and sequential access routines are 
;* listed.
;*
;* For all other devices a master write enable bit EEMWE must be set prior 
;* to setting the EEWE bit.
;*
;***************************************************************************
.include "1200def.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"
;*
;* Number of words	:5 + return
;* Number of cycles	:10 + return (if EEPROM is ready)
;* Low Registers used	:None
;* High Registers used:	;2 (EEdwr,EEawr)
;*
;***************************************************************************

;***** Subroutine register variables

.def	EEdwr	=r16		;data byte to write to EEPROM
.def	EEawr	=r17		;address to write to

;***** Code

EEWrite:
	sbic	EECR,EEWE	;if EEWE not clear
	rjmp	EEWrite		;    wait more
	out	EEAR,EEawr	;output address
	out	EEDR,EEdwr	;output data
	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 "EEard"
;*
;* Number of words	:6 + return
;* Number of cycles	:12 + return (if EEPROM is ready)
;* Low Registers used	:1 (EEdrd)
;* High Registers used:	:1 (EEard)
;*
;***************************************************************************

;***** Subroutine register variables

.def	EEdrd	=r0		;result data byte
.def	EEard	=r16		;address to read from

;***** Code

EERead:
	sbic	EECR,EEWE	;if EEWE not clear
	rjmp	EERead		;    wait more
	out	EEDR,EEard	;output address
	sbi	EECR,EERE	;set EEPROM Read strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	sbi	EECR,EERE	;set EEPROM Read strobe 2nd time
				;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	:7 + return
;* Number of cycles	:10 + return (if EEPROM is ready)
;* Low Registers used	:1 (EEWtmp)
;* High Registers used:	:1 (EEdwr_s)
;*
;***************************************************************************

;***** Subroutine register variables

.def	EEwtmp	=r0		;temporary storage of address
.def	EEdwr_s	=r16		;data to write

;***** Code

EEWrite_seq:
	sbic	EECR,EEWE	;if EEWE not clear
	rjmp	EEWrite_seq	;    wait more
	in	EEwtmp,EEAR	;get address
	inc	EEwtmp		;increment address
	out	EEAR,EEwtmp	;output address
	out	EEDR,EEdwr_s	;output data
	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	:6 + return
;* Number of cycles	:12 + return (if EEPROM is ready)
;* Low Registers used	:2 (EErtmp,EEdrd_s)
;* High Registers used:	:None
;*
;***************************************************************************

;***** Subroutine register variables

.def	EErtmp	=r0		;temporary storage of address
.def	EEdrd_s	=r1		;result data byte

;***** Code

EERead_seq:
	in	EErtmp,EEAR	;get address
	inc	EErtmp		;increment address
	out	EEAR,EErtmp	;output address
	sbi	EECR,EERE	;set EEPROM Read strobe
				;This instruction takes 4 clock cycles since
				;it halts the CPU for two clock cycles
	sbi	EECR,EERE	;set EEPROM Read strobe 2nd time
				;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	=r18
.def	temp	=r19

;***** Code

RESET:


;***** Program a random location

	ldi	EEdwr,$aa
	ldi	EEawr,$10
	rcall	EEWrite		;store $aa in EEPROM location $10

;***** Read from a random locations

	ldi	EEard,$10
	rcall	EERead		;read address $10
	out	PORTB,EEdrd	;output value to Port B

;***** Fill the EEPROM with bit pattern $55,$aa,$55,$aa,...

	ldi	counter,64	;init loop counter
	ser	temp		
	out	EEAR,temp	;EEAR <- $ff (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 r2-r11

	ldi	temp,$ff	
	out	EEAR,temp	;EEAR <- $ff (start address - 1)

	ldi	ZL,2		;Z-pointer points to r2

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
