please dont rip this site

SX Microcontroller EEPROM Memory Method

24C32

by Virgil Stamps converted and optimized for the SX by James Newton

; ee.asm
;	LIST P=16C74A, F=INHX8M
;        __CONFIG _BODEN_OFF & _CP_OFF & _WDT_OFF & _XT_OSC
;
;        include <p16c74a.inc>
;*****************************************************************************
; This application written by Virgil Stamps,  6-12-99
; I had an application that needed configuration files for various modes of operation.
; A 24C32 I2C EEPROM provides 4Kx8 non-volatile storage. A PIC 16C74 is the processor.
; "Creating electronic products for fun and profit." This code is given
; to the public domain. If you need help, email author at stamps@brokersys.com
;*****************************************************************************
PortCTris	equ	%10010110
SDAOnMask	equ	%11111101
SDAOffMask	equ	%00000010

	RESET	START

	
INIT	setb	STATUS.RP0	; bank 1
	mov	M, #$0F
	mov	!RC, #PortCTris
; rc7= RX rc6= TX rc5=SDO rc4=SDI rc3=SCLK rc1=na rc0=na
	clrb	STATUS.RP0	; bank 0
	clr	event
	ret

;*****************************************************************************
; Program start. Simple poll loop. A good place for breakpoint and testing.
;*****************************************************************************

START	call	INIT	; Initialize Processor Registers
	setb	event.ee_busy	; read block
	mov	W, #0	; which block
	mov	BLK, W
POLL	nop
	snb	event.ee_busy	; ee busy?
	call	EE_SERVICE	; service eeprom if needed
	jmp	POLL

; Driver for Microchip 24C32A Serial EEPROM (32K-bit).
; Generic program listing for those seeking information on programming this type EEPROM.
; Approximately 30 ms to read and 80 ms to write a block of 80 bytes.
; The EEPROM is organized as virtual memory accessed by a block number
; and temporarily stored in RAM at BLOCK (0x0A0 - 0x0EF)
; A 32K-bit device has a maximum of 51 blocks. 4,096 bytes / 80 = 51.2 blocks
; A virtual memory location in your application could be defined as BLK (0-50)
; and a offset (0-79).


EE		equ	RC	; EEPROM port
SDA		equ	1	; EE data
SCL		equ	0	; EE clk
block		equ	$0A0
blk_size	equ	$050	; 80 decimal

; VARIABLES defined  in low RAM   Arbitrary as to where you want to put them
event		equ	$03D	; event register where:
ee_busy		equ	2	; service requested  1=busy, 0=idle
ee_write	equ	1	; 1=write, 0=read
ee_blk_op	equ	0	; 1=read or write block operation, 0=idle
ADDR0		equ	$03E	; address high byte
ADDR1		equ	$03F	; address low byte
BLK		equ	$040	; block number (0-50)
BLKC		equ	$041	; block counter
blkptr		equ	$042	; block pointer
o_data		equ	$043	; output data
i_data		equ	$044	; input data
ee_cntr4	equ	$045	; temp counter
ee_cntr3	equ	$046	; temp counter
ee_cntr2	equ	$047	; temp counter
ee_cntr1	equ	$048	; temp counter
X_DELAY		equ	$04B	; delay counter MS
DELAY		equ	$04C	; delay counter LS


;*****************************************************************************
; This application burst mode writes 10 groups of 8-bytes each.
; The read function block reads 80-bytes in a loop.
; To write the 80 bytes at block, set BLK= block number in EEPROM, set event,ee_busy,
; set event,ee_write, call EE_SERVICE.
; To read 80 bytes to block from EEPROM, set BLK= block number in EEPROM,
; set event,ee_busy, clear event,ee_write, call EE_SERVICE.
; on return:  event,ee_busy is zero, event,ee_block is zero.
;*****************************************************************************

EE_SERVICE
	sb	event.ee_busy	; busy?
	ret	; no
	call	EEPRMSVC	; service eeprom
	sb	event.ee_busy
	jmp	EE_SERVICE
	mov	W, #10
	call	X_DELAY500
	jmp	EE_SERVICE	; if yes

EEPRMSVC
	snb	event.ee_write	; write to ee?
	jmp	write_block	; if yes
	jmp	read_block	; no, read a block

write_block
	snb	event.ee_blk_op	; writing a block now?
	jmp	write_busy	; if yes
	setb	event.ee_blk_op	; no, signal writing a block
	call	set_addr
	mov	W, #block
	mov	blkptr, W	; addr of block buffer
	mov	W, #10
	mov	ee_cntr4, W	; write 10 groups of 8 bytes each
write_busy
	call	low_scl
	call	low_sda
	mov	W, #blk_size/10
	mov	ee_cntr2, W
	mov	W, blkptr
	mov	FSR, W
	call	w_block
	decsz	ee_cntr4	; done all groups of 8?
	jmp	poll_ack	; if no
	clrb	event.ee_blk_op	; eeprom block operation done
	clrb	event.ee_write	; eeprom not writing
	clrb	event.ee_busy	; eeprom not busy
	jmp	delay50ms	; return after delay

poll_ack
	mov	W, #100
	mov	ee_cntr3, W
ack_loop
	decsz	ee_cntr3
	jmp	ack_tst
	jmp	err
ack_tst
	call	strt
	mov	W, #$0a0
	call	out_byte
	call	wait
	snb	RC.SDA	; did chip acknowledge?
	jmp	clkit	; if no
	jmp	pulse	; yes, so exit
clkit
	call	pulse
	jmp	ack_loop	; poll again

err
	nop	; EEPROM is bad  (add your own error recovery)
	jmp	err	; eeprom did not respond in 100 tries


