;************************************************************************
;                                                                       *
;   Filename:      BA_L5-Flash+PB_LED.asm                               *
;   Date:          25/12/08                                             *
;   File Version:  1.2                                                  *
;                                                                       *
;   Author:        David Meiklejohn                                     *
;   Company:       Gooligum Electronics                                 *
;                                                                       *
;************************************************************************
;                                                                       *
;   Architecture:  Baseline PIC                                         *
;   Processor:     12F508/509                                           *
;                                                                       *
;************************************************************************
;                                                                       *
;   Files required: none                                                *
;                                                                       *
;************************************************************************
;                                                                       *
;   Description:    Lesson 5, example 2                                 *
;                                                                       *
;   Demonstrates use of Timer0 to maintain timing of background actions *
;   while performing other actions in response to changing inputs       *
;                                                                       *
;   One LED simply flashes at 1 Hz (50% duty cycle).                    *
;   The other LED is only lit when the pushbutton is pressed            *
;                                                                       *
;************************************************************************
;                                                                       *
;   Pin assignments:                                                    *
;       GP1 - "button pressed" indicator LED                            *
;       GP2 - flashing LED                                              *
;       GP3 - pushbutton                                                *
;                                                                       *
;************************************************************************

    list        p=12F509      
    #include    <p12F509.inc>

                ; int reset, no code protect, no watchdog, 4MHz int clock
    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC


;***** VARIABLE DEFINITIONS
        UDATA_SHR
sGPIO   res 1                   ; shadow copy of GPIO

        UDATA
dlycnt  res 1                   ; delay counter


;************************************************************************
RESET   CODE    0x000           ; effective reset vector
        movwf   OSCCAL          ; update OSCCAL with factory cal value 


;***** MAIN PROGRAM

;***** Initialisation
start	
        movlw   b'111001'       ; configure GP1 and GP2 (only) as outputs
        tris    GPIO  
        movlw   b'11010100'     ; configure Timer0:
                ; --0-----          timer mode (T0CS = 0)
                ; ----0---          prescaler assigned to Timer0 (PSA = 0)
                ; -----100          prescale = 32 (PS = 100)            
        option                  ;   -> increment every 32 us

        clrf    GPIO            ; start with all LEDs off
        clrf    sGPIO           ;   update shadow


;***** Main loop
loop    ; delay 500ms
        banksel dlycnt
        movlw   .125            ; repeat 125 times
        movwf   dlycnt          ; -> 125 x 4ms = 500ms 
dly500  ; (begin 500ms delay loop)
        clrf    TMR0            ; clear timer0 
w_tmr0      ; check and respond to button press      
        bcf     sGPIO,1         ; assume button up -> LED off
        btfss   GPIO,3          ; if button pressed (GP3 low)
        bsf     sGPIO,1         ;   turn on LED

        movf    sGPIO,w         ; copy shadow to GPIO
        movwf   GPIO
            ; check timer0 until 4ms elapsed
        movf    TMR0,w         
        xorlw   .125            ; (4ms = 125 x 32us)            
        btfss   STATUS,Z
        goto    w_tmr0
        ; (end 500ms delay loop)
        decfsz  dlycnt,f        
        goto    dly500

        ; toggle LED       
        movf    sGPIO,w
        xorlw   b'000100'       ; toggle LED on GP2
        movwf   sGPIO           ;   using shadow register

        ; repeat forever
        goto    loop           


        END

