;*******************************************************************************;
;*                                                                              ;
;*  This implements a generic library functionality to support I2C Master       ;
;*  for PIC16 family                                                            ;
;*  It adds additional functionality of Rx/Tx user defined Cicular buffer       ;
;*                                                                              ;
;*******************************************************************************;
;* FileName:            16I2CMI.asm                                     ;        
;* Dependencies:        P16xxx.inc                                      ;
;*                      I2CMInt.Def                                     ;
;*                      I2CMInt.Inc                                     ;
;* Processor:           PIC16xxxx                                       ;
;* 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                                                           ;
                                                                        ;
;***********************************************************************;

_I2CMINTINIT    CODE                                                        
;***********************************************************************;
; Function: I2CMIntInit                                                 ;
;                                                                       ;
; PreCondition: None                                                    ;
;                                                                       ;
; Overview:                                                             ;
;       This routine is used for MSSP 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                     ;
                                                ;
        BANKSEL SSPCON                          ;Enable MSSP module and set in Master mode
        movlw   028h                            ;
        movwf   SSPCON                          ;
                                                ;
        bsf     STATUS,RP0                      ;
        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                                  ;
                                                ;
;***********************************************;15


_I2CMINTSTART   CODE                                                        
;***********************************************************************;
; 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                    ;
                                                ;
        BANKSEL SSPSTAT                         ;
        btfsc   SSPSTAT,S                       ;if Start bit already is set goto StartErr
        goto    I2CStartErr                     ;
                                                ;
        bcf     vI2CMIntStatus,I2CMErrBusBusy   ;
                                                ;
I2CSendStart                                    ;
        bcf     STATUS,RP0                      ;
        bcf     PIR1,SSPIF                      ;clear serial_sync interrupt
                                                ;
        bsf     STATUS,RP0                      ;
        bsf     PIE1,SSPIE                      ;enable serial_sync interrupt
                                                ;
        #ifdef I2CM_MULTI_MASTER                ;
                                                ;
        bsf     PIE2,BCLIE                      ;enable Bus collision interrupt
                                                ;
        #endif                                  ;
                                                ;
        BANKSEL _vI2CMIntBufWrPtr               ;
        clrf    _vI2CMIntBufWrPtr               ;Flush buffer
        clrf    _vI2CMIntBufRdPtr               ;
        clrf    _vI2CMIntTxDataCount            ;clear transmit data count
        clrf    _vI2CMIntRxDataCount            ;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
                                                ;
        BANKSEL SSPCON2                         ;
        bsf     SSPCON2,SEN                     ;Send START bit
        return                                  ;
                                                ;
I2CStartErr                                     ;
        bsf     vI2CMIntStatus,I2CMErrBusBusy   ;
        return                                  ;
                                                ;
;***********************************************;26




_I2CMINTRESTART CODE                                                        
;***********************************************************************;
; 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 and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntReStart:                                 ;
                                                ;
        GLOBAL  I2CMIntReStart                  ;
                                                ;
        btfss   vI2CMIntStatus,I2CMBusy         ;Check is it busy
        goto    I2CMSendReStart                 ;if not send RepStart
                                                ;
        bsf     _vI2CMIntState,I2CMRStrt        ;Set RepStart to be sent flag
        BANKSEL _vI2CMIntTxDataCount            ;
        movf    _vI2CMIntTxDataCount,w          ;Record present Tx datacount 
        movwf   _vI2CMIntRSPnt                  ;
        return                                  ;
                                                ;
I2CMSendReStart                                 ;
                                                ;
        BANKSEL PIR1                            ;
        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
                                                ;
        BANKSEL SSPCON2                         ;
        bsf     SSPCON2,RSEN                    ;Send Repeated START bit
                                                ;
        return                                  ;
                                                ;
;***********************************************;17




_I2CMINTSTOP    CODE                                                        
;***********************************************************************;
; 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
        goto    I2CMCheckIsRx                   ;if not check is it Reception
                                                ;
        bsf     _vI2CMIntState,I2CMStp          ;Set Stop bit to be sent flag
        return                                  ;
                                                ;