w_block
	call	strt	; burst write 8 bytes
	mov	W, #$0a0
	call	out_byte
	call	ack
	mov	W, ADDR0	; ms addr
	call	out_byte
	call	ack
	mov	W, ADDR1	; ls addr
	call	out_byte
	call	ack
wrtblk
	mov	W, INDF	; byte to write
	call	out_byte
	call	ack
	inc	FSR
	inc	blkptr
	mov	W, #1
	add	ADDR1, W	; EEPROM addr low
	snb	C
	inc	ADDR0	; EEPROM addr high
	decsz	ee_cntr2
	jmp	wrtblk
	call	stop
	ret

read_block
	setb	event.ee_blk_op	; signal reading a block
	call	set_addr
	call	low_scl
	call	high_sda
	call	high_scl	; idle bus
	mov	W, #block
	mov	FSR, W	; addr of block buffer
	mov	W, #blk_size
	mov	ee_cntr2, W	; bytes to copy

	call	strt
	mov	W, #$0a0	; write preface
	call	out_byte
	call	ack
	mov	W, ADDR0	; ms address
	call	out_byte
	call	ack
	mov	W, ADDR1	; ls address
	call	out_byte
	call	ack

	call	strt
	mov	W, #$0a1
	call	out_byte	; read preface
more_seq
	call	ack
	call	in_byte	; fetch the byte
	mov	W, i_data
	mov	INDF, W	; copied to current block
	inc	FSR	; point to next address in block
	mov	W, #1
	add	ADDR1, W
	snb	C
	inc	ADDR0
	decsz	ee_cntr2	; read all bytes?
	jmp	more_seq
	call	stop
	clrb	event.ee_blk_op	; block read is done
	clrb	event.ee_busy	; ee not busy
	ret

out_byte
	mov	o_data, W	; output 8 bits to eeprom
	mov	W, #8
	mov	ee_cntr1, W
o_loop
	rl	o_data	; msb to carry
	call	low_sda
	snb	C	; is it a 1?
	call	high_sda
	call	pulse
	decsz	ee_cntr1	; done?
	jmp	o_loop	; no
	call	high_sda
	ret

in_byte
	mov	W, #8	; input 8 bits from eeprom
	mov	ee_cntr1, W
	call	high_sda
i_loop
	call	high_scl	; data valid
	clrb	C
	snb	RC.SDA
	setb	C
	rl	i_data
	call	low_scl
	call	wait
	decsz	ee_cntr1
	jmp	i_loop
	ret

ack
	call	high_sda	; acknowledge operation
	snb	RC.SDA	; bit low?
	jmp	force0	; if no
	jmp	pulse	; slave acknowledges
force0
	call	low_sda	; master acknowledges
	call	pulse
	jmp	high_sda	; return as input

strt
	call	high_sda
	call	high_scl
	call	low_sda	; strt condition
	jmp	low_scl

stop
	call	low_sda
	call	high_scl
	call	high_sda	; stop condition
	jmp	low_scl

low_sda
	call	wait
	setb	STATUS.RP0	; bank 1
	mov	M, #$0F
	mov	!RC, #PortCTris | SDAOnMask
; rc1=SDA rc0=SCL
	clrb	STATUS.RP0	; bank 0
	clrb	RC.SDA
	jmp	wait

high_sda	call	wait
	setb	STATUS.RP0	; bank 1
	mov	M, #$0F
	mov	!RC, #PortCTris & SDAOffMask
; rc1=SDA rc0=SCL
	clrb	STATUS.RP0	; bank 0
	setb	RC.SDA
	jmp	wait

low_scl
	clrb	EE.SCL	; clock line goes low
	ret
high_scl
	setb	EE.SCL	; clock line goes high
	ret

wait
	nop	; delay for the chip
	nop
	nop
	nop
	ret

pulse
	call	high_scl	; one clock pulse
	call	wait
	jmp	low_scl


; subroutine to compute block address: addr = n * 80

set_addr
	clr	ADDR0	; assume 1st block
	clr	ADDR1
	mov	W, BLK
	mov	BLKC, W
	mov	W, BLK
	sb	Z	; zero?
	jmp	next_addr2	; if n
	jmp	set_done	; if yes
next_addr2
	clrb	C	; set ADDR0 and ADDR1 modulo 80
	mov	W, #blk_size	; sizeof block
	add	ADDR1, W
	snb	C	; overflow?
	inc	ADDR0	; if yes
	decsz	BLKC
	jmp	next_addr2	; if no
set_done
	ret

; a delay routine

delay50ms
	mov	W, #100
X_DELAY500
	mov	X_DELAY, W	; +1		1 cycle
X_DELAY500_LOOP
	call	DELAY500	; step1		wait 500uSec
	decsz	X_DELAY	; step2		1 cycle
	jmp	X_DELAY500_LOOP	; step3		2 cycles
	ret	; +2            2 cycles

DELAY500
	mov	W, #165	; +1            1 cycle
	mov	DELAY, W	; +2		1 cycle
DELAY500_LOOP
	decsz	DELAY	; step 1	1 cycle
	jmp	DELAY500_LOOP	; step 2	2 cycles
	ret	; +3            2 cycles

	END				; End of program


See also:


file: /Techref/scenix/lib/mem/24c32.htm, 8KB, , updated: 2004/6/10 13:40, local time: 2022/1/27 21:15,
TOP NEW HELP FIND: 
107.21.85.250:LOG IN

 ©2022 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://www.sxlist.com/techref/scenix/lib/mem/24c32.htm"> SX Microcontroller 24C32 EEPROM Memory Method</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

 

Welcome to sxlist.com!


Site supported by
sales, advertizing,
& kind contributors
just like you!

Please don't rip/copy
(here's why

Copies of the site on CD
are available at minimal cost.
 

Welcome to www.sxlist.com!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .