; file: buttontest.asm ; ; test input on gpio3. ; INCLUDE "P12F509.INC" INCLUDE "macross12f509.inc" ; available file registers 0x7-0x1f (25 registers) ; (there are more at 0x30-0x3f but only by ; FSR indirect addressing.) CBLOCK 0x07 rnd ; for randomizer count d0,d1,d2 ; for various timing and misc p0,p1,p2 ; pattern params bitsOut whichPattern led0:2 ; 1st: linear brightness, 2nd: running sum, 3rd: target brightness led0Target led1:2 led1Target led2:2 led2Target led3:2 led3Target led4:2 led4Target cblock07End ; keep this last ENDC IF cblock07End > 0x20 ERROR "CBLOCK07 exceeded" ENDIF ; MACROS ; Poke a random value into a file register ; mask is anded, and min is added ; RANDF x,31,10 to get 10..41 RANDF MACRO fregdst,mask,min CALL Rnd MOVFW rnd IF mask != 0xff ANDLW mask ENDIF MOVWF fregdst IF min != 0 MOVLW min ADDWF fregdst,f ENDIF ENDM ; Each 1-bit dac is maintained as 2 bytes: ; the brightness and the running-sum. ; (a third byte is sometimes the "target brightness") ; Rotate the current 1-bit dac on-offness ; into the right side of "dest". StepDac MACRO dacState,dest MOVFW dacState ADDWF dacState+1,F RLF dest,F ; put led in low bit ENDM LedsOff MACRO MOVLF 0xff,GPIO ; lights off while we rethink ENDM ; Check the button input and just bail on whatever's ; happening if the button is pressed. Note that we ; rely on jump table entries being present in both ; pages. CheckButton MACRO IFBC GPIO,3 ; button grounded = pressed GOTO GotoHandleButton ENDM ORG 0 ; lets begin ; we keep a matching jump table at 0x000 and 0x200, ; for certain key routines that we want to "just work" GOTOHILO Start GotoHandleButton: GOTOHILO HandleButton ; ---------------------------------- ; UTILITIES ; Delay 1 pip Delay: MOVLF 1,d2 ; Delay by d2 pips DelayD2: CLRF d0 CLRF d1 _delay: INCFSZ d0,f GOTO _delay CheckButton INCFSZ d1,f GOTO _delay DECFSZ d2,f GOTO _delay RETLW 0 ; Delay a pip *without* checking the button DelayNoButton: CLRF d0 MOVLF 0x60,d1 _delayNB: DECFSZ d0,f GOTO _delayNB DECFSZ d1,f GOTO _delayNB RETLW 0 DisplayCount: MOVFF count,bitsOut RLF bitsOut,w ANDLW 0x30 MOVWF bitsOut MOVFW count ANDLW 0x07 IORWF bitsOut,f COMF bitsOut,f MOVFF bitsOut,GPIO RETLW 0 RefreshLeds: ; advance each dac CLRF bitsOut StepDac led4,bitsOut StepDac led3,bitsOut ; just a zero for bit 3 BCF STATUS,C RLF bitsOut,f StepDac led2,bitsOut StepDac led1,bitsOut StepDac led0,bitsOut MOVFW bitsOut XORLW 0xFF ; invert for sink led MOVWF GPIO CLRWDT RETLW 0 ; move each LED to its target value, pausing ; d2 tween each step. ; do 256 steps to be sure. ; uses: d0, d1. GlideLeds256: ; glide LEDs all the way... CLRF d0 ; outer counter, make sure we do 256 altogether GlideLeds: ; glide LEDs by d0 steps _glideLedsLoop1: CALL RefreshLeds MIGFPIN led0,led0+2 CALL RefreshLeds MIGFPIN led1,led1+2 CALL RefreshLeds MIGFPIN led2,led2+2 CALL RefreshLeds MIGFPIN led3,led3+2 CALL RefreshLeds MIGFPIN led4,led4+2 ; now delay by d2 refreshes... CALL RefreshLeds ; refresh leds by d2 times. MOVFF d2,d1 ; 2 NOPS 6 _glideLedsLoop: CheckButton CALL RefreshLeds NOPS 5 DECFSZ d1,f GOTO _glideLedsLoop NOP CALL RefreshLeds NOPS 5 DECFSZ d0,f GOTO _glideLedsLoop1 RETLW 0 ; load up bits 0..4 of count to the target ; brightnesses of the LEDs. CountToTarget: CLRF led0Target CLRF led1Target CLRF led2Target CLRF led3Target CLRF led4Target MOVLW 0xff IFBS count,0 MOVWF led0Target IFBS count,1 MOVWF led1Target IFBS count,2 MOVWF led2Target IFBS count,3 MOVWF led3Target IFBS count,4 MOVWF led4Target RETLW 0 ; load up bits 0..4 of count to the current ; brightnesses of the LEDs. CountToBrighness: CLRF led0 CLRF led1 CLRF led2 CLRF led3 CLRF led4 MOVLW 0xff IFBS count,0 MOVWF led0 IFBS count,1 MOVWF led1 IFBS count,2 MOVWF led2 IFBS count,3 MOVWF led3 IFBS count,4 MOVWF led4 RETLW 0 ; ; Put a (very psuedo) random number into ; the 'rnd' file register. Rnd: MOVFW rnd ADDWF TMR0,w RLF rnd,f RLF rnd,f ADDWF rnd,f RETLW 0 ; ---------------------------------- ; MAIN Start: ;CALL delay ; All five outputs to "out" ; GPIO 3 can only be "in" MOVLW b'00001000' TRIS GPIO MOVLW b'00011111' ; OPTION IFBS STATUS,GPWUF GOTO pastInit ; these inits done only the first time CLRF whichPattern pastInit: switchToPattern: CheckButton CLRF count PATTERN_COUNT EQU 5 ; switch statement for whichPattern MOVFF whichPattern,d0 ; hijack d0 INCF d0,f DECF d0,f IFZ GOTO GotoP1 DECF d0,f IFZ GOTO GotoP2 DECF d0,f IFZ GOTO GotoP3 DECF d0,f IFZ GOTO GotoP4 DECF d0,f IFZ GOTO GotoP5 GOTO GotoP5 GotoP1: GOTOHILO Pattern1 GotoP2: GOTOHILO Pattern2 GotoP3: GOTOHILO Pattern3 GotoP4: GOTOHILO Pattern4 GotoP5: GOTOHILO Pattern5 ; -------------------------------------------------- Pattern1: INCF count,f CALL DisplayCount CALL Delay GOTO Pattern1 ; one-hot, fading out ; p0: time to choose no rates, &c ; p1: how much fading to do ; p2: how much to step Pattern2: CLRF led0Target CLRF led1Target CLRF led2Target CLRF led3Target CLRF led4Target MOVLF 0,count _pattern2Setup ; glide-time (higher is slower) RANDF d2,0x3f,0x20 ; 0x20..0x60 ; MOVLF 0x40,d2 RANDF p1,0x7f,0x40 ; 0x40..0xc0, number of fadesteps RANDF p2,0x3,1 ; how much to bump each time ; MOVLF 11,p0 ; do this many before new setup RANDF p0,0x1f,11 ; change pattern after this many _pattern2: ; set led[count] brightness to ff, vi IFS MOVLW led0 ADDWF count,w ADDWF count,w ADDWF count,w MOVWF FSR MOVLF 0xff,INDF ;MOVLF 0x90,d0 MOVFF p1,d0 CALL GlideLeds LedsOff ; bump count wrap at 5 MOVFF p2,d0 _pattern2BumpCount INCF count MOVFW count XORLW 5 IFZ CLRF count DECFSZ d0 GOTO _pattern2BumpCount ; time for new everythings? DECFSZ p0 GOTO _pattern2 ; reset params! GOTO _pattern2Setup Pattern3: MOVLF 1,count _pattern3: CALL DisplayCount CALL Delay CALL Delay BCF STATUS,C BTFSC count,4 BSF STATUS,C RLF count,f GOTO _pattern3 ; fading binary step ; p0 step value, an odd number ; p1 time ; p2 how far fade gets Pattern4: CALL Rnd MOVFW rnd IORLW 1 MOVWF p0 RANDF p1,0x7f,10 RANDF p2,0x7f,0x70 _pattern4: CLRF led0Target CLRF led1Target CLRF led2Target CLRF led3Target CLRF led4Target MOVLW 0xff IFBS count,0 MOVWF led0Target IFBS count,1 MOVWF led1Target IFBS count,2 MOVWF led2Target IFBS count,3 MOVWF led3Target IFBS count,4 MOVWF led4Target MOVFF p1,d2 MOVFF p2,d0 CALL GlideLeds MOVFW count ADDWF p0,w ANDLW 0x1f MOVWF count IFNZ GOTO _pattern4 GOTO Pattern4 ; setup again Pattern5: ; SLEEP! or "off"ish ; danger... hopefully upon waking we'd get here, and ; increment past the sleeping pattern. ohoh. CheckButton LedsOff; lights off please. SLEEP ; ----------------------------- ; Button Checking ;CheckButton: ; BTFSC GPIO,3 ; normally high ; RETLW 0 ; button is pressed... ; increment whichPattern, and show it as 1..n lit up HandleButton: INCF whichPattern,f MOVFW whichPattern XORLW PATTERN_COUNT IFZ CLRF whichPattern ; show it... MOVFF whichPattern,d0 INCF d0,f CLRF count _showWhichPattern BSF STATUS,C RLF count,f DECFSZ d0,f GOTO _showWhichPattern CALL DisplayCount ; debounce by waiting, then awaiting button-up CALL DelayNoButton _buttonStillDown: ;while button down, flash 1..n for whichPattern INCF d0,f IFZ INCF d1,f MOVFW bitsOut IFBS d1,5 MOVLW 0xff MOVWF GPIO IFBC GPIO,3 GOTO _buttonStillDown ; button released, delay to debounce CALL DelayNoButton ; and selected. GOTO switchToPattern ORG 0x200 GOTOHILO Start GOTOHILO HandleButton CheckButton END NDF patternTime,0x7f,0x40 RANDF patternCount,0x7,1 _p3loop: CLRF led0+2 CLRF led1+2 CLRF led2+2 CLRF led4+2 CLRF led5+2 MOVLF 0xff,led0+2 CALL GlideLeds MOVLF 0xff,led1+2 CALL GlideLeds MOVLF 0xff,led2+2 CALL GlideLeds MOVLF 0xff,led4+2 CALL GlideLeds MOVLF 0xff,led5+2 CALL GlideLeds CALL FadeoutLeds CALL FadeoutLeds ; make count faster each time BCF STATUS,C RRF patternTime,f INCF patternTime,f DECFSZ patternCount,f GOTO _p3loop Pattern4: ; various groups on RANDF patternTime,0x3f,0x80 RANDF patternCount,0x7,13 _p4loop: ; set each led to 0 or 80 RANDF led0+2,0x80,0 RANDF led1+2,0x80,0 RANDF led2+2,0x80,0 RANDF led4+2,0x80,0 RANDF led5+2,0x80,0 CALL GlideLeds CALL FadeoutLeds DECFSZ patternCount,f GOTO _p4loop ; now, we wait for the Watch Dog Timer ; to fire. since its on a separatre clock, ; it lets the timer advance a very random ; amount, increasing our diversity. WaitUntilTimeout: GOTO WaitUntilTimeout GOTO PatternsStart ; ----------------------------- ; High Code ; Code up here in needs to track STATUS:PA0 for ; the 9th bit of the address on GOTO or CALL. We ; keep it set while up here. We clear it to GOTO ; a low address, and temporarily clear it to ; CALL a low address ; ORG 0x200 Pattern7High: MOVLF 0xf0,led0 MOVLF 0x80,led1 MOVLF 0x40,led2 MOVLF 0x20,led4 MOVLF 0x10,led5 CALLLO FadeoutLeds GOTOHILO _p7b END ; EOF CLRF led4+2 CLRF led5+2 MOVLF 0xff,led0+2 CALL GlideLeds MOVLF 0xff,led1+2 CALL GlideLeds MOVLF 0xff,led2+2 CALL GlideLeds MOVLF 0xff,led4+2 CALL GlideLeds MOVLF 0xff,led5+2 CALL GlideLeds CALL FadeoutLeds CALL FadeoutLeds ; make count faster each time BCF STATUS,C RRF patternTime,f INCF patternTime,f DECFSZ patternCount,f GOTO _p3loop Pattern4: ; various groups on RANDF patternTime,0x3f,0x80 RANDF patternCount,0x7,13 _p4loop: ; set each led to 0 or 80 RANDF led0+2,0x80,0 RANDF led1+2,0x80,0 RANDF led2+2,0x80,0 RANDF led4+2,0x80,0 RANDF led5+2,0x80,0 CALL GlideLeds CALL FadeoutLeds DECFSZ patternCount,f GOTO _p4loop ; now, we wait for the Watch Dog Timer ; to fire. since its on a separatre clock, ; it lets the timer advance a very random ; amount, increasing our diversity. WaitUntilTimeout: GOTO WaitUntilTimeout GOTO PatternsStart END ; EOF s ; ORG 0x200 Pattern7High: MOVLF 0xf0,led0 MOVLF 0x80,led1 MOVLF 0x40,led2 MOVLF 0x20,led4 MOVLF 0x10,led5 CALLLO FadeoutLeds GOTOHILO _p7b END ; EOF CLRF led4+2 CLRF led5+2 MOVLF 0xff,led0+2 CALL GlideLeds MOVLF 0xff,led1+2 CALL GlideLeds MOVLF 0xff,led2+2 CALL GlideLeds MOVLF 0xff,led4+2 CALL GlideLeds MOVLF 0xff,led5+2 CALL GlideLeds CALL FadeoutLeds CALL FadeoutLeds ; make count faster each time BCF STATUS,C RRF patternTime,f INCF patternTime,f DECFSZ patternCount,f GOTO _p3loop Pattern4: ; various groups on RANDF patternTime,0x3f,0x80 RANDF patternCount,0x7,13 _p4loop: ; set each led to 0 or 80 RANDF led0+2,0x80,0 RANDF led1+2,0x80,0 RANDF led2+2,0x80,0 RANDF led4+2,0x80,0 RANDF led5+2,0x80,0 CALL GlideLeds CALL FadeoutLeds DECFSZ patternCount,f GOTO _p4loop ; now, we wait for the Watch Dog Timer ; to fire. since its on a separatre clock, ; it lets the timer advance a very random ; amount, increasing our diversity. WaitUntilTimeout: GOTO WaitUntilTimeout GOTO PatternsStart END ; EOF