I2CMCheckIsRx                                   ;
                                                ;
        bsf     vI2CMIntStatus,I2CMBusy         ;
        PAGESEL I2CMNoAck                       ;
        btfss   _vI2CMIntState,I2CMTx           ;Check is it reception
        goto    I2CMNoAck                       ;If so send NoAck
                                                ;
I2CMSendStop                                    ;
                                                ;
        BANKSEL PIR1                            ;
        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
                                                ;
        BANKSEL SSPCON2                         ;
        bsf     SSPCON2,PEN                     ;Send STOP bit
                                                ;
        return                                  ;
                                                ;
;***********************************************;22




_I2CMINTPUT     CODE                                                        
;***********************************************************************;
; Function: I2CMIntPut                                                  ;
;                                                                       ;
; PreCondition: I2CMIntStart should have called.                        ;
;                                                                       ;
; Overview:                                                             ;
;       Sends data byte over I2C Bus if Bus is free or store 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
        goto    I2CDirectTx                     ;
                                                ;
        BANKSEL PIE1                            ;
        bcf     PIE1,SSPIE                      ;
                                                ;
        PAGESEL _I2CMIntWrBuf                   ;If busy
        call    _I2CMIntWrBuf                   ;Save in buffer
                                                ;
        BANKSEL _vI2CMIntTxDataCount            ;
        incf    _vI2CMIntTxDataCount,f          ;Increment Tx Data Count
                                                ;
        BANKSEL PIE1                            ;
        bsf     PIE1,SSPIE                      ;
                                                ;
        return                                  ;
                                                ;
I2CDirectTx                                     ;
        bsf     vI2CMIntStatus,I2CMBusy         ;
                                                ;
        movlw   0e0h                            ;
        andwf   _vI2CMIntState,f                ;
        bsf     _vI2CMIntState,I2CMCheckAckState;Set next state to CheckAckState
                                                ;
        BANKSEL SSPBUF                          ;
        movwf   SSPBUF                          ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync intrupt flag
                                                ;
        return                                  ;
                                                ;
;***********************************************;50        



_I2CMINTGETCOUNT    CODE                                                        
;***********************************************************************;
; Function: I2CMIntGetCount                                             ;
;                                                                       ;
; 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 are changed                         ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;
I2CMIntSetGetCount:                             ;
                                                ;
        GLOBAL  I2CMIntSetGetCount              ;
                                                ;
        BANKSEL _vI2CMIntRxDataCount            ;
        addwf   _vI2CMIntRxDataCount,f          ;
                                                ;
        btfsc   vI2CMIntStatus,I2CMBusy         ;Check is it busy
        return                                  ;
                                                ;
        bsf     vI2CMIntStatus,I2CMBusy         ;
                                                ;
        PAGESEL I2CMAck                         ;
        btfss   _vI2CMIntState,I2CMTx           ;If not busy and Ack is due
        goto    I2CMAck                         ;Goto send Ack
                                                ;
        bcf     _vI2CMIntState,I2CMTx           ;
        PAGESEL I2CMReceiveEn                   ;Enable receiver
        goto    I2CMReceiveEn                   ;
                                                ;
;***********************************************;27


_I2CMINTGET     CODE                                                        
;***********************************************************************;
; 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                      ;
                                                ;
        BANKSEL PIE1                            ;
        bcf     PIE1,SSPIE                      ;
                                                ;
        PAGESEL _I2CMIntRdBuf                   ;
        call    _I2CMIntRdBuf                   ;Read the byte from buffer
                                                ;
        BANKSEL PIE1                            ;
        bsf     PIE1,SSPIE                      ;
                                                ;
        return                                  ;
                                                ;
;***********************************************;49        




