;*****************************************************************************
;
;       8051- Programm fuer ATMEL Flash- Mikrocontroller AT89S53
;	
;	Teilprogramm for ZSTG, wird durch INCLUDE eingebunden
;
;       Autor: Andreas Hoeger
;       Datum: 16.09.2000		
;
; 	14_02_02: initial version for ZSTG
;	26_02_03: removed read random and read random internal because 
;		  not needed without EEPROM and to make BIT06 unused.
;       rr_tt_zz: 
;
;*****************************************************************************

        ;*********************************************************************
        ; Unterprogramme fuer I2C- Bus
        ;*********************************************************************

write_byte_internal:

	; I2C-Bus Byte Write function for EEPROM (adr & data).
	; Called with address in I2CADR_H:I2CADR_L. Data in I2C_DATA.
	; Device ID in I2C_ID.
	; Does not wait for write cycle to complete.
	; Destroys A.

	; includes 10 ms waiting time

	call	start

	mov	a,I2C_ADR_H	; 
	rl	a		; programmable address to bits 3:1
	orl	a,I2C_ID	; add fixed address
	clr	acc.0		; specify write operation
	call	shout		; send device address

	mov	a,I2C_ADR_L	; send low byte of address
	call	shout		;

	mov	a,I2C_DATA	; get data
	call	shout		; send data

	call	stop
	call	zehn_ms

	ret

read_ds_random_2byte:

	; I2C Random Read function for two bytes from ds1621.
	; Called with programmable address as "write byte". 
	; Returns first data byte in TEMP_H.
	; Returns second data byte in TEMP_L.

	mov	a,I2C_ADR_H

	; Send dummy write command to set internal address.

	call	start

	rl	a		; programmable address to bits 3:1
	orl	a,I2C_ID	; add fixed address
	clr	acc.0		; specify write operation
	call	shout		; send device address

	mov	a,I2C_ADR_L	; send low byte of address
	call	shout		;

	call	start

	mov	a,I2C_ADR_H
	rl	a		; programmable address to bits 3:1
	orl	a,I2C_ID	; add fixed address
	setb	acc.0		; specify read operation

	call	shout		; send device address
	call	shin		; receive first data byte
				; data is returned in A
	mov	TEMP_H,A
	call	ACK		; acknowledge first byte

	call	shin		; receive second data byte
				; data is returned in A
	mov	TEMP_L,A
	call	NAK		; do not acknowledge byte
	call	stop
	ret

start:
	; Send START, defined as high-to-low SDA with SCL high.
	; Return with SCL, SDA low.
	; Sets Error Code if bus is not available.

	setb	SDA
	setb	SCL

	; Verify bus available.

	jnb	SDA, x40	; jump if not high
	jnb	SCL, x40	; jump if not high
	nop			; enforce setup delay and cycle delay
	clr	SDA
	mov	R7,#6		; enforce hold delay

wait_start:	
	
	nop	
	djnz	R7,wait_start
	clr	SCL
	jmp	x41

x40:	mov	ERROR,#EW_IIC_NOT_READY	; I2C-Bus-Fehler eintragen
	call	errorcode_out

x41:	ret

stop:
	; Send STOP, defined as low-to-high SDA with SCL high.
	; SCL expected low on entry. Return with SCL, SDA high.

	clr	SDA
	nop			; enforce SCL low and data setup
	nop
	setb	SCL
	mov	R7,#6		; enforce setup delay
wait_stop:	
	nop	
	djnz	R7,wait_stop
	setb	SDA
	ret

shout:
	; Shift out a byte to the I2C-bus, most significant bit first.
	; SCL, SDA expected low on entry. Return with SCL low.
	; Called with data to send in A.
	; Sets Error Code to indicate failure by slave to acknowledge.
	; Destroys A.

	push	b
	mov	b, #8		; bit counter
x42:	nop
	rlc	a		; move bit into CY
	mov	SDA, c		; output bit
	nop			; enforce SCL low and data setup
	nop
	nop
	setb	SCL		; raise clock
	nop			; enforce SCL high
	nop			;
	nop			;
	nop			;
	nop			;
	nop			;
	clr	SCL		; drop clock
	djnz	b, x42		; next bit
	setb	SDA		; release SDA for ACK
	nop			; enforce SCL low and tAA
	nop			;
	setb	SCL		; raise ACK clock
	nop			; enforce SCL high
	nop			;
	nop			;
	nop			;
	mov	c, SDA		; get ACK bit
	nop
	nop
	clr	SCL		; drop ACK clock
	jnc	x42a		; Low=ACK from slave i.o.

	mov	ERROR,#EW_IIC_BYTESEND_ACK	; I2C-Bus-Fehler eintragen
	call	errorcode_out

x42a:	pop	b
	ret

shin:
	; Shift in a byte from the I2C-bus, most significant bit first.
	; SCL expected low on entry. Return with SCL low.
	; Returns received data byte in A.

	setb	SDA		; make SDA an input
	push	b
	mov	b, #8		; bit count
x43:
	nop			; enforce SCL low and data setup
	nop			;
	nop			;
	setb	SCL		; raise clock
	nop			; enforce SCL high
	nop
	nop			;
	nop
	mov	c, SDA		; input bit
	rlc	a		; move bit into byte
	nop
	nop
	clr	SCL		; drop clock
	djnz	b, x43		; next bit
	pop	b
	ret

ACK:
	; Clock out an acknowledge bit (low).
	; SCL expected low on entry. Return with SCL, SDA low.

	clr	SDA		; ACK bit
	nop			; enforce SCL low and data setup
	nop			;
	setb	SCL		; raise clock
	mov	R7,#6		; enforce SCL high
wait_ack:	
	nop	
	djnz	R7,wait_ack
	clr	SCL		; drop clock
	ret


NAK:
	; Clock out a negative acknowledge bit (high).
	; SCL expected low on entry. Return with SCL low, SDA high.

	setb	SDA		; NAK bit
	nop			; enforce SCL low and data setup
	nop			;
	setb	SCL		; raise clock
	mov	R7,#6		; enforce SCL high
wait_nak:	
	nop	
	djnz	R7,wait_nak
	clr	SCL		; drop clock
	ret

;*****************************************************************************
; ENDE DES QUELLTEXTES
;*****************************************************************************

