;******************************************************************************
;* This file contains  the macros of 10 bit ADC library module for 
;* interrupt option
;******************************************************************************
;*File name:      ADCInt.inc
;*Dependencies:   ADCInt.asm
;*Processors:     PIC18                          
;*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
;*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;* B.K. Anantha Ramu    May 13, 2003    Initial Release (V1.0)
;* 
;********************************************************************/
#ifndef __ADCInt_INC                    ;Check if inc file already included
    #define __ADCInt_INC                

    #include <ADCInt.def>               ;This file is created by MpAM, with 
                                        ;user entered options
;------------------------------------------------------------------------------


                                        ;ADCInt_Source to be defined where the 
                                        ;variables are declared. 
    IFNDEF ADCInt_Source

        IFDEF __18F1220
            ERROR  "This library module is not compatible for the selected processor"
        ENDIF 

        IFDEF __18F1320
             ERROR "This library module is not compatible for the selected processor"
        ENDIF 

        #define A2D_10BIT_MODULE        ;With this definition, availability of
                                        ;module features will be known.
        #define _GEN_MODULE_ERROR       ;If ADC module is not available this 
                                        ;enables to generate error.
        #include <P18xxx.INC>           ;This defines module features for 
                                        ;different processors.
        EXTERN vADCIntChannelNumber_A   ;These variables/functions are defined
        EXTERN _ADCIntChannelSelect     ;in ADCInt.asm file
        EXTERN ADCIntAcquisitionTime    ;
        EXTERN ADCIntISR                ;
        EXTERN ADCIntRead               ;
        EXTERN ADCIntBufInit
        EXTERN vADCIntStatus            ;
        EXTERN vADCIntResultsCount      ;
        EXTERN vADCIntBufRdPtr          ;
        EXTERN vADCIntBufWrPtr          ;
        EXTERN vADCIntResultHigh
        IFNDEF   _LEFT8BITS
            EXTERN vADCIntResultLow     ;If selected resolution is 10 bits
        ENDIF                           ;vADCIntResultLow is defined.

    ELSE
        GLOBAL vADCIntChannelNumber_A
        GLOBAL _ADCIntChannelSelect
        GLOBAL ADCIntAcquisitionTime
        GLOBAL ADCIntISR
        GLOBAL ADCIntRead
        GLOBAL ADCIntBufInit
        GLOBAL vADCIntStatus 
        GLOBAL vADCIntResultsCount
        GLOBAL vADCIntBufRdPtr
        GLOBAL vADCIntBufWrPtr
        GLOBAL vADCIntResultHigh
        IFNDEF  _LEFT8BITS 
            GLOBAL vADCIntResultLow     ;If selected resolution is 10 bits
        ENDIF                           ;vADCIntResultLow is defined.
    ENDIF
;------------------------------------------------------------------------------
    #define ADCIntBufFull       0x0     ;This bit of vADCIntStatus when set 
                                        ;indicates buffer full.
    #define ADCIntBufEmpty      0x1     ;This bit of vADCIntStatus when set
                                        ;indicates buffer empty.
    #define ADCIntBufOverFlow   0x2     ;This bit of vADCIntStatus when set
                                        ;indicates buffer overflow condition. 
;------------------------------------------------------------------------------

    IFDEF   _LEFT10BITS                 ;User Resolution/format selection:
        #define  _ADCINT_LEFT           ;10 bits-Left justified.
        #define  _ADCINT_10BITS
    ENDIF

    IFDEF   _RIGHT10BITS                ;User Resolution/format selection:
        #define  _ADCINT_RIGHT          ;10 bits-Right justified.
        #define  _ADCINT_10BITS
    ENDIF

    IFDEF   _LEFT8BITS                  ;User Resolution/format selection:
        #define  _ADCINT_LEFT           ;8 bits-Left justified.
        #define  _ADCINT_8BITS
    ENDIF
