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,
|
| ©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? <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?
|