;*******************************************************************************;
;*                                                                              ;
;*  This implements a generic library functionality to support I2C Master       ;
;*  for PIC18 family                                                            ;
;*  It adds additional functionality of Rx/Tx user defined Cicular buffer       ;
;*                                                                              ;
;*******************************************************************************;
;* FileName:            18I2CMI.asm                                     ;        
;* Dependencies:        P18xxx.inc                                      ;
;*                      I2CMInt.Def                                     ;
;*                      I2CMInt.Inc                                     ;
;* Processor:           PIC18xxxx                                       ;
;* Assembler:           MPASMWIN 02.70.02 or higher                     ;
;* Linker:              MPLINK 2.33.00 or higher                        ;
;* Company:             Microchip Technology, Inc.                      ;
;*                                                                      ;
;* Software License Agreement                                           ;
;*                                                                      ;
;* The software supplied herewith by Microchip Technology Incorporated  ;
;* (the "Company") for its PICmicro Microcontroller is intended and    ;
;* supplied to you, the Company's customer, for use solely and          ;
;* exclusively on Microchip PICmicro Microcontroller products. The      ;
;* software is owned by the Company and/or its supplier, and is         ;
;* protected under applicable copyright laws. All rights are reserved.  ;
;* Any use in violation of the foregoing restrictions may subject the   ;
;* user to criminal sanctions under applicable laws, as well as to      ;
;* civil liability for the breach of the terms and conditions of this   ;
;* license.                                                             ;
;*                                                                      ;
;* THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,    ;
;* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED    ;
;* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A          ;
;* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,    ;
;* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR           ;
;* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.                    ;
;*                                                                      ;
;*                                                                      ;
;* ANY SPECIAL DESCRIPTION THAT MIGHT BE USEFUL FOR THIS FILE.          ;
;*                                                                      ;
;* Author               Date            Comment                         ;
;*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;* Vidyadhar       Mar 31, 2003    Initial Release (V1.0)               ;
;*                                                                      ;
;***********************************************************************;


;***********************************************************************;
_I2CMINTCODE   code                                                     ;
                                                                        ;
;***********************************************************************;
; Function: I2CMIntInit                                                 ;
;                                                                       ;
; PreCondition: None                                                    ;
;                                                                       ;
; Overview:                                                             ;
;       This routine is used for MSSP/SSP/BSSP Module Initialization    ;
;       It initializes Module according to CLM options and flushes the  ;
;        buffer. It clears all I2C errors                               ;
;                                                                       ;
; Input: CLM options                                                    ;
;                                                                       ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntInit:                                    ;
                                                ;
        GLOBAL  I2CMIntInit                     ;
                                                ;
        movlw   028h                            ;
        movwf   SSPCON1                         ;Enable MSSP module and Master mode
                                                ;
        movlw   _I2CM_BAUD_COUNT                ;
        movwf   SSPADD                          ;loading SSPADD with baudrate generator
                                                ;reload value
        #ifdef  I2CM_CONTROLED_SLEW_RATE        ; 
                                                ;
        bsf     SSPSTAT,SMP                     ;
                                                ;
        #endif                                  ;
                                                ;
        #ifdef  I2CM_SMBUS                      ; 
                                                ;
        bsf     SSPSTAT,CKE                     ;
                                                ;
        #endif                                  ;
                                                ;
        bsf     INTCON,PEIE                     ;
        bsf     INTCON,GIE                      ;
                                                ;
        clrf    vI2CMIntStatus                  ;
        clrf    _vI2CMIntState                  ;
                                                ;
        return                                  ;
                                                ;
;***********************************************;12



;***********************************************************************;
; Function: I2CMIntStart                                                ;
;                                                                       ;
; PreCondition: I2CMIntInit must have already been called.              ;
;                                                                       ;
; Overview:                                                             ;
;       Sends Start bit on I2C Bus.                                     ;
;                                                                       ;
; Input: None                                                           ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntStart:                                   ;
                                                ;
        GLOBAL  I2CMIntStart                    ;
                                                ;
        btfsc   SSPSTAT,S                       ;
        bra     I2CStartErr                     ;if Start bit already is set goto StartErr
                                                ;
        bcf     vI2CMIntStatus,I2CMErrBusBusy   ;
                                                ;
I2CSendStart                                    ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        bsf     PIE1,SSPIE                      ;enable serial_sync interrupt
                                                ;
        #ifdef  I2CM_MULTI_MASTER               ;
                                                ;
        bsf     PIE2,BCLIE                      ;enable Bus collision interrupt
                                                ;
        #endif                                  ;
                                                ;
        BANKSEL _vI2CMIntBufWrPtr               ;
        clrf    _vI2CMIntBufWrPtr,1             ;
        clrf    _vI2CMIntBufRdPtr,1             ;
        clrf    _vI2CMIntTxDataCount,1          ;clear transmit data count
        clrf    _vI2CMIntRxDataCount,1          ;clear receive data count
        movlw   009h                            ;Sets buffer empty flag & busy flag
        movwf   vI2CMIntStatus                  ;Clears all error flags
                                                ;
        bsf     _vI2CMIntState,I2CMTransmitState;Set next state to TransmitState
                                                ;
        bsf     SSPCON2,SEN                     ;Send START bit
                                                ;
        return                                  ;
                                                ;
I2CStartErr                                     ;
        bsf     vI2CMIntStatus,I2CMErrBusBusy   ;
        return                                  ;
                                                ;
;***********************************************;19




;***********************************************************************;
; Function: I2CMIntReStart                                              ;
;                                                                       ;
; PreCondition: I2CMIntStart should have called.                        ;
;                                                                       ;
; Overview:                                                             ;
;  Sends RepeatedStart condition on I2C Bus if its free or sets a flag. ;
;                                                                       ;
; Input: None                                                           ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits are changed                         ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntReStart:                                 ;
                                                ;
        GLOBAL  I2CMIntReStart                  ;
                                                ;
        btfss   vI2CMIntStatus,I2CMBusy         ;Check is it busy
        bra     I2CMSendReStart                 ;if not send RepStart
                                                ;
        bsf     _vI2CMIntState,I2CMRStrt        ;Set RepStart to be sent flag
        movff   _vI2CMIntTxDataCount,_vI2CMIntRSPnt;Record present Tx datacount 
        return                                  ;
                                                ;
I2CMSendReStart                                 ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;
        bsf     _vI2CMIntState,I2CMTransmitState;Set next state to TransmitState
                                                ;
        bcf     _vI2CMIntState,I2CMRStrt        ;Clear RepStart to be sent flag
                                                ;
        bsf     SSPCON2,RSEN                    ;Send Repeated START bit
                                                ;
        return                                  ;
                                                ;
;***********************************************;13




;***********************************************************************;
; Function: I2CMIntStop                                                 ;
;                                                                       ;
; PreCondition: I2CMIntStart should have called.                        ;
;                                                                       ;
; Overview:                                                             ;
;       Sends Stop bit on I2C Bus if its free or sets a flag.           ;
;                                                                       ;
; Input: None                                                           ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntStop:                                    ;
                                                ;
        GLOBAL  I2CMIntStop                     ;
                                                ;
        btfss   vI2CMIntStatus,I2CMBusy         ;Check is it busy
        bra     I2CMCheckIsRx                   ;if not check is it Reception
                                                ;
        bsf     _vI2CMIntState,I2CMStp          ;Set Stop bit to be sent flag
        return                                  ;
                                                ;
I2CMCheckIsRx                                   ;
                                                ;
        bsf     vI2CMIntStatus,I2CMBusy         ;
        btfss   _vI2CMIntState,I2CMTx           ;Check is it reception
        goto    I2CMNoAck                       ;If so send NoAck
                                                ;
I2CMSendStop                                    ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;Set next state to EndState
                                                ;
        bcf     _vI2CMIntState,I2CMStp          ;Clear Stop to be sent flag
                                                ;
        bsf     SSPCON2,PEN                     ;Send STOP bit
                                                ;
        return                                  ;
                                                ;
;***********************************************;16