;------------------------------------------------------------------------------
                                        ;The following lines extracts the 
                                        ;features of the processor used
                                        ;from P18xxx.inc file.
    IFDEF _A2D_10BIT_1CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'1'
    ENDIF

    IFDEF _A2D_10BIT_2CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'2'
    ENDIF

    IFDEF _A2D_10BIT_3CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'3'
    ENDIF

    IFDEF _A2D_10BIT_4CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'4'
    ENDIF

    IFDEF _A2D_10BIT_5CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'5'
    ENDIF

    IFDEF _A2D_10BIT_6CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'6'
    ENDIF

    IFDEF _A2D_10BIT_7CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'7'
    ENDIF

    IFDEF _A2D_10BIT_8CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'8'
    ENDIF

    IFDEF _A2D_10BIT_9CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'9'
    ENDIF

    IFDEF _A2D_10BIT_10CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'10'
    ENDIF

    IFDEF _A2D_10BIT_11CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'11'
    ENDIF

    IFDEF _A2D_10BIT_12CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'12'
    ENDIF

    IFDEF _A2D_10BIT_13CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'13'
    ENDIF

    IFDEF _A2D_10BIT_14CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'14'
    ENDIF

    IFDEF _A2D_10BIT_15CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'15'
    ENDIF

    IFDEF _A2D_10BIT_16CHANNEL_MODULE
        #define _ADCINT_CHANNELS D'16'
    ENDIF

    IFDEF _A2D_10BIT_4REGISTER_MODULE
        #define _ADCINT_PIC181          ;10 bit ADC with ADCON0,
    ENDIF                               ;ADCON1 registers. No ADCON2 register
        
    IFDEF _A2D_10BIT_5REGISTER_MODULE
        #define _ADCINT_PIC182          ;10 bit ADC with
    ENDIF                               ;ADCON0,ADCON1 & ADCON2 register


;------------------------------------------------------------------------------
;The following lines defines the constants which are used as input arguments for
;the macro mADCIntInit.
;Constants for ADC port configuration names
    CONSTANT ADCPORTCONFIG0 = D'0'
    CONSTANT ADCPORTCONFIG1 = D'1'
    CONSTANT ADCPORTCONFIG2 = D'2'
    CONSTANT ADCPORTCONFIG3 = D'3'
    CONSTANT ADCPORTCONFIG4 = D'4'
    CONSTANT ADCPORTCONFIG5 = D'5'
    CONSTANT ADCPORTCONFIG6 = D'6'
    CONSTANT ADCPORTCONFIG7 = D'7'
    CONSTANT ADCPORTCONFIG8 = D'8'
    CONSTANT ADCPORTCONFIG9 = D'9'
    CONSTANT ADCPORTCONFIG10 = D'10'
    CONSTANT ADCPORTCONFIG11 = D'11'
    CONSTANT ADCPORTCONFIG12 = D'12'
    CONSTANT ADCPORTCONFIG13 = D'13'
    CONSTANT ADCPORTCONFIG14 = D'14'
;Constants for ADC reference voltage configuration names
    CONSTANT ADCREFERENCECONFIG0  = D'0'
    CONSTANT ADCREFERENCECONFIG1  = D'1'
    CONSTANT ADCREFERENCECONFIG2  = D'2'
    CONSTANT ADCREFERENCECONFIG3  = D'3'                
;****************************************************************************
; Macro:        _mADCIntADCON1Set
;
; Overview:     Sets bits of ADCON1 reg as per user options
;
; Input:        Definitions from ADCInt.DEF, processor classification
;                ie: definitions _ADCINT_PIC181, _ADCINT_PIC182 etc. 
;               _ADCINT_PIC181: 10 bit ADC with ADCON0 & ADCON1 registers. No ADCON2
;                        register
;               _ADCINT_PIC182: 10 bit ADC with ADCON0, ADCON1 & ADCON2 registers
;
; Output:       ADCON1
;
; Side Effects: WREG changes
;
; Maximum instruction cycles: 2
;****************************************************************************
_mADCIntADCON1Set       MACRO
    IFDEF _ADCINT_PIC181 
        IFDEF _ADCINT_RIGHT
_ADCINT_RESULTFORMAT=B'10000000'
        ELSE
_ADCINT_RESULTFORMAT=B'00000000'
        ENDIF
        IFDEF _FOSC2
_ADCINT_ADCS2=B'00000000'
        ENDIF
        IFDEF _FOSC8
_ADCINT_ADCS2=B'00000000'
        ENDIF
        IFDEF _FOSC32
_ADCINT_ADCS2=B'00000000'
        ENDIF
        IFDEF _RCCLK
_ADCINT_ADCS2=B'01000000'
        ENDIF
        IFDEF _FOSC4
