; 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