;***********************************************************************;
; Function: I2CMIntPut                                                  ;
;                                                                       ;
; PreCondition: I2CMIntStart should have called.                        ;
;                                                                       ;
; Overview:                                                             ;
;       Sends data byte over I2C Bus if Bus is free or sotre in Buffer. ;
;                                                                       ;
; Input: 'W' Register                                                   ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntPut:                                     ;
                                                ;
        GLOBAL  I2CMIntPut                      ;
                                                ;
        bsf     _vI2CMIntState,I2CMTx           ;
                                                ;
        btfss   vI2CMIntStatus,I2CMBusy         ;Check is it busy
        bra     I2CDirectTx                     ;
                                                ;
        bcf     PIE1,SSPIE                      ;
                                                ;
        call    _I2CMIntWrBuf                   ;If busy
                                                ;Save in buffer
        BANKSEL _vI2CMIntTxDataCount            ;
        incf    _vI2CMIntTxDataCount,f,1        ;Increment Tx Data Count
                                                ;
        bsf     PIE1,SSPIE                      ;
                                                ;
        return                                  ;
I2CDirectTx                                     ;
        bsf     vI2CMIntStatus,I2CMBusy         ;
                                                ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;
        bsf     _vI2CMIntState,I2CMCheckAckState;Set next state to CheckAckState
                                                ;
        movwf   SSPBUF                          ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync intrupt flag
                                                ;
        return                                  ;
                                                ;
;***********************************************;45        



;***********************************************************************;
; Function: I2CMIntSetGetCount                                          ;
;                                                                       ;
; PreCondition: I2CMIntPut should have called.                          ;
;                                                                       ;
; Overview:                                                             ;
;      Enables Master receiver, notes the no. of bytes to be received.  ;
;                                                                       ;
; Input: 'W' Reg                                                        ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntSetGetCount:                             ;
                                                ;
        GLOBAL  I2CMIntSetGetCount              ;
                                                ;
        BANKSEL _vI2CMIntRxDataCount            ;
        addwf   _vI2CMIntRxDataCount,f,1        ;
                                                ;
        btfsc   vI2CMIntStatus,I2CMBusy         ;Check is it busy
        return                                  ;
                                                ;
        bsf     vI2CMIntStatus,I2CMBusy         ;
                                                ;
        btfss   _vI2CMIntState,I2CMTx           ;If not busy and Ack is due
        goto    I2CMAck                         ;Goto send Ack
                                                ;
        bcf     _vI2CMIntState,I2CMTx           ;
        goto    I2CMReceiveEn                   ;Enable receiver
                                                ;
;***********************************************;19



;***********************************************************************;
; Function: I2CMIntGet                                                  ;
;                                                                       ;
; PreCondition: I2CMIntGetCount should have been called and             ;
;                buffer should not be empty                             ;
;                                                                       ;
; Overview:                                                             ;
;       This reads data from buffer.                                    ; 
;                                                                       ;
; Input: None                                                           ;
;                                                                       ;
; Output: 'W' Register                                                  ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntGet:                                     ;
                                                ;
        GLOBAL  I2CMIntGet                      ;
                                                ;
        bcf     PIE1,SSPIE                      ;
                                                ;
        call    _I2CMIntRdBuf                   ;Read the byte from buffer
                                                ;
        bsf     PIE1,SSPIE                      ;
                                                ;
        return                                  ;
                                                ;
;***********************************************;42        




;***********************************************************************;
; Function: I2CMIntISR                                                  ;
;                                                                       ;
; PreCondition: Must be called from an interrupt handler                ;
;                                                                       ;
; Overview:                                                             ;
;       This is a Interrupt service routine for Serial Interrupt.       ;
;       It handles Reception and Transmission of data on interrupt.     ;
;       Call it from Interrupt service routine.                         ;
;                                                                       ;
; Input: None                                                           ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 2 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntISR:                                     ;
        GLOBAL  I2CMIntISR                      ;
                                                ;
        btfsc   PIR1,SSPIF                      ;check has sspif occurred
        bra     I2CMYes                         ;
                                                ;
        #ifdef  I2CM_MULTI_MASTER               ;
                                                ;
        btfss   PIR2,BCLIF                      ;check has bclif occurred
        return                                  ;
                                                ;
        bsf     vI2CMIntStatus,I2CMErrBusCollision        ;
        bcf     PIR2,BCLIF                      ;
                                                ;
        #endif                                  ;
                                                ;
        return                                  ;
                                                ;