_I2CMINTISR     CODE                                                        
;***********************************************************************;
; 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                      ;
                                                ;
        BANKSEL PIR1                            ;
        btfsc   PIR1,SSPIF                      ;check has sspif occurred
        goto    I2CMYes                         ;
                                                ;
        #ifdef  I2CM_MULTI_MASTER               ;
                                                ;
        btfss   PIR2,BCLIF                      ;check has bclif occurred
        return                                  ;
                                                ;
        bsf     vI2CMIntStatus,I2CMErrBusCollision        ;
        bcf     PIR2,BCLIF                      ;
                                                ;
        #endif                                  ;
                                                ;
        return                                  ;
                                                ;
I2CMYes                                         ;
        movf    SSPCON,w                        ;
        andlw   00fh                            ;
        xorlw   008h                            ;
        btfss   STATUS,Z                        ;
        return                                  ;check is Master Mode
                                                ;
        btfsc   _vI2CMIntState,I2CMTransmitState;
        goto    I2CMTransmit                    ;
                                                ;
        btfsc   _vI2CMIntState,I2CMCheckAckState;
        goto    I2CMCheckAck                    ;17 + 66
                                                ;
        btfsc   _vI2CMIntState,I2CMReceiveState ;
        goto    I2CMReceive                     ;20 + 59
                                                ;
        btfsc   _vI2CMIntState,I2CMReceiveEnState;
        goto    I2CMReceiveEn                   ;
                                                ;
        btfss   _vI2CMIntState,I2CMStopState    ;
        goto    I2CMEnd                         ;
                                                ;
        PAGESEL I2CMSendStop                    ;
        goto    I2CMSendStop                    ;
                                                ;
;***********************************************;

;***********************************************;
I2CMCheckAck                                    ;
                                                ;
        BANKSEL SSPCON2                         ;
        btfss   SSPCON2,ACKSTAT                 ;checking for acknowledge received.
        goto    I2CMCheckWhatNext               ;
                                                ;
        bsf     vI2CMIntStatus,I2CMErrNoAck     ;
        PAGESEL I2CMSendStop                    ;
        goto    I2CMSendStop                    ;
                                                ;
I2CMCheckWhatNext                               ;
        btfss   _vI2CMIntState,I2CMRStrt        ;Is repeated Start to be sent
        goto    I2CMTransmit                    ;
                                                ;
        BANKSEL _vI2CMIntRSPnt                  ;
        movf    _vI2CMIntRSPnt,f                ;
        PAGESEL I2CMSendReStart                 ;
        btfsc   STATUS,Z                        ;If yes is this the point where it has to be sent
        goto    I2CMSendReStart                 ;if yes goto send 
                                                ;
;-----------------------------------------------;
I2CMTransmit                                    ;
                                                ;
        BANKSEL _vI2CMIntTxDataCount            ;
        movf    _vI2CMIntTxDataCount,f          ;Is transmission of all bytes over
        btfss   STATUS,Z                        ;
        goto    I2CMRdTxData                    ;If not goto read data to be transmitted
                                                ;
        movf    _vI2CMIntRxDataCount,f          ;If data to be received
        btfss   STATUS,Z                        ;
        goto    I2CMReceiveEn                   ;goto enable receiver
                                                ;
        PAGESEL I2CMSendStop                    ;
        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          ;decrement the Tx Data Count
        decf    _vI2CMIntRSPnt,f                ;
                                                ;
        BANKSEL SSPBUF                          ;
        movwf   SSPBUF                          ;
                                                ;
        bcf     PIR1,SSPIF                      ;clear serial_sync intrupt flag
                                                ;
        return                                  ;
                                                ;
;***********************************************;

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


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

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

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

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





;_I2CMINTRDBUF                                                           
;***********************************************************************;
; 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                                  ;
                                                ;
        BANKSEL _vI2CMIntDupFSR                 ;
        movf    FSR,w                           ;Save FSR
        movwf   _vI2CMIntDupFSR                 ;
                                                ;
        BANKSEL _vI2CMIntBufRdPtr               ;
        movlw   vI2CMIntBuffer                  ;load wreg with read pointer address
        addwf   _vI2CMIntBufRdPtr,w             ;
        movwf   FSR                             ;load fsr with read pointer address
        movf    INDF,w                          ;move wreg the content of read pointer address
                                                ;
        BANKSEL _vI2CMIntTempReg                ;
        movwf   _vI2CMIntTempReg                ;read data is saved in temflg
                                                ;
        movf    _vI2CMIntDupFSR,w               ;Retrive FSR
        movwf   FSR                             ;
                                                ;
        BANKSEL _vI2CMIntBufRdPtr               ;
        incf    _vI2CMIntBufRdPtr,f             ;increment read pointer
        movlw   I2CM_BUFFER_LENGTH              ;
        xorwf   _vI2CMIntBufRdPtr,w             ;
        btfsc   STATUS,Z                        ;
        clrf    _vI2CMIntBufRdPtr               ;
                                                ;
        movf    _vI2CMIntBufRdPtr,w             ;Check is buffer empty
        xorwf   _vI2CMIntBufWrPtr,w             ;
        btfss   STATUS,Z                        ;
        goto    I2CBufNotEmt                    ;
        bcf     vI2CMIntStatus,I2CMDataReady    ;
        bsf     vI2CMIntStatus,I2CMBufEmpty     ;
                                                ;
I2CBufNotEmt                                    ;
        BANKSEL _vI2CMIntTempReg                ;
        movf    _vI2CMIntTempReg,w              ;Get the read data in 'W'
                                                ;
        bcf     vI2CMIntStatus,I2CMBufFull      ;
        bcf     vI2CMIntStatus,I2CMBufOverFlow  ;
                                                ;
        return                                  ;
;***********************************************;37



;_I2CMINTWRBUF                                                           
;***********************************************************************;
; Function: _I2CMIntWrBuf                                               ;
;                                                                       ;
; PreCondition: None.                                                   ;
;                                                                       ;
; Overview:                                                             ;
;       This writes data into buffer.                                   ; 
;                                                                       ;
; Input: 'W' Register                                                   ;
;                                                                       ;
; Output: None                                                          ;
;                                                                       ;
; Side Effects: Bank selection bits and 'W' register are changed        ;
;                                                                       ;
; Stack requirement: 1 level deep                                       ;
;                                                                       ;
;***********************************************;***********************;
                                                ;        
_I2CMIntWrBuf:                                  ;
        btfsc   vI2CMIntStatus,I2CMBufFull      ;
        return                                  ;
                                                ;        
                                                ;
        BANKSEL _vI2CMIntTempReg                ;
        movwf   _vI2CMIntTempReg                ;save the Data in tempreg
                                                ;
        movf    FSR,w                           ;Save FSR
        movwf   _vI2CMIntDupFSR                 ;
                                                ;
        BANKSEL _vI2CMIntBufWrPtr               ;
        movlw   vI2CMIntBuffer                  ;load wreg with write pointer address
        addwf   _vI2CMIntBufWrPtr,w             ;
                                                ;
        movwf   FSR                             ;
        BANKSEL _vI2CMIntTempReg                ;
        movf    _vI2CMIntTempReg,w              ;
        movwf   INDF                            ;move wreg content to write pointer pointing location
                                                ;
        movf    _vI2CMIntDupFSR,w               ;Retrive FSR
        movwf   FSR                             ;
                                                ;
        BANKSEL _vI2CMIntBufWrPtr               ;
        incf    _vI2CMIntBufWrPtr,f             ;increment write pointer
        movlw   I2CM_BUFFER_LENGTH              ;
        xorwf   _vI2CMIntBufWrPtr,w             ;
        btfsc   STATUS,Z                        ;
        clrf    _vI2CMIntBufWrPtr               ;
                                                ;
        movf    _vI2CMIntBufWrPtr,w             ;Check is buffer full
        xorwf   _vI2CMIntBufRdPtr,w             ;
        btfsc   STATUS,Z                        ;
        bsf     vI2CMIntStatus,I2CMBufFull      ;
                                                ;
        bcf     vI2CMIntStatus,I2CMBufEmpty     ;
                                                ;
        return                                  ;
                                                ;
;***********************************************;32



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




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





