please dont rip this site

Scenix Lib IO OSI2 I2C I2CS_VP.SRC

;=======================================================================
; 	INTER - INTEGRATED CIRCUIT (I2C) SERIAL INTERFACE 
;			VIRTUAL PERIPHERAL
;	I2CSDO1.SRC -- I2CS (Authentic I2C Slave) VP Demo #1
;	Revision X1.01, 08.14.98
;	Developed by Authentic Engineering for Scenix Semiconductor, Inc.
;	Authentic Engineering // http://www.authenticeng.com // ak@silcom.com
;
;	We consider this revision as a Beta version, and would appreciate
;	any feedback and recommendation on the improvements of this VP.	
;=======================================================================
;=======================================================================
;
;	Authentic I2CS (I2CS Slave) Virtual Peripheral
;
;	I2CS is a part of the Authentic SPI virtual peripherals for SX micro.
;	This VP provides the means to connect the SX microcontroller to the 
;	I2C Bus. It supports data transfer in 10-bit address mode at clock 
;	rates up to 1.8MHz. It supports transfer of only one byte at a time.	
;
;	------ Communication Protocol -----
;
;	I2C Bus protocol was introduced more than ten years ago. Original 
;	I2CS protocol (with seven bit address and clock frequency up to 
;	0.2 MHz) is widely used by the industry. However, some extensions 
;	of this protocol were developed in order to provide wider address 
;	space and faster transfer rate. For more details please refer to 
;	I2C Peripherals for Microcontrollers Data Handbook, published by
;	Philips Semiconductors in 1992.
;
;	I2CS complies with extension of the I2C protocol - 10 bit address
;	and fast clock rate of 400 KHz (in fact data transfer rate may
;	be as high as 1.8 Mb/s). I2CS does not support GENERAL CALL 
;	command on the I2C Bus. I2CS does not support CBUS protocol.
;	I2CS also does not support original 7-bit address protocol,
;	however it can be easily modified to work in 7-bit address mode.
;
;	Authentic I2CS VP supports I2C Bus communication protocol, 
;	recommended by Philips for software implementations of I2C 
;	Slaves.	According to this protocol data transfer cycle includes 
;	next steps:
;
;	1. I2C Bus Master generates S (start condition) and then generates
;	Start Byte - special byte used only to establish communication
;	with slow responding, software driven I2C devices. Start Byte is -
;	01h.
; 
;	I2C Slave monitors the SDA line often enough to detect the 
;	long SDA line LOW state associated with 01h byte. When this event 
;	on the Bus is detected the Slave starts to monitor the SDA line 
;	often enough to detect Sr (start repeat) condition. Slave  
;	should not generate ACK signal in response to Start Byte.
;
;	2. Master generates Sr (start repeat) condition. Sr condition
;	is detected by Slave and Slave starts to receive the address from 
;	the Master.
;
;	3. Master sends to Slave two byte of address information. If the
;	address information matches Slave address, the Slave must 
;	generate ACK signals for each of two bytes.
;	
;	First byte is 1111 0SS(r/w), where SS are two MSBs of 10-bit Slave 
;	address, R/W is the transfer direction bit. R/W=1 corresponds to 
;	data transfer from Slave to Master.
;
;	Second Byte contains simply eight bits of Slave Bus address
;
;	4. Data are transferred to/from Master. When the data are transferred
;	to Slave the Slave generates the ACK signal.
;
;	5. Master generates P (Stop) condition.
;	
;	6. Transfer can be interrupted at any time by Sr or P (Stop) signals
;	generated by Master. To detect these situations Slave monitors SDA line
;	during each SCL HIGH state.
;
;	It is worth mentioning that the I2CS protocol was developed having
;	in mind easy hardware implementation. The software implementation
;	of this protocol is relatively complicated. Specifically - the software 
;	must assure correct response on Start and Stop conditions on the bus.
;	It may contradict with other software functions. In this case we recommend
;	to develop relatively simple hardware extension to support this protocol.
;
;	----- Timing considerations ------
;
;	I2CS must sample the SDA line often enough to assure detection of Start Byte.
;	The minimum sampling depends on Bus Clock frequency. For the clock
;	frequency of 400 KHz the sampling period should not be more than 18 usec.
;	I2CS must be called by MAIN program at least every 18 usec. The I2CS will 
;	exit within 180 nsec in the case when SDA LOW state is not detected.
;	So, the sampling of the SDA Bus occupies only 1% of CPU time.
;
;	When the SDA LOW state is detected, the I2CS will wait for 30 usec or until
;	the Sr condition is detected. This waiting time is controlled by 
;
;		I2CS_START_TIMEOUT. 
;		F0h value corresponds to 30 usec waiting time. 
;	
;	In order to prevent I2CS locking in case of I2C Bus faults (like absents of 
;	Clock signal), the I2CS VP make use of timeout timer. This timer is initiated 
;	whenever the I2CS comes into some wait state. When the timeout timer expires
;	data transfer will be terminated by Slave. The waiting time is always the 
;	same and is controlled by
;
;		I2CS_CLK_TIMEOUT. 50 (decimal) value corresponds to 6 usec.
;	 
;	------ Address ------
;
;	I2CS provides direct memory access for the Master. The RAM space, 
;	accessible from the Master is limited to one bank - 16 bytes. This 
;	IO_RAM Bank can be randomly addressed by the Master and is used as a 
;	mail box between Bus Master and user application program, running on
;	the Slave. 
;
;	The I2C Bus address of I2CS consists of 10 bits, four LSbits are
;	used to address corresponding bytes in the IO_RAM bank. Upper six bits 
;	are user defined and represent the I2CS Bus address - (we call it Bus ID). 
;	I2CS 10-bit Bus ID consists of two parts. One is the address of the
;	The IO_RAM bank itself is defined by Slave MAIN program.
;	The address of I2CS is defined by next bytes:
;
;	I2CS_IO_RAM	
;	Defines the base address of the BANK. Must be one of 10h, 30h....
;					
;	I2CS_ID_MASK_MSB
;
;	Must be 1111 0SS0. Five MSBs are pointing that it is 10-bit address mode
;	two bits SS are  first two bits of 10-bit bus address. Last bit is zero.
;
;	I2CS_ID_MASK_LSB
;
;	Four MSBs define the Slave I2C Bus address. Four LSBs, must be zero.
;	
;	Example:
;	Two address bytes send by Master:  1  1  1  1  0  s10  s9  1
;				 	  s8 s7 s6 s5 r4 r3   r2 r1
;	will address location r4 r3 r2 r1 of the Slave IO_RAM in the case when
;	Slave MASK_MSB and MASK_LSB will contain bits S10-S5 on corresponding 
;	positions:
;		I2CS_ID_MASK_MSB	  1  1  1  1  0  s10  s9  0
;		I2CS_ID_MASK_LSB	  s8 s7 s6 s5 0  0    0   0
;
;	
;	------- I/O pin configuration -------
;
;	I2CS makes use of three pins. 
;	SCL line pin in always configured as an input. 
;	SDA input pin is always configured as input.
;	SDA output pin is dynamically reconfigured from input to output state.
;	I2CS make use of PortB only, However, it is relatively easy to change the
;	the program so that it will work with any other port. The port configuration 
;	is controlled by next data:
;
;	I2CS_SCL_PIN		pointer to SCL pin
;	I2CS_SDA_IN_PIN		pointer to SDA input pin
;	I2CS_SDA_OUT_PIN	pointer to SDA output pin
;	I2CS_PORT_RX_MASK	image of PortB direction register
;				in receive mode
;	I2CS_PORT_TX_MASK	image of port direction register
;				in transmit mode
;
;	------- Entry points ------
;
;	I2CS VP has two entry points:
;
;	I2CS_INIT - an entry point of the subroutine, which will provide
;	correct configuration of the PortB.
;
;	I2CS_EXECUTE - an entry point of the I2CS VP.
;
;	------ Control and status data ------
;
;	The following is a list of all I2CS control parameters (described above)
;
;	I2CS_START_TIMEOUT. F0h value corresponds to 30 usec waiting time. 
;
;	I2CS_CLK_TIMEOUT. 50 (decimal) value corresponds to 6 usec.
;
;	I2CS_IO_RAM	
;	Defines the base address of the BANK. Must be one of 10h, 30h....
;					
;	I2CS_ID_MASK_MSB
;	I2CS_ID_MASK_LSB	Two byte mask of I2CS Bus ID.
;
;	I2CS_SCL_PIN		pointer to SCL pin
;	I2CS_SDA_IN_PIN		pointer to SDA input pin
;	I2CS_SDA_OUT_PIN	pointer to SDA output pin
;	I2CS_PORT_RX_MASK	image of PortB direction register
;				in receive mode
;	I2CS_PORT_TX_MASK	image of port direction register
;				in transmit mode
;
;	I2CS provides the feed back to the user program with a help of two bytes
;	- I2CS_STATUS and I2CS_FSR.
;
;	I2CS_FSR contains the image of FSR register for the last byte transferred
;  
;	I2CS_STATUS/Bit.0 -	I2CS_READY
;	Set by I2CS when data reception was accomplished. Should be cleared by MAIN 
;	program. Acts as a flag indicating that byte was written by Master.
;
;	I2CS_STATUS/Bit.1 -	I2CS_OVERFLOW
;	Warning, set by I2CS when the data were written by I2C Bus Master 
;	before the previous data have been processed by MAIN (before 
;	I2CS_READY flag was cleared).
;
;	I2CS_STATUS/Bit.3 -	I2CS_STOP_EVENT
;	Set when transfer was aborted because of Stop event.
;
;	I2CS_STATUS/Bit.4 -	I2CS_START_REPEAT_EVENT
;	Set when Sr event occurred during the data transfer.
;
;	I2CS_STATUS/Bit.5 -	I2CS_TIMEOUT
;	Set when transfer was aborted because of expiration of TIMEOUT TIMER.
;
;	I2CS_STATUS/Bit.6 -	I2CS_RECEIVE_TRANSMIT
;	Set when last transfer was transmission to Master.
;
;	I2CS_STATUS/Bit.7 -	I2CS_TRANSFER_ERROR
;	Set when transfer was aborted by either timeout or P events.
;
;	------ How to use I@CS from the user program ------
;
;	1. Initialize all control data
;	2. Call I2CS_INIT to initialize the Port (optional)
;	3. Disable interrupts and call I2CS_EXECUTE
;	4. Check the content of I2CS_STATUS, clear I2CS_READY bit, if necessary.
;	5. Make sure that steps 3 and 4 repeated often enough to support correct
;	   operation of I2CS Bus.	 
;
;=======================================================================

;================= Recommended system configuration ====================
;**************************** Code start *******************************

			device	pins28, pages4, banks8, oschs, turbo, stackx, optionx 
			id	'I2CS_D1'

reset			reset_entry

;****************** I/O PINS and RAM configuration **********************

i2cs_port		=	rb		;SX port assigned for I2CS communication

i2cs_scl_pin		=	rb.0		;I2CS clock line
i2cs_sda_in_pin		=	rb.1		;I2CS data input pin
i2cs_sda_out_pin	=	rb.2		;I2CS data output pin
sys_bank		=	10h		;MAIN program RAM
i2cs_ram_bank		=	30h		;I2CS RAM bank
i2cs_io_ram		=	50h		;I2CS I/O RAM bank


;=======================================================================

;========================== Authentic I2C SLAVE VP =====================

;******************************** I2CS RAM *****************************

			org	i2cs_ram_bank

;I2CS control data

i2cs_port_rx_mask	ds	1		;PortB direction register image for receive mode
i2cs_port_tx_mask	ds	1		;PortB direction register image for transmit mode

i2cs_id_mask_msb	ds	1		;I2CS ID MSbyte, correct MSB value should be 1111 0SS(r/w)
						;Bit sero is data transfer direction (r=1/W=0)
						;Bits 1,2 (SS) are the MSBits of the 10 bit 
						;I2CS Bus ID. 
						;Bits 3 to 7 must be 1111 0XXX
i2cs_id_mask_lsb	ds	1		;LSByte of the ID. Bits from 0 to 3 address 
						;the RAM (r) within the selected bank, bits 4 to 7
						;are the LSBits of I2CS Bus ID:	SSSS rrrr

						;So the two address mask bytes will look like
						; 1111 0SS0  SSSS 0000

i2cs_fsr		ds	1		;FSR image for the last byte transferred (read/written)
i2cs_clk_timeout	ds	1		;Clock detection timeout
i2cs_start_timeout	ds	1		;Start detection timeout

;I2CS status data

i2cs_status		ds	1		;I2CS Status word
i2cs_ready		equ	i2cs_status.0	;Set when data reception was accomplished.
						;Should be cleared by MAIN program. Acts as 
						;as a flag indicating that byte was written by Master
i2cs_overflow		equ	i2cs_status.1	;Warning, set when the data are written
						;by I2C Bus Master before the previous data
						;were processed by MAIN (before I2CS_READY flag was cleared)
i2cs_stop_event		equ	i2cs_status.3	;Set when the transfer was aborted
						;because of detection of Stop event on the BUS
i2cs_start_repeat_event	equ	i2cs_status.4	;Set when the Sr (Start Repetition) was detected
i2cs_timeout		equ	i2cs_status.5	;Set when watchdog timeout occurred
i2cs_receive_transmit	equ	i2cs_status.6	;Set when the last operation was transmission to Master
i2cs_transfer_error	equ	i2cs_status.7	;Error - transfer aborted by I2CS timeout or P

i2cs_io_buffer		ds	1		;Data shift register for I2CS

;I2CS private data

i2cs_state		ds	1		;Internal state of the I2CS
i2cs_start_ok		equ	i2cs_state.0	;Set when start condition was detected
i2cs_id_ok		equ	i2cs_state.1	;Set when I2CS address was detected
i2cs_byte_ok		equ	i2cs_state.2	;Set when data byte was transferred
i2cs_stop_ok		equ	i2cs_state.3	;Set when Stop condition was detected
i2cs_start_repeat	equ	i2cs_state.4	;Set when repetition start condition was detected
i2cs_timeout_exp	equ	i2cs_state.5	;Set when I2CS timeout expires

i2cs_shift_counter	ds	1		;number of bits to transfer
i2cs_timeout_counter	ds	1		;I2CL timeout counter

			org	main_end

;********************** I2CS subroutines *******************************

;******************** Send acknowledgement *****************************
;
;	This subroutine generates the ACK signal on I2CS_OUT_PIN. 
;	It first configures the PortB direction register with the
;	I@CS_PORT_TX_MASK. Then sets the SDA pin LOW until the Clock
;	signal occurs, or the timeout timer expires.

i2cs_send_ack		mov	i2cs_timeout_counter,i2cs_clk_timeout	
								;Initialize Clock timeout counter
			mov	m,#$0f
			mov	!rb,i2cs_port_tx_mask		;Configure the pin as an output 
			clrb	i2cs_sda_out_pin		;Set ACK - SDA LOW

:i2cs_send_ack_1	jb	i2cs_scl_pin,:i2cs_send_ack_2	;Wait for SCL LOW to HIGH transition
			djnz	i2cs_timeout_counter,:i2cs_send_ack_1
			setb	i2cs_timeout_exp		;Exit when timeout expires
			jmp	:i2cs_send_ack_exit

			mov	i2cs_timeout_counter,i2cs_clk_timeout	
								;Initialize clock timeout counter
:i2cs_send_ack_2	jnb	i2cs_scl_pin,:i2cs_send_ack_exit	
								;Wait for the end of ACK clock pulse
								;(HIGH to LOW transition of SCL line)
			djnz	i2cs_timeout_counter,:i2cs_send_ack_2
			setb	i2cs_timeout_exp		;Exit when timeout expires

:i2cs_send_ack_exit	mov	!rb,i2cs_port_rx_mask		;Disactivate output pin and exit
			setb	i2cs_sda_out_pin
			ret
;**************** End of Send Acknowledgement subroutine ***************

;************************* Get byte subroutine *************************
;
;	This subroutine receives the byte from I2C Master and stores it
;	in I2CS_IO_BUFFER. The Subrotine aborts data reception in cases
;	when:
;		- the clock frequency will be too low
;		- the Sr (Start repetition) will occur
;		- the P (Stop) will occur 

i2cs_get_byte		mov	i2cs_shift_counter,#$08		;Set the number of bits to receive

:i2cs_get_byte_loop	mov	i2cs_timeout_counter,i2cs_clk_timeout
								;Set the timeout counter
:i2cs_get_0		jnb	i2cs_scl_pin,:i2cs_get_1	;Wait for SCL LOW state	
			djnz	i2cs_timeout_counter,:i2cs_get_0
			setb	i2cs_timeout_exp		;Exit when timeout expires
			ret
			
:i2cs_get_1		movb	rc.1,i2cs_scl_pin		;XXXX TEST PIN TO MONITOR THE CLOCK	
			mov	i2cs_timeout_counter,i2cs_clk_timeout
								;Set the timeout counter
:i2cs_get_2		jb	i2cs_scl_pin,:i2cs_get_bit_in	;Wait for SCL LOW to HIGH transition
			djnz	i2cs_timeout_counter,:i2cs_get_2
			setb	i2cs_timeout_exp		;Exit when timeout expires
			ret

:i2cs_get_bit_in	rl	i2cs_io_buffer			;Shift the data in
			movb	i2cs_io_buffer.0,i2cs_sda_in_pin
			movb	rc.0,i2cs_sda_in_pin		;XXXX TEST PIN TO MONITOR THE DATA
			movb	rc.1,i2cs_scl_pin		;XXXX TEST PIN TO MONITOR THE CLOCK	
			mov	i2cs_timeout_counter,i2cs_clk_timeout
								;Set the timeout counter
:i2cs_get_wait		jnb	i2cs_scl_pin,:i2cs_get_3	;Wait for SCL HIGH to LOW step
			djnz	i2cs_timeout_counter,:i2cs_get_wait
			setb	i2cs_timeout_exp		;Exit when timeout expires
			ret

:i2cs_get_3		movb	rc.1,i2cs_scl_pin		;XXXX TEST PIN TO MONITOR THE CLOCK

			jb	i2cs_io_buffer.0,:i2cs_get_4	;Compare SDA line state right after 
			sb	i2cs_sda_in_pin			;the HIGH to LOW clock transission
			jmp	:i2cs_get_continue		;to the SDA line state right after
								;LOW to HIGH clock transmission
			setb	i2cs_stop_ok			;they should be identical, otherwise
			ret					;it is either Sr or P event

:i2cs_get_4		snb	i2cs_sda_in_pin			;In both cases - exit
			jmp	:i2cs_get_continue
			setb	i2cs_start_repeat
			ret
			
:i2cs_get_continue	djnz	i2cs_shift_counter,:i2cs_get_byte_loop
			ret

;******************* End of Get byte subroutine ************************

;*********************** Send byte subroutine **************************
;
;	This subroutine sends the byte of data from I2CS_IO_BUFFER to the Master. 
;	The Subroutine aborts data reception in cases when:
;		the clock frequency will be too low
;		the Sr (Start repetition) will occur

i2cs_send_byte		mov	!rb,i2cs_port_tx_mask		;Set the direction of SDA pin as an output
			mov	i2cs_shift_counter,#$8		;Set the shift counter
:i2cs_send_byte_loop
			mov	i2cs_timeout_counter,i2cs_clk_timeout
								;Set the timeout counter
								;to wait for SCL LOW state
:i2cs_send_0		jnb	i2cs_scl_pin,:i2cs_shift_bit_out	;Wait for SCL LOW
			djnz	i2cs_timeout_counter,:i2cs_send_0
			setb	i2cs_timeout_exp		;Exit when timeout expires
			jmp	:i2cs_send_byte_exit

			mov	i2cs_timeout_counter,i2cs_clk_timeout
								;Initialize clock timeout counter
								;to wait for SCL LOW to HIGH step
:I2cs_shift_bit_out	movb	i2cs_sda_out_pin,i2cs_io_buffer.7	
								;Shift bit out
:i2cs_send_1		jb	i2cs_scl_pin,:i2cs_send_2	;Wait for SCL LOW to HIGH transition
			djnz	i2cs_timeout_counter,:i2cs_send_1
			setb	i2cs_timeout_exp		;Exit when timeout expires
			jmp	:i2cs_send_byte_exit

			mov	i2cs_timeout_counter,i2cs_clk_timeout
								;Initialize clock timeout counter
								;to wait for SCL HIGH to LOW step
:i2cs_send_2		jnb	i2cs_scl_pin,:i2cs_send_3	;Wait for SCL HIGH to LOW transition
			djnz	i2cs_timeout_counter,:i2cs_send_2
			setb	i2cs_timeout_exp		;Exit when timeout expires
			jmp	:i2cs_send_byte_exit

