; Justice Unlimited Gadget Microcode ; (C) 2004 Nathan (Acorn) Pooley ; ; gmain.inc ; ;@DOC@ main loop and sleep/wake/on/off code ; ;############################################ ;############### WAKE UP #################### ;############################################ ; wake up and stay in same mode we were in before sleep wake_up: ENABLE_SPINNER bsf b_rbif ; force PORTB interrupt bsf b_rbie ; enable PORTB interrupt bra main_start ; continue into main ;############################################ ;############### BUTTON WAIT ################ ;############################################ ; ; wait until button has been unpressed for a while (debounce) ; turn_onoff_but_wait: movlw TURN_ON_WAIT_TIME movwf v_tmp2 turn_onoff_but_loop: call time movlw TURN_ON_WAIT_TIME btfss PORTB,7 movwf v_tmp2 ; reset tmp2 if button is held in decfsz v_tmp2,f ; loop until tmp2 empties bra turn_onoff_but_loop return ;############################################ ;############### INIT_OFF ################### ;############################################ ; ; turn off spinner, checking for movement ; INPUT CONDITIONS: ; b_turn_off = 0: sleep ; 1: turn off immediately ; ; turn_off: DISABLE_IR ENABLE_SPINNER nop ; wait for spinner to turn on nop movf PORTB,w ; get PORTB current val bcf b_rbie ; disable portb interrupt ; ; save PORTB value ; movwf v_off_bval DISABLE_SPINNER ; ; sleep or turn off? ; btfsc b_turn_off bra turn_off_now btfsc b_showing_time bra wake_up ; ; abort sleep if timer2 is on - a button must have been pressed ; btfsc b_tmr2on bra wake_up ; ; abort sleep if we got a spinner change just before disabling ; interrupts ; btfsc b_got_input bra wake_up ; ; abort sleep if buttons pressed ; btfss v_off_bval,7 bra wake_up ; ; fall thru to sleep ; ;############################################ ;############### SLEEP ###################### ;############################################ ; ; THIS SHOULD ONLY BE CALLED FROM turn_off (above) ; ; ; "SLEEP" looks just like "ON", but spinner is disabled ; ; at this point: ; spinner is turned off ; v_off_bval = last PORTB value ; fall_asleep: ; ; Set sleep-off timer (time until we turn off) ; movlw SLEEP_OFF_TIME ; turn off after this long btfss disab_light movlw SLEEP_OFF_TIME_LIGHT ; faster if light is on call set_sleep_time sleep_main_loop: movlw SLEEP_NOSPIN_TIME ; keep spinner off this long movwf v_tmp2 call time ; call time every 1/10 sec (only needed ; about once per sec) sleep_loop1: movf PORTB,w xorwf v_off_bval,w andlw 0x9f ; ignore spinner bnz wake_up ; wake up if button was pressed decfsz v_tmp2,f ; loop until time to check spinner bra sleep_loop1 ; loop until PORTB changes ; ; time to check spinner ; ENABLE_SPINNER nop ; allow time for spinner to turn on nop movf PORTB,w ; get spinner value DISABLE_SPINNER xorwf v_off_bval,w andlw 0x60 ; only look at spinner bits bnz wake_up ; ; is it time to turn off completely? ; btfss b_sleep bra sleep_main_loop ; keep sleeping ; ; fall thru to turn_off ; ;############################################ ;############### TURN OFF ################### ;############################################ ; ; THIS SHOULD ONLY BE CALLED FROM turn_off (above) ; ; ; "OFF" means display is off ; click = reset to welcome screen ; spin = wake up to where we were ; ; at this point: ; spinner is turned off ; v_off_bval = last PORTB value ; turn_off_now: ; ; turn stuff off ; bcf b_light rcall output_disable ; ; wait until button is unpressed (and debounced) ; (but only if turnoff was caused by button click) ; btfsc b_turn_off rcall turn_onoff_but_wait bsf v_off_bval,7 ; turn off button bit (1=unpressed) off_main_loop: bcf b_turn_off #if QUICK_TURNON ; ; set v_tmp2 as counter until time to check spinner ; movlw OFF_NOSPIN_QTIME ; keep spinner off this long movwf v_tmp2 #else ; QUICK_TURNON ; ; Set sleep-off timer (used to check spinner) ; movlw OFF_NOSPIN_TIME ; keep spinner off this long rcall set_sleep_time #endif ; QUICK_TURNON off_loop1: call time ; call time repeatedly btfss PORTB,7 ; button pressed? bra turn_on_click ; yes - turn on! #if SIMULATE_INPUT movf PORTB,w xorwf v_off_bval,w andlw 0x88 bnz turn_on_click movf PORTB,w xorwf v_off_bval,w andlw 0x66 bnz turn_on_spin #endif #if QUICK_TURNON decfsz v_tmp2,f ; loop until time to check spinner bra off_loop1 #else ; QUICK_TURNON btfss b_sleep ; time to check spinner? bra off_loop1 ; no - keep waiting #endif ; QUICK_TURNON ; ; time to check spinner ; ENABLE_SPINNER nop ; allow time for spinner to turn on nop movf PORTB,w ; get spinner value DISABLE_SPINNER xorwf v_off_bval,w andlw 0x60 ; only look at spinner bits bz off_main_loop ; same - stay off btfsc PORTB,7 ; any buttons pressed? bra turn_on_spin ; turned on by spinner ; ; when spinner moved fall thru to turn_on_click ; ;############################################ ;############### TURN ON #################### ;############################################ turn_on_click: rcall init_mode ; reset to welcome screen ; ; wait until button is unpressed (and debounced) ; rcall turn_onoff_but_wait turn_on_spin: #if REPORT_ERRORS incf v_cnt_turnon,f #endif ; ; enable output ; clrf v_en_cnt rcall output_enable ; ; setup the current mode ; ; (NOTE: This calls input enable) ; rcall load_mode ; ; fall through to main loop ; ;############################################ ;############### MAIN LOOP ################## ;############################################ main_start: ; ; reset auto-off timer & turn-off bit ; bcf b_turn_off call reset_sleep_time ; set time until sleep main: #if SIMULATE_NOTIMEOUT call reset_sleep_time ; never fall asleep #endif rcall main_func btfss b_sleep bra main bra turn_off ;############################################ ;############### MAIN FUNCTION ############## ;############################################ ; ; called repeatedly from the main loop ; main_func: #if SIMULATE_INPUT sim_input: movf PORTB,w xorwf v_si_oldb,w andlw 0x0e btfsc STATUS,Z bra sim_input_end xorwf v_si_oldb,f movwf v_tmp call reset_sleep_time btfss v_tmp,3 bra sim_input_1 ; ; RB0 = button press ; movf v_func_btn0_click,w ; button clicked? goto main_jump sim_input_1: btfss v_tmp,1 bra sim_input_2 ; ; RB1 = dec ; bsf b_spinchange decfsz v_spinval,f bra sim_input_2 incf v_spinval,f btfsc b_spinwrap movff v_spinmax,v_spinval sim_input_2: btfss v_tmp,2 bra sim_input_3 ; ; RB2 = inc ; bsf b_spinchange incf v_spinval,f decf v_spinval,w subwf v_spinmax,w bnz sim_input_3 decf v_spinval,w btfsc b_spinwrap movlw 0x01 movwf v_spinval sim_input_3: sim_input_end: #endif #if TEST_INPUT btfss v_bheld,7 bra ti_2 nop ; HELD bcf v_bheld,7 return ti_2: btfss b_got_input bra ti_3 nop ; INPUT bra input return ti_3: btfss b_spinchange bra ti_4 nop ; SPINCHANGE bcf b_spinchange return ti_4: return ti_button_released: nop ; BUTTON RELEASED return #endif movf v_func_event1,w ; any events occurred? bnz main_bit_check movf v_func_event2,w bnz main_bit_check movf v_func_event3,w bnz main_bit_check movf v_func_default,w ; default function movf v_time_addsec,f ; need to update time? btfss STATUS,Z movlw func_time main_bit_check: btfsc b_spinchange movf v_func_spinchange,w ; spinner changed? btfsc b_got_input ; inbuf not empty? movlw func_input ; TODO: to support mulit-button decode v_bheld btfsc v_bheld,7 ; button0 was held in? bra light_toggle_held ; hold in to toggle light goto main_jump |
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:58 2004