DRUID Development Docs: ginput_isr.inc

Gadget Sourcecode: ginput_isr.inc

; Justice Unlimited Gadget Microcode
; (C) 2004 Nathan (Acorn) Pooley 
;
; ginput_isr.inc
;
;@DOC@ spinner and button interrupt service routines
;


;############################################
;############### PORTB INTERRUPT ############
;############################################


    ;
    ; handle PORTB when bit7 goes on or off
    ;
    ; PORTB has already been stored into INDF1 (which has been inc)
    ;
    ;   v_bnopush         - hi bit clear if any buttons were held in
    ;   v_oldb            - old value of PORTB (spinner bits cleared
    ;   v_bdebounce       - recently toggled buttons clear
    ;                       other bits set
    ;   v_changed         - (not persistant) bits that changed and
    ;                       are not already being debounced
    ;   v_brelmask        - bits cleared here will not be recorded 
    ;                        when released (they were held in)
    ;
    ;   v_bheld           - buttons held in for a while (not cleared in isr)
isr_button:

    ;
    ; remember that buttons are toggling
    ;
    clrf    v_bnopush       ; buttons are pressed (only hi bit matters)

    ;
    ; check for overflow
    ;
    movf    FSR1L,w
    subwf   v_inbuf_ptr,w   ; overflow buffer?
    bz      isr_btn_overflow    ; YES - OVERFLOW

    ;
    ; get value from input buffer
    ; set hi bit in input buffer so byte will be used as spinner byte
    ;
    decf    FSR1L,f
    comf    INDF1,w         ; PORTB value
    bsf     INDF1,7         ; set hi bit (this is spinner info, not button)
    incf    FSR1L,f         ; put back onto input buffer


    andlw   0x9f            ; ignore spinner value
;   btfsc   STATUS,Z        ; anything pressed?
;   setf    v_bnopush       ; no buttons are pressed (only hi bit matters)

    ;
    ; determine which bits changed and are not already being debounced
    ;
    xorwf   v_oldb,w        ; get change
    andwf   v_bdebounce,w   ; ignore debounce bits

    ;
    ; if no bits changed, we are done
    ;
    btfsc   STATUS,Z
    retfie  1               ; done if no change

    xorwf   v_oldb,f        ; store new value

    ;
    ; bits changed - record which ones and start debounce timer
    ;
    movwf   v_bchanged      ; these bits changed
    comf    v_bchanged,w
    andwf   v_bdebounce,f   ; turn off changed bits (we are now debouncing                          ; them)

    ;
    ; what buttons got released
    ;
    comf    v_oldb,w        ; get current bits
    andwf   v_bchanged,w    ; buttons that were released
    andwf   v_brelmask,w    ; ignore buttons held for a long time
    bz      isr_btn_relmask ; none released?
    
    ;
    ; button was released - record it
    ;
    ; TODO: to support more than 1 button record which one was released
    ;
    movlw   0x00
    movwf   INDF1
    incf    FSR1L,f

    ;
    ; check for overflow
    ;
    movf    FSR1L,w
    subwf   v_inbuf_ptr,w   ; overflow buffer?
    bz      isr_btn_overflow    ; YES - OVERFLOW

isr_btn_relmask:
    comf    v_oldb,w        ; get current bits
    andwf   v_bchanged,w    ; buttons that were released
    iorwf   v_brelmask,f    ; stop ignoring these bits

    ;
    ; TODO - enable this if need button presses
    ;
#if 0
    ;
    ; what buttons got pressed?
    ;
    movf    v_oldb,w        ; get current bits
    andwf   v_bchanged,w    ; buttons that were pressed
    bz      isr_btn_timer2  ; none pressed?

    ;
    ; button was pressed - record it
    ;
    ; TODO: to support more than 1 button record which one was pressed
    ;
    movlw   0x01
    movwf   INDF1
    incf    FSR1L,f

    ;
    ; check for overflow
    ;
    movf    FSR1L,w
    subwf   v_inbuf_ptr,w   ; overflow buffer?
    bz      isr_btn_overflow    ; YES - OVERFLOW

#endif

    ;
    ; setup timer2 for debouncing
    ;
isr_btn_timer2:
    movlw   HOLD_CNT
    movwf   v_bhold_cnt     ; reset hold counter
    clrf    TMR2
    bsf     b_tmr2on
    bcf     b_tmr2if        ; in case it just timed out
    retfie  1

    ;
    ; overflowed input buffer
    ;
isr_btn_overflow:
    bcf     b_rbie          ; disable PORTB interrupt for a while
    decf    FSR1L,f         ; remove extra byte
    bra     isr_btn_timer2  ; start timer2 (to re-enable PORTB intr)

;############################################
;############### TIMER2 - DEBOUNCE ##########
;############################################

    ;
    ; timer2 timed out - buttons are now debounced
    ;
isr_timer2:
    bcf     b_rbie          ; disable PORTB interrupt while we do this
    btfss   b_tmr2if
    bra     isr_timer2_end  ; if PORTB interrupt just occured, skip

    setf    v_bdebounce     ; no longer debouncing
    bsf     b_rbif          ; force PORTB interrupt

    movf    v_oldb,w        ; get button state
    bnz     isr_timer2_holdcheck

    ;
    ; No buttons are pressed - stop handling button debouncing
    ;
    setf    v_bnopush       ; Stop forcing PORTB interrupt to examine
    bra     isr_timer2_hold

isr_timer2_holdcheck:
    decfsz  v_bhold_cnt,f   ; have buttons been held?
    bra     isr_timer2_end

    ;
    ; Turn off timer.  This happens in 2 cases:
    ;    a)  w==0   - no buttons are pressed, so stop handling buttons
    ;    b)  w!=0   - some buttons have been held in for a long time
    ;
isr_timer2_hold:
    bcf     b_tmr2on        ; turn off timer2 (do not need it now)
    andwf   v_brelmask,w    ; do not set held for buttons already marked held
    iorwf   v_bheld,f       ; add to held in buttons
    comf    WREG,w  
    andwf   v_brelmask,f    ; do not acknowledge these buttons releasing


isr_timer2_end:
    bcf     b_tmr2if        ; clear interrupt
    bsf     b_rbie          ; re-enable PORTB interrupts (PORTB interrupt
                            ;   will occur here)
    bra     isr_return      ; return from interrupt

This file Copyright (C) 2004 by Nathan (Acorn) Pooley
Go to DRUID Development page
Go to DRUID page
Go to JU Gadgets page
Go to Justice Unlimited homepage
Go to Acorn's personal webpage
Contact Acorn
See comments from others
Post your own comments
File created by do_doc at Wed Aug 4 17:53:31 2004