:i2cs_send_3		mov	i2cs_timeout_counter,#3		;Hold the data for about 0.4 usec
:i2cs_send_4		djnz	i2cs_timeout_counter,:i2cs_send_4
	
			jnb	i2cs_io_buffer.7,:i2cs_send_continue	
								;if the current bit was HIGH, then
								;there is a chance of Sr condition
								;generated by Master								
			jb	i2cs_sda_in_pin,:i2cs_send_continue
								;Current SDA line state is HIGH - continue
			setb	i2cs_start_repeat		;SDA line is LOW - Sr occurred, exit
			jmp	:i2cs_send_byte_exit

:i2cs_send_continue	rl	i2cs_io_buffer
			djnz	i2cs_shift_counter,:i2cs_send_byte_loop
								;decrement bit counter and exit
:i2cs_send_byte_exit	mov	!rb,i2cs_port_rx_mask		;restore the direction register for DSA pin
			ret
;******************* End of Send byte subroutine ***********************

;****************** I2CS initialization subroutine *********************

i2cs_init		bank	i2cs_ram_bank
			mov	m,#$0f			;set data direction registers
			mov	!rb,i2cs_port_rx_mask	;configure ports
			setb	i2cs_sda_out_pin
			ret

;******************* End of initialization subroutine ******************

;************************* I2CS DATA TRANSFER **************************

i2cs_execute		bank	i2cs_ram_bank		;set I2CS RAM bank

;************** Detection of Start condition on the BUS ****************

			snb	i2cs_sda_in_pin		;Test if SDA line is LOW
			ret				;SDA pin is HIGH - no Start Byte
							;Exit
;SDA line LOW detected, wait for Sr (Start repetition)

i2cs_sr_detect		mov 	i2cs_timeout_counter,i2cs_start_timeout

;Wait for SDA LOW to HIGH transition
			clr	i2cs_state		;Begin detection of the Sr,
							;wait for SDA HIGH
:i2cs_sda_test		jb	i2cs_sda_in_pin,:i2cs_sda_high
							;when SDA is HIGH - go to next step
			djnz	i2cs_timeout_counter,:i2cs_sda_test
							;One wait cycle is 120 nsec		
			jmp	:i2cs_false_start	;Timeout - exit

;Wait for first SDA HIGH to LOW transition

:i2cs_sda_high		jnb	i2cs_sda_in_pin,:i2cs_sda_low
							;When SDA goes LOW - test the SCL
			djnz	i2cs_timeout_counter,:i2cs_sda_high
			jmp	:i2cs_false_start	;Timeout - exit

;Test the SCL line - it must be HIGH, if it is LOW - false start

:i2cs_sda_low		snb	i2cs_scl_pin		;It was LOW to HIGH step on SDA							
							;line, when the SCL was LOW - false start
			jmp	i2cs_start

:i2cs_false_start	ret				;Exit I2CS, no Start detected

;************** Decode the first byte in transfer **********************
;	Start condition detected; next step - decode the address
;	First byte contains R/W bit, and two bits of 10-bit address

i2cs_start		clr	i2cs_state		;Reset the state machine
			setb	i2cs_start_ok		;Start  detected
			and	i2cs_status,#$01	;Clear all bits of Status byte but READY bit
							;Ready bit may be cleared only by MAIN program
:get_transfer		call	i2cs_get_byte		;Get 1st address byte

;Test if the transfer was interrupted either by Sr, P signals or by timeout timer 
			mov	w,i2cs_state			
			and	w,#$38			;Select three state bits
			sz				;Continue if ZERO
			jmp	i2cs_exit

;Test if the byte was the Start Byte
			mov	w,i2cs_io_buffer
			xor	w,#$01			;Is it the "START BYTE" (01h) ?	
			snz
			jmp	i2cs_sr_detect		;Yes, it was the Start Byte
							;Go back and wait for Sr condition
;Check if this is I2CS  ID
			mov	w,i2cs_io_buffer	;Is it 10-bit address ?
			and	w,#$fe			;Mask the r/w bit
			xor	w,i2cs_id_mask_msb	;Test ten bit address (must be1111 0SSX)
			sz
			jmp	i2cs_exit		;This is not I2CS ID - exit			
;Decode R/W bit	
			clrb	i2cs_receive_transmit
			snb	i2cs_io_buffer.0	;Test the r/w bit
			setb	i2cs_receive_transmit	;Zero indicates transmission from master
;Send ack 
			call 	I2cs_send_ack		;Generate ACK signal
			snb	i2cs_timeout_exp	;Was the timeout OK ?
			jmp	i2cs_exit		;No

;************************ Decode the second byte ***********************
;	Second byte contains last eight bit of 10-bit address

			call	i2cs_get_byte

;Test if the transfer was interrupted by either Sr or P signal or timeout timer
			mov	w,i2cs_state			
			and	w,#$38			;Select three state bits
			sz				;Continue if ZERO
			jmp	i2cs_exit

;Decode the LSB of Bus ID
			mov	w,i2cs_io_buffer
			and	w,#$f0			;Test the ID
			xor	w,i2cs_id_mask_lsb	;Is it the I2CS bus ID ?
			sz
			jmp	i2cs_exit		;This is not I2CS Bus ID
;Decode ram address	
			mov	w,i2cs_io_buffer
			and	w,#$0f
			or	w,i2cs_io_ram		;Combine the last 4 bits of BUS ID
							;with the defined I/O_RAM bank address
			mov	i2cs_fsr,w		;Save the FSR image

			setb	i2cs_id_ok
			call 	i2cs_send_ack		;Generate the ACK
			snb	i2cs_timeout_exp	;Was the timeout OK ?
			jmp	i2cs_exit		;No

;*********************** Transfer the byte *****************************
			
			jb	i2cs_receive_transmit,:i2cs_transmit_byte
;Receive the byte	
			call	i2cs_get_byte

;Test if the transfer was interrupted by either Sr or P signal 
			mov	w,i2cs_state			
			and	w,#$38			;Select three state bits
			sz				;Continue if ZERO
			jmp	i2cs_exit

			mov	08h,i2cs_io_buffer	;Move the data to I2CS I/O RAM location
			mov	fsr,i2cs_fsr		;using FSR as I/O data pointer
			mov	indf,08h

			bank	i2cs_ram_bank
			call	i2cs_send_ack		;Generate the ACK signal
			snb	i2cs_timeout_exp	;Was the timeout OK ?
			jmp	i2cs_exit		;No

			setb	i2cs_byte_ok
			jmp	i2cs_exit		;Data transfer finished - exit
;Transmit the byte
:i2cs_transmit_byte	mov	fsr,i2cs_fsr		;Move the data from I2CS RAM Location
			mov	08h,indf		;to I2CS_IO_BUFFER using FSR as pointer
			bank	i2cs_ram_bank
			mov	i2cs_io_buffer,08h
			call	i2cs_send_byte		;Send the data
			jmp	i2cs_exit		;Whatever happened - exit
		
;*********************** Data Transfer Exit ****************************
;
;	This part of I2CS VP may be customized to meet specific needs of
;	the interface to the MAIN program
;
i2cs_exit		jnb	i2cs_start_repeat,:i2cs_exit_1	
							;Was Sr detected ?
			setb	I2cs_start_repeat
			jmp	i2cs_start		;Yes, start all over again

:I2cs_exit_1		jnb	i2cs_stop_ok,:i2cs_exit_2
							;Was stop condition detected ?
			setb	i2cs_stop_event		;Yes, set the flags and exit
			setb	i2cs_transfer_error
			jmp	:i2cs_finish
			
:i2cs_exit_2		jnb	i2cs_timeout_exp,:i2cs_exit_3
							;Was timeout detected ?
			setb	i2cs_timeout		;Yes, set the flags and exit
			setb	i2cs_transfer_error
			jmp	:i2cs_finish

:i2cs_exit_3		jb	i2cs_receive_transmit,:i2cs_finish
							;Was it data transmission from the Master
			snb	i2cs_ready		;Yes, check if the Warning should be set
			setb	i2cs_overflow
			setb	i2cs_ready

:i2cs_finish		ret

;========================== END OF I2CS VP =============================

file: /Techref/scenix/lib/io/osi2/i2c/i2cs_vp.src, 24KB, , updated: 1999/2/20 11:23, local time: 2024/12/25 21:47,
TOP NEW HELP FIND: 
3.142.198.108:LOG IN

 ©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="http://linistepper.com/Techref/scenix/lib/io/osi2/i2c/i2cs_vp.src"> scenix lib io osi2 i2c i2cs_vp</A>

Did you find what you needed?