_ADCINT_ADCS2=B'01000000'
        ENDIF
        IFDEF _FOSC16
_ADCINT_ADCS2=B'01000000'
        ENDIF
        IFDEF _FOSC64
_ADCINT_ADCS2=B'01000000'
        ENDIF
        IF _port_config_name<D'6'
_ADCINT_PORTCONFIG=_port_config_name
        ELSE
_ADCINT_PORTCONFIG=_port_config_name+2
        ENDIF 

_ADCINT_ADCON1VALUE=_ADCINT_RESULTFORMAT|_ADCINT_ADCS2|_ADCINT_PORTCONFIG
        movlw   _ADCINT_ADCON1VALUE
        movwf   ADCON1
    ENDIF
    IFDEF _ADCINT_PIC182
_ADCINT_PORTCONFIG=_port_config_name
_ADCINT_REFERENCECONFIG=D'16'*_ref_config_name  ;ADC reference configuration bits occupy
                                                ;positions 4 & 5. Hence they are shifted
                                                ;by 4 positions.      
_ADCINT_ADCON1VALUE=_ADCINT_REFERENCECONFIG|_ADCINT_PORTCONFIG
        movlw   _ADCINT_ADCON1VALUE
        movwf   ADCON1
    ENDIF
    ENDM
;****************************************************************************
; Macro:        _mADCIntADCON2Set
;
; Overview:     Sets ADCON2 bits as per user options
;               
;
; Input:        Definitions from ADCInt.DEF,processor classification
;               ie: definitions _ADCINT_PIC181, _ADCINT_PIC182 etc.
;               _ADCINT_PIC181: 10 bit ADC with ADCON0 & ADCON1 registers. No ADCON2
;                        register
;               _ADCINT_PIC182: 10 bit ADC with ADCON0, ADCON1 & ADCON2 registers 
;
; Output:       ADCON2
;
; Side Effects: WREG changes
;
; Maximum instruction cycles: 2
;****************************************************************************
_mADCIntADCON2Set       MACRO
    IFDEF _ADCINT_PIC182 

        IFDEF _ADCINT_RIGHT
_ADCINT_RESULTFORMAT=B'10000000'
        ELSE
_ADCINT_RESULTFORMAT=B'00000000'
        ENDIF
        IFDEF _FOSC2
_ADCINT_CLOCK=B'00000000'
        ENDIF
        IFDEF _FOSC8
_ADCINT_CLOCK=B'00000001'
        ENDIF
        IFDEF _FOSC32
_ADCINT_CLOCK=B'00000010'
        ENDIF
        IFDEF _RCCLK
_ADCINT_CLOCK=B'00000011'
        ENDIF
        IFDEF _FOSC4
_ADCINT_CLOCK=B'00000100'
        ENDIF
        IFDEF _FOSC16
_ADCINT_CLOCK=B'00000101'
        ENDIF
        IFDEF _FOSC64
_ADCINT_CLOCK=B'00000110'
        ENDIF
_ADCINT_ADCON2VALUE=_ADCINT_RESULTFORMAT|_ADCINT_CLOCK
        movlw   _ADCINT_ADCON2VALUE
        movwf   ADCON2
    ENDIF
    ENDM
;****************************************************************************
; Macro:        _mADCIntADCON0Set
;
; Overview:     Sets ADCON0 bits as per user options
;               
;
; Input:        Definitions from ADCInt.DEF,processor classification
;               ie: definitions _ADCINT_PIC181, _ADCINT_PIC182 etc.
;               _ADCINT_PIC181: 10 bit ADC with ADCON0 & ADCON1 registers. No ADCON2
;                        register
;               _ADCINT_PIC182: 10 bit ADC with ADCON0, ADCON1 & ADCON2 registers 
;
; Output:       ADCON0
;
; Side Effects: WREG changes
;
; Maximum instruction cycles: 2
;****************************************************************************
_mADCIntADCON0Set       MACRO
    IFDEF _ADCINT_PIC181 
        IFDEF _FOSC2
_ADCINT_CLOCK=B'00000000'
        ENDIF
        IFDEF _FOSC8
_ADCINT_CLOCK=B'01000000'
        ENDIF
        IFDEF _FOSC32
_ADCINT_CLOCK=B'10000000'
        ENDIF
        IFDEF _RCCLK
_ADCINT_CLOCK=B'11000000'
        ENDIF
        IFDEF _FOSC4
_ADCINT_CLOCK=B'00000000'
        ENDIF
        IFDEF _FOSC16
_ADCINT_CLOCK=B'01000000'
        ENDIF
        IFDEF _FOSC64
_ADCINT_CLOCK=B'10000000'
        ENDIF

_ADCINT_CHANNEL=B'00000000'
          

_ADCINT_ON=1
_ADCINT_START=0
_ADCINT_ADCON0VALUE=_ADCINT_CLOCK|_ADCINT_CHANNEL|_ADCINT_START|_ADCINT_ON
        movlw   _ADCINT_ADCON0VALUE
        movwf   ADCON0
    ENDIF

    IFDEF _ADCINT_PIC182
_ADCINT_CHANNEL=B'00000000'

_ADCINT_START=B'00000000'
_ADCINT_ON=B'00000001'

_ADCINT_ADCON0VALUE=_ADCINT_CHANNEL|_ADCINT_START|_ADCINT_ON
        movlw   _ADCINT_ADCON0VALUE
        movwf   ADCON0
    ENDIF
    ENDM
;****************************************************************************
; Macro:        mADCIntReadHigh
;
; Overview:     This reads high byte of the ADC result register ADRESH.
;
; Input:        None
;
; Output:       WREG
;
; Side Effects: STATUS changes.
;
; Maximum instruction cycles: 1
;******************************************************************************
mADCIntReadHigh         MACRO

        movf    ADRESH,W
        ENDM

;****************************************************************************
; Macro:        mADCIntReadLow
;
; Overview:     This reads low byte of the ADC result register ADRESL.
;
; Input:        None
;
; Output:       WREG
;
; Side Effects: STATUS changes.
;
; Maximum instruction cycles: 1
;******************************************************************************
mADCIntReadLow          MACRO
        movf    ADRESL,W
        ENDM


;****************************************************************************
; Macro:        mADCIntInit
;
; Overview:     Configures ADC as per user options.
;               This sets channel 0 as default ADC channel.
;               If user wants to use a different channel, he can select
;               the required channel by invoking macro mADCIntChannelSelect.
;               Enables ADC interrupt. 
;        
;
; Input:        _port_config_name: The port configuration name is used to define
;                analog & digital ports.
;                _ref_config_name: The ADC reference voltage configuration name
;                is used to define ADC reference voltage source & it is required only 
;               for _ADCINT_PIC182 processors.
;               Definitions from ADCInt.DEF & P18xxx.inc
;               _ADCINT_PIC181: 10 bit ADC with ADCON0 & ADCON1 registers. No ADCON2
;               register
;               _ADCINT_PIC182: 10 bit ADC with ADCON0, ADCON1 & ADCON2 registers 
;
; Output:       ADCON0,ADCON1,ADCON2,PIR1, PIE1, INTCON, vADCIntStatus, 
;               vADCIntResultsCount, vADCIntBufRdPtr, vADCIntBufWrPtr
;
; Side Effects:  WREG, STATUS, BSR changes
; Stack requirement: 1 level deep
; Maximum instruction cycles: 20
;****************************************************************************
    IFDEF _ADCINT_PIC181
mADCIntInit             MACRO   _port_config_name
        IF (_port_config_name >=0 && _port_config_name <=D'13')

            _mADCIntADCON2Set   ;Sets ADCON2(if existing) reg bits as per user options & processor
            _mADCIntADCON1Set   ;Sets ADCON1 reg bits as per user options & processor 
            _mADCIntADCON0Set   ;Sets ADCON0 reg bits as per user options & processor
            call ADCIntBufInit  ;Clears ADCIntBufFull, ADCIntBufOverFlow flags.
                                ;Sets ADCIntBufEmpty flag. Clears read & write
                                ;pointers.  
            _mADCIntInterruptInit   ;Enables ADC interrupt
        ELSE
             ERROR "Argument(Port configuration name) for macro mADCIntInit is not correct"
        ENDIF
        ENDM        
    ENDIF
    IFDEF _ADCINT_PIC182
mADCIntInit             MACRO   _port_config_name,_ref_config_name
    IF (_port_config_name<0||_port_config_name>D'14')
            ERROR "Argument(Port configuration name) for macro mADCIntInit is not correct"
        EXITM
        ENDIF
        IF (_ref_config_name<0||_ref_config_name>D'3')
            ERROR "Argument(Ref configuration name) for macro mADCIntInit is not correct"
        EXITM
        ENDIF

        _mADCIntADCON2Set   ; sets ADCON2(if existing) reg bits as per user options & processor 
        _mADCIntADCON1Set   ; sets ADCON1 reg bits as per user options & processor 
        _mADCIntADCON0Set   ; sets ADCON0 reg bits as per user options & processor
         call ADCIntBufInit ;Clears ADCIntBufFull, ADCIntBufOverFlow flags.
                            ;Sets ADCIntBufEmpty flag. Clears read & write
                            ;pointers.
        _mADCIntInterruptInit   ;Enables ADC interrupt.

        ENDM 
    ENDIF




;*****************************************************************************
; Macro:        mADCIntStart
;
; Overview:     Starts AD conversion by setting GO bit of ADCON0. 
;               
;
; Input:        None
;
; Output:       None
;                            
; Side Effects: None
;
; Maximum instruction cycles: 1
;*****************************************************************************
mADCIntStart            MACRO
        bsf     ADCON0,GO
        ENDM

;*****************************************************************************
; Macro:        mADCIntDisable
;
; Overview:     Switches off the ADC & disables ADC interrupt.
;               
; Input:        None
;
; Output:       None
;                            
; Side Effects: None
;
; Maximum instruction cycles: 2
;*****************************************************************************
mADCIntDisable          MACRO
        bcf     ADCON0,ADON
        bcf     PIE1, ADIE                
        ENDM 
;*****************************************************************************
; Macro:        mADCIntIsBusy
;
; Overview:     checks GO bit of ADCON0
;               
; Input:        None
;
; Output:       WREG contains 0 if ADC not busy, 1 if ADC is busy. 
;                            
; Side Effects: None
;
; Maximum instruction cycles: 3
;*****************************************************************************
mADCIntIsBusy           MACRO
        movlw   0
        btfsc   ADCON0,GO
        movlw   1
        ENDM
;*****************************************************************************
; Macro:        mADCIntChannelSelect
;
; Overview:     This macro selects the ADC channel.   
;               
; Input:        Channel number as macro argument.
;
; Output:       ADCON0    
;                            
; Side Effects: WREG, STATUS changes
;
; Maximum instruction cycles: 12
;*****************************************************************************
mADCIntChannelSelect    MACRO   channel_number
    IF channel_number<_ADCINT_CHANNELS
        movlw   channel_number
        call    _ADCIntChannelSelect
    ELSE
        MESSG "WARNING: The  processor does not have the selected ADC channel"
    ENDIF
    ENDM

;*****************************************************************************
; Macro:        mSetADCIntHighPriority 
;
; Overview:     This macro sets high priority for ADC interrupt.    
;               
; Input:        None
;
; Output:       None  
;                            
; Side Effects: None
;
; Maximum instruction cycles: 2
;*****************************************************************************
mSetADCIntHighPriority  MACRO
        bsf     IPR1,ADIP
        bsf     RCON,IPEN
        ENDM
;*****************************************************************************
; Macro:        mSetADCIntLowPriority 
;
; Overview:     This macro sets low priority for ADC interrupt.    
;               
; Input:        None
;
; Output:       None  
;                            
; Side Effects: None
;
; Maximum instruction cycles: 2
;*****************************************************************************
mSetADCIntLowPriority   MACRO
        bcf     IPR1,ADIP
        bsf     RCON,IPEN
        ENDM



;*****************************************************************************
; Macro:        _mADCIntIntrInit 
;
; Overview:    This macro enables ADC interrupt 
;               
;               
; Input:        None
;
; Output:       PIR1, PIE1, INTCON  
;                            
; Side Effects: None
;
; Maximum instruction cycles: 4
;*****************************************************************************
_mADCIntInterruptInit    MACRO
        bcf     PIR1,ADIF               ;Clears ADC interrupt before start
        bsf     PIE1,ADIE               ;ADC interrupt enabled
        bsf     INTCON,PEIE             ;Peripheral interrupt enabled
        bsf     INTCON,GIE              ;Global interrupt enabled
        ENDM
;*****************************************************************************

#endif                                  ;For inc file check.