I2CMYes                                         ;
        movf    SSPCON1,w                       ;
        andlw   00fh                            ;
        xorlw   008h                            ;
        btfss   STATUS,Z                        ;
        return                                  ;check is Master Mode
                                                ;
        btfsc   _vI2CMIntState,I2CMTransmitState;
        bra     I2CMTransmit                    ;11
                                                ;
        btfsc   _vI2CMIntState,I2CMCheckAckState;
        bra     I2CMCheckAck                    ;13 + 54
                                                ;
        btfsc   _vI2CMIntState,I2CMReceiveState ;
        bra     I2CMReceive                     ;15 + 55
                                                ;
        btfsc   _vI2CMIntState,I2CMReceiveEnState;
        bra     I2CMReceiveEn                   ;17
                                                ;
        btfsc   _vI2CMIntState,I2CMStopState    ;
        bra     I2CMSendStop                    ;19
                                                ;
        bra     I2CMEnd                         ;20
                                                ;
;***********************************************;

;***********************************************;
I2CMCheckAck                                    ;
                                                ;
        btfss   SSPCON2,ACKSTAT                 ;checking for acknowledge from slave.
        bra     I2CMCheckWhatNext               ;
                                                ;
        bsf     vI2CMIntStatus,I2CMErrNoAck     ;
        goto    I2CMSendStop                    ;
                                                ;
I2CMCheckWhatNext                               ;
                                                ;
        btfss   _vI2CMIntState,I2CMRStrt        ;Is repeated Start to be sent
        bra     I2CMTransmit                    ;
                                                ;
        BANKSEL _vI2CMIntRSPnt                  ;
        movf    _vI2CMIntRSPnt,f,1              ;If yes is this the point where it has to be sent
        bz      I2CMSendReStart                 ;if yes goto send
                                                ;
;-----------------------------------------------;
I2CMTransmit                                    ;
                                                ;
        BANKSEL _vI2CMIntTxDataCount            ;
        tstfsz  _vI2CMIntTxDataCount,1          ;Is transmission of all bytes over
        bra     I2CMRdTxData                    ;If not goto read data to be transmitted
                                                ;
        tstfsz  _vI2CMIntRxDataCount,1          ;If data to be received
        bra     I2CMReceiveEn                   ;goto enable receiver
                                                ;
        btfsc   _vI2CMIntState,I2CMStp          ;Is Stop has to be sent
        goto    I2CMSendStop                    ;
                                                ;
        bcf     vI2CMIntStatus,I2CMBusy         ;clear busy and return
        return                                  ;
                                                ;
I2CMRdTxData                                    ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;
        bsf     _vI2CMIntState,I2CMCheckAckState;Set next state to CheckAckState
                                                ;
        call    _I2CMIntRdBuf                   ;read a byte from circular buffer
                                                ;
        BANKSEL _vI2CMIntTxDataCount            ;
        decf    _vI2CMIntTxDataCount,f,1        ;decrement the Tx Data Count
        decf    _vI2CMIntRSPnt,f,1              ;
                                                ;
        movwf   SSPBUF                          ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync intrupt flag
                                                ;
        return                                  ;
                                                ;
;***********************************************;

;***********************************************;
I2CMReceive                                     ;
                                                ;
        movf    SSPBUF,w                        ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        btfsc   vI2CMIntStatus,I2CMBufFull      ;checking is buffer empty
        goto    I2CMBufFullErr                  ;
                                                ;
        call    _I2CMIntWrBuf                   ;write the byte into circular buffer
                                                ;
        bsf     vI2CMIntStatus,I2CMDataReady    ;set Data Ready flag
                                                ;
        BANKSEL _vI2CMIntRxDataCount            ;
        decfsz  _vI2CMIntRxDataCount,f,1        ;decrement the to be Rx Data Count
        goto    I2CMAck                         ;
                                                ;
        btfsc   _vI2CMIntState,I2CMStp          ;Is Stop has to be sent
        goto    I2CMNoAck                       ;
                                                ;
        bcf     vI2CMIntStatus,I2CMBusy         ;clear busy and return
                                                ;
        return                                  ;
                                                ;
