;************************************************************************
;                                                                       *
;   Filename:      BA_L6-Macro_debounce-cond.asm                        *
;   Date:          6/9/09                                               *
;   File Version:  1.4                                                  *
;                                                                       *
;   Author:        David Meiklejohn                                     *
;   Company:       Gooligum Electronics                                 *
;                                                                       *
;************************************************************************
;                                                                       *
;   Architecture:  Baseline PIC                                         *
;   Processor:     12F508/509                                           *
;                                                                       *
;************************************************************************
;                                                                       *
;   Files required: none                                                *
;                                                                       *
;************************************************************************
;                                                                       *
;   Description:    Lesson 6, example 6                                 *
;                   Toggles LED when button is pressed                  *
;                                                                       *
;   Demonstrates use of conditional assembly                            *
;   to select alternate configurations and pin assignments              *
;                                                                       *
;************************************************************************

    list        p=12F509 
    #include    <p12F509.inc>


;***** CONFIGURATION
    #define     DEBUG
    constant    REV='A'             ; hardware revision

    IFDEF DEBUG
                    ; int reset, no code protect, no watchdog, 4MHz int clock
        __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC
    ELSE
                    ; int reset, code protect on, watchdog on, 4MHz int clock
        __CONFIG    _MCLRE_OFF & _CP_ON & _WDT_ON & _IntRC_OSC
    ENDIF

; pin assignments
    IF REV=='A'                         ; pin assignments for REV A:
        constant    nLED=1              ;   indicator LED on GP1
        #define     BUTTON  GPIO,3      ;   pushbutton on GP3
    ENDIF
    IF REV=='B'                         ; pin assignments for REV B:
        constant    nLED=2              ;   indicator LED on GP2
        #define     BUTTON  GPIO,5      ;   pushbutton on GP5
    ENDIF
    IF REV!='A' && REV!='B'
        ERROR "Revision must be 'A' or 'B'"
    ENDIF


;***** MACROS

; Debounce switch on given input port,pin
; Waits for switch to be 'high' continuously for 10ms
;
; Uses:	TMR0		Assumes: TMR0 running at 256us/tick
;
DbnceHi MACRO   port,pin
    local       start,wait,DEBOUNCE
    variable    DEBOUNCE=.10*.1000/.256 ; switch debounce count = 10ms/(256us/tick)

        pagesel $               ; select current page for gotos
start   clrf    TMR0            ; button down so reset timer (counts "up" time)
wait    btfss   port,pin        ; wait for switch to go high (=1)
        goto    start 
        movf    TMR0,w          ; has switch has been up continuously for debounce time?
        xorlw   DEBOUNCE
        btfss   STATUS,Z        ; if not, keep checking that it is still up
        goto    wait
        ENDM


;***** VARIABLE DEFINITIONS
        UDATA_SHR
sGPIO   res 1                   ; shadow copy of GPIO


;************************************************************************
RESET   CODE    0x000           ; effective reset vector
        movwf   OSCCAL          ; update OSCCAL with factory cal value 


;***** MAIN PROGRAM

;***** Initialisation
start
        movlw   ~(1<<nLED)      ; configure LED pin (only) as output 
        tris    GPIO    

        movlw   b'11010111'     ; configure Timer0:
                ; --0-----          timer mode (T0CS = 0)
                ; ----0---          prescaler assigned to Timer0 (PSA = 0)
                ; -----111          prescale = 256 (PS = 111)          
        option                  ;   -> increment every 256 us

        clrf    GPIO            ; start with LED off
        clrf    sGPIO           ;   update shadow

;***** Main loop
loop
wait_dn btfsc   BUTTON         ; wait for button press (=0)
        goto    wait_dn 

        movf    sGPIO,w         ; toggle LED 
        xorlw   1<<nLED         ;   using shadow register
        movwf   sGPIO           
        movwf   GPIO            ;   write to port

        DbnceHi BUTTON          ; wait until button released

        ; repeat forever
        goto    loop        


        END


