;======================================================================= ; 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,#0ドルf 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,#0ドルf ;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,#0ドルf 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 =============================
.