I2CMBufFullErr                                  ;
        bsf     vI2CMIntStatus,I2CMBufOverFlow  ;
        return                                  ;
;***********************************************;


;***********************************************;
                                                ;
I2CMAck                                         ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;
        bsf     _vI2CMIntState,I2CMReceiveEnState;Set next state to ReceiveEnState
                                                ;
        bcf     SSPCON2,ACKDT                   ;
        bsf     SSPCON2,ACKEN                   ;Acknowledge
                                                ;
        return                                  ;
                                                ;
;***********************************************;

;***********************************************;
                                                ;
I2CMNoAck                                       ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;
        bsf     _vI2CMIntState,I2CMStopState    ;Set next state to StopState
                                                ;
        bsf     SSPCON2,ACKDT                   ;
        bsf     SSPCON2,ACKEN                   ;No_Acknowledge
                                                ;
        return                                  ;
                                                ;
;***********************************************;

;***********************************************;
                                                ;
I2CMReceiveEn                                   ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;
        bsf     _vI2CMIntState,I2CMReceiveState ;Set next state to ReceiveState
                                                ;
        bsf     SSPCON2,RCEN                    ;enable reciever
                                                ;
        return                                  ;
                                                ;
;***********************************************;

;***********************************************;
                                                ;
I2CMEnd                                         ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        bcf     PIE1,SSPIE                      ;
        bcf     PIE2,BCLIE                      ;
                                                ;
        bcf     vI2CMIntStatus,I2CMBusy         ;clear Busy
                                                ;
        return                                  ;
                                                ;
;***********************************************;




;***********************************************************************;
; Function: _I2CMIntRdBuf                                               ;
;                                                                       ;
; PreCondition: I2CMIntPut or I2CMIntGet should have called.            ;
;                                                                       ;
; Overview:                                                             ;
;       This reads data from buffer.                                    ; 
;                                                                       ;
; Input: None                                                           ;
;                                                                       ;
; Output: 'W' Register                                                  ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;        
_I2CMIntRdBuf:                                  ;
                                                ;
        btfsc   vI2CMIntStatus,I2CMBufEmpty     ;
        return                                  ;
                                                ;
        movff   FSR0H,_vI2CMIntDupFSRH          ;
        movff   FSR0L,_vI2CMIntDupFSR           ;Save FSR
                                                ;
        #ifdef  _DONT_USE_LFSR                  ;
                                                ;
        BANKSEL _vI2CMIntBufRdPtr               ;
        movlw   HIGH(vI2CMIntBuffer)            ;load wreg with read pointer address
        movwf   FSR0H                           ;
        movlw   LOW(vI2CMIntBuffer)             ;
        addwf   _vI2CMIntBufRdPtr,w,1           ;load fsr with read pointer address
        movwf   FSR0L                           ;
                                                ;
        #else                                   ;
                                                ;
        BANKSEL _vI2CMIntBufRdPtr               ;
        lfsr    FSR0,vI2CMIntBuffer             ;load fsr with read pointer address
        movf    _vI2CMIntBufRdPtr,w,1           ;
        addwf   FSR0L                           ;
                                                ;
        #endif                                  ;
                                                ;
        btfsc   STATUS,C                        ;
        incf    FSR0H,f                         ;
                                                ;
        incf    _vI2CMIntBufRdPtr,f,1           ;increment read pointer
        movlw   I2CM_BUFFER_LENGTH              ;
        xorwf   _vI2CMIntBufRdPtr,w,1           ;
        btfsc   STATUS,Z                        ;
        clrf    _vI2CMIntBufRdPtr,1             ;
                                                ;
        movf    _vI2CMIntBufRdPtr,w,1           ;
        xorwf   _vI2CMIntBufWrPtr,w,1           ;Check is buffer empty
        btfss   STATUS,Z                        ;
        bra     I2CBufNotEmt                    ;
        bcf     vI2CMIntStatus,I2CMDataReady    ;
        bsf     vI2CMIntStatus,I2CMBufEmpty     ;
                                                ;
I2CBufNotEmt                                    ;
        movf    INDF0,w                         ;move the content of read pointer address to W
                                                ;
        movff   _vI2CMIntDupFSR,FSR0L           ;
        movff   _vI2CMIntDupFSRH,FSR0H          ;Retrive FSR
                                                ;
        bcf     vI2CMIntStatus,I2CMBufFull      ;
        bcf     vI2CMIntStatus,I2CMBufOverFlow  ;
                                                ;
        return                                  ;
;***********************************************;34





;***********************************************************************;
; Function: _I2CMIntWrBuf                                               ;
;                                                                       ;
; PreCondition: None.                                                   ;
;                                                                       ;
; Overview:                                                             ;
;       This writes data into buffer.                                   ; 
;                                                                       ;
; Input: 'W' Register                                                   ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: None                                                    ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;        
_I2CMIntWrBuf:                                  ;
        btfsc   vI2CMIntStatus,I2CMBufFull      ;
        return                                  ;
                                                ;        
        movff   WREG,_vI2CMIntTempReg           ;save the wreg content (data) in temflg
                                                ;
        movff   FSR0H,_vI2CMIntDupFSRH          ;
        movff   FSR0L,_vI2CMIntDupFSR           ;Save FSR
                                                ;
        #ifdef  _DONT_USE_LFSR                  ;
                                                ;
        BANKSEL _vI2CMIntBufWrPtr               ;
        movlw   HIGH(vI2CMIntBuffer)            ;
        movwf   FSR0H                           ;
        movlw   LOW(vI2CMIntBuffer)             ;load wreg with write pointer address
        addwf   _vI2CMIntBufWrPtr,w,1           ;
        movwf   FSR0L                           ;
                                                ;
        #else                                   ;
                                                ;
        BANKSEL _vI2CMIntBufWrPtr               ;
        lfsr    FSR0,vI2CMIntBuffer             ;load fsr with read pointer address
        movf    _vI2CMIntBufWrPtr,w,1           ;
        addwf   FSR0L                           ;
                                                ;
        #endif                                  ;
                                                ;
        btfsc   STATUS,C                        ;
        incf    FSR0H,f                         ;
                                                ;
        movff    _vI2CMIntTempReg,INDF0         ;write the content to write pointer pointing location
                                                ;
        movff   _vI2CMIntDupFSR,FSR0L           ;
        movff   _vI2CMIntDupFSRH,FSR0H          ;Retrive FSR
                                                ;
        incf    _vI2CMIntBufWrPtr,f,1           ;increment write pointer
        movlw   I2CM_BUFFER_LENGTH              ;
        xorwf   _vI2CMIntBufWrPtr,w,1           ;
        btfsc   STATUS,Z                        ;
        clrf    _vI2CMIntBufWrPtr,1             ;
                                                ;
        movf    _vI2CMIntBufWrPtr,w,1           ;
        xorwf   _vI2CMIntBufRdPtr,w,1           ;Check is buffer full
        btfsc   STATUS,Z                        ;
        bsf     vI2CMIntStatus,I2CMBufFull      ;
                                                ;
        bcf     vI2CMIntStatus,I2CMBufEmpty     ;
                                                ;
        return                                  ;
                                                ;
;***********************************************;34



;***********************************************************************;
; Function: I2CMIntDiscardBuf                                           ;
;                                                                       ;
; PreCondition: None.                                                   ;
;                                                                       ;
; Overview:                                                             ;
;       This flushes the buffer.                                        ; 
;                                                                       ;
; Input: 'W' Register                                                   ;
;                                                                       ;
; Output: Buffer                                                        ;
;                                                                       ;
; Side Effects: None                                                    ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;        
I2CMIntDiscardBuf:                              ;
        GLOBAL  I2CMIntDiscardBuf               ;
                                                ;
        BANKSEL _vI2CMIntBufRdPtr               ;
        clrf    _vI2CMIntBufRdPtr,1             ;
        clrf    _vI2CMIntBufWrPtr,1             ;
        bsf     vI2CMIntStatus,I2CMBufEmpty     ;
        bcf     vI2CMIntStatus,I2CMBufFull      ;
        bcf     vI2CMIntStatus,I2CMBufOverFlow  ;
                                                ;
        return                                  ;
                                                ;
;***********************************************;10




;***********************************************;
;        END                                    ;
;***********************************************;


