please dont rip this site

Microchip Virgilstamps Ee.asm

;  ee.asm

        include <>
; 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
RESET_V		EQU	0x0000		; Address of RESET Vector
ISR_V		EQU	0x0004		; Address of Interrupt Vector

		ORG	RESET_V		; RESET vector location
RESET		GOTO	START                        

		ORG	ISR_V		; Interrupt vector location  
		nop                     ; interrupt service would be here
INIT   	        bsf     STATUS,RP0      ; bank 1
		movlw	b'10010110'
		movwf	TRISC		; rc7= RX rc6= TX rc5=SDO rc4=SDI rc3=SCLK rc1=na rc0=na
		BCF	STATUS, RP0	; bank 0        
		clrf	event

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

START	CALL	INIT                    ; Initialize Processor Registers 
	bsf	event,ee_busy		; read block
	movlw	.0                      ; which block
	movwf	BLK	
POLL    nop
        btfsc   event,ee_busy           ; ee busy?
        call    EE_SERVICE              ; service eeprom if needed

; 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     PORTC           ; EEPROM port
SDA		equ	1               ; EE data
SCL		equ	0		; EE clk
block		equ	0x0A0
blk_size	equ	0x050		; 80 decimal

; VARIABLES defined  in low RAM   Arbitrary as to where you want to put them
event           equ     0x03D           ; 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     0x03E           ; address high byte
ADDR1		equ	0x03F		; address low byte
BLK             equ     0x040           ; block number (0-50)
BLKC            equ     0x041           ; block counter 
blkptr          equ     0x042           ; block pointer
o_data          equ     0x043           ; output data
i_data          equ     0x044           ; input data
ee_cntr4        equ     0x045           ; temp counter
ee_cntr3        equ     0x046           ; temp counter
ee_cntr2        equ     0x047           ; temp counter
ee_cntr1        equ     0x048           ; temp counter
X_DELAY         equ     0x04B           ; delay counter MS
DELAY           equ     0x04C           ; 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      btfss   event,ee_busy   ; busy?
                return                  ; no
                call    EEPRMSVC        ; service eeprom
		btfss	event,ee_busy
                movlw   .10
	        call    X_DELAY500
                goto    EE_SERVICE      ; if yes

EEPRMSVC	btfsc	event,ee_write	; write to ee?
		goto	write_block	; if yes
                goto	read_block      ; no, read a block

write_block     btfsc   event,ee_blk_op ; writing a block now?
		goto	write_busy	; if yes
		bsf	event,ee_blk_op	; no, signal writing a block
                call    set_addr
                movlw   block
		movwf	blkptr       	; addr of block buffer
      		movlw	.10
                movwf   ee_cntr4        ; write 10 groups of 8 bytes each
write_busy	call	low_scl
		call	low_sda
		movlw	blk_size/.10
		movwf	ee_cntr2
		movf	blkptr,w
		movwf	FSR
		call	w_block
                decfsz	ee_cntr4        ; done all groups of 8?
		goto	poll_ack        ; if no
		bcf	event,ee_blk_op ; eeprom block operation done
		bcf	event,ee_write  ; eeprom not writing
		bcf	event,ee_busy   ; eeprom not busy
                goto    delay50ms       ; return after delay

poll_ack        movlw   .100
		movwf	ee_cntr3
ack_loop	decfsz	ee_cntr3
		goto	ack_tst
		goto	err
ack_tst	        call	strt
                movlw	0x0a0
		call	out_byte
                call	wait
		btfsc	PORTC,SDA	; did chip acknowledge?
		goto	clkit           ; if no
                goto    pulse           ; yes, so exit
clkit		call	pulse
                goto	ack_loop        ; poll again

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

w_block         call    strt            ; burst write 8 bytes
		movlw	0x0a0
		call	out_byte
		call	ack
		movf	ADDR0,w         ; ms addr
		call	out_byte
		call	ack
		movf	ADDR1,w         ; ls addr
		call	out_byte
		call	ack
wrtblk		movf	INDF,w          ; byte to write
		call	out_byte
		call	ack
		incf	FSR
		incf	blkptr
		movlw	.1
		addwf	ADDR1           ; EEPROM addr low
		btfsc	STATUS,C
		incf	ADDR0           ; EEPROM addr high
		decfsz	ee_cntr2
		goto	wrtblk
		call	stop

read_block	bsf	event,ee_blk_op	; signal reading a block
                call    set_addr
                call    low_scl
		call	high_sda
		call	high_scl	; idle bus
		movlw	block
		movwf	FSR       	; addr of block buffer
		movlw	blk_size
		movwf	ee_cntr2	; bytes to copy

	        call	strt
		movlw	0x0a0           ; write preface
		call	out_byte
		call	ack
		movf	ADDR0,w         ; ms address
		call	out_byte
		call	ack
		movf	ADDR1,w         ; ls address
		call	out_byte
		call	ack

		call	strt
		movlw	0x0a1
		call	out_byte	; read preface
more_seq	call	ack
		call	in_byte		; fetch the byte
		movf	i_data,w
		movwf	INDF		; copied to current block
		incf	FSR		; point to next address in block
		movlw	.1
		addwf	ADDR1
		btfsc	STATUS,C
		incf	ADDR0
                decfsz	ee_cntr2	; read all bytes?
		goto	more_seq
		call	stop
		bcf	event,ee_blk_op ; block read is done
		bcf	event,ee_busy	; ee not busy

out_byte	movwf	o_data          ; output 8 bits to eeprom
		movlw	.8
		movwf	ee_cntr1
o_loop		rlf	o_data          ; msb to carry
		call	low_sda
		btfsc	STATUS,C        ; is it a 1?
		call	high_sda
		call	pulse
		decfsz	ee_cntr1         ; done?
		goto	o_loop          ; no
		call	high_sda

in_byte		movlw	.8              ; input 8 bits from eeprom
		movwf	ee_cntr1
		call	high_sda
i_loop  	call	high_scl        ; data valid
         	bcf	STATUS,C
		btfsc	PORTC,SDA
		bsf	STATUS,C
		rlf	i_data
		call	low_scl
		call	wait
		decfsz	ee_cntr1
		goto	i_loop

ack		call	high_sda	; acknowledge operation
		btfsc	PORTC,SDA	; bit low?
		goto	force0          ; if no
		goto	pulse		; slave acknowledges
force0		call	low_sda         ; master acknowledges
		call	pulse
		goto	high_sda        ; return as input

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

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

low_sda		call	wait
		BSF     STATUS, RP0	; bank 1
		bcf	TRISC,SDA	; output
		bcf	STATUS, RP0	; bank 0
		goto	wait

high_sda        call	wait
		BSF     STATUS, RP0	; bank 1
		bsf	TRISC,SDA	; input
		bcf	STATUS, RP0	; bank 0
		goto	wait

low_scl		bcf	EE,SCL          ; clock line goes low
high_scl	bsf	EE,SCL          ; clock line goes high

wait		nop                     ; delay for the chip

pulse		call	high_scl        ; one clock pulse
		call	wait
		goto	low_scl

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

set_addr        clrf    ADDR0           ; assume 1st block
		clrf	ADDR1
                movf    BLK,w
                movwf   BLKC
                movf    BLK,w
                btfss   STATUS,Z        ; zero?
                goto    next_addr2      ; if n
                goto    set_done        ; if yes
next_addr2      bcf     STATUS,C        ; set ADDR0 and ADDR1 modulo 80
		movlw	blk_size        ; sizeof block
		addwf	ADDR1,f
                btfsc   STATUS,C        ; overflow?
                incf    ADDR0           ; if yes 
		decfsz	BLKC
                goto    next_addr2      ; if no
set_done        return

; a delay routine

delay50ms       movlw   .100
X_DELAY500	MOVWF	X_DELAY		; +1		1 cycle
X_DELAY500_LOOP	CALL	DELAY500	; step1		wait 500uSec
		DECFSZ	X_DELAY, F	; step2		1 cycle
		GOTO	X_DELAY500_LOOP	; step3		2 cycles
                RETURN                  ; +2            2 cycles

DELAY500        MOVLW   D'165'          ; +1            1 cycle
		MOVWF	DELAY		; +2		1 cycle
DELAY500_LOOP	DECFSZ	DELAY, F	; step 1	1 cycle
		GOTO	DELAY500_LOOP	; step 2	2 cycles
                RETURN                  ; +3            2 cycles

	END				; End of program

file: /Techref/microchip/virgilstamps/ee.asm, 10KB, , updated: 1999/6/12 12:51, local time: 2024/6/16 02:25,

 ©2024 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=""> microchip virgilstamps ee</A>

Did you find what you needed?


Welcome to!


Welcome to!