; file: masterSolarController.asm ; ; This program controls the lighting of Democracity, ; activating various parts for day or nighttime. ; ; It includes a time-delay sort of behavior, so that ; it cannot change on and off too fast, and is tolerant ; of brief flickers and shadows. ; ; Actually, it's a general purpose sensor-stabilizer. ; input 3 affects the four outputs gp1, gp2, gp4, gp5, ; where gp1 activates the fastest, and gp5 the most liesurely. ; ; gp 0 blinks with a low duty cycle, signaling alive-ness, and ; sensor state. ; ; poly@omino.com, 2008 August ; INCLUDE "P12F509.INC" INCLUDE "macross12f509.inc" ; config __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_ON & _IntRC_OSC ; available file registers 0x7-0x1f (25 registers) ; (there are more at 0x30-0x3f but only by ; FSR indirect addressing.) CBLOCK 0x07 sleep0,sleep1 ; for the sleep delay timer ticks ; counter for always blinking active light ticksDel; bits which changed this tick. t0 ; counter for fastest output t1 ; counter for slower-responding output t2 t3 ; counter for slowest responding output (about 60 sec) thisGpio prevGpio rnd ENDC CBLOCK 0x30 cblock30End ; keep this last ENDC IF cblock30End > 0x40 ERROR "CBLOCK30 exceeded" ENDIF OUTSOFFVALUE EQU 0x37 ; to invert some of the outputs OUTSMASK EQU 0x37 ORG 0 ; lets begin GOTO Start ResetCounter MACRO counter ; slam a counter down to 0 or up to ff... MOVLW 0xff IFBC counter,7 MOVLW 0 MOVWF counter ENDM INCPINF_IF_BIT MACRO reg,ifreg,ifbit LOCAL _x IFBC ifreg,ifbit GOTO _x INCPINF reg _x: ENDM DECPINF_IF_BIT MACRO reg,ifreg,ifbit LOCAL _x IFBC ifreg,ifbit GOTO _x DECPINF reg _x: ENDM Start: ; All five outputs to "out" ; GPIO 3 can only be "in", with pullup pls. MOVLW 0 TRIS GPIO MOVLW b'10011111' ; OPTION MOVLF OUTSOFFVALUE,GPIO ; all "off" CLRF ticks ; all outputs off to start CLRF t0 CLRF t1 CLRF t2 CLRF t3 MainLoop: CLRWDT INCF ticks,w XORWF ticks,w MOVWF ticksDel INCF ticks,f MOVFF GPIO,thisGpio XORWF prevGpio,f IFBC prevGpio,3 GOTO _m0 ; gpio bit 3 changed. slam the current values to whichever ; side each was on. ; this means whenever the light changes, the ; counting has to "start over again", be it high ; or low. Means it can't change faster than a half-sweep ; (since the relay activates at 0x80). ResetCounter t0 ResetCounter t1 ResetCounter t2 ResetCounter t3 _m0: MOVFF thisGpio,prevGpio IFBS thisGpio,3 ; dark = 1-bit. GOTO _mDark ; it is light... migrate towards "off". DECPINF_IF_BIT t0,ticksDel,1 DECPINF_IF_BIT t1,ticksDel,2 DECPINF_IF_BIT t2,ticksDel,3 DECPINF_IF_BIT t3,ticksDel,4 GOTO _m1 _mDark: ; it is dark... migrate towards "on" ; set dest for all outputss INCPINF_IF_BIT t0,ticksDel,1 INCPINF_IF_BIT t1,ticksDel,2 INCPINF_IF_BIT t2,ticksDel,3 INCPINF_IF_BIT t3,ticksDel,4 _m1: ; load up gpio ; gp0: just the blinker, which is 1/16 for light, ; and 2/16 for dark MOVLW 0 IFBS ticks,0 GOTO _m2 IFBS ticks,1 GOTO _m2 IFBS ticks,2 GOTO _m2 IFBS ticks,3 GOTO _m2 IFBS thisGpio,3 GOTO _lit ; extra blinks if sensor on. IFBS ticks,4 GOTO _m2 IFBS ticks,5 GOTO _m2 _lit: MOVLW 1 _m2: ; gp1,2,4,5 <- t0,t1,t2,t3 IFBS t0,7 XORLW 1<<1 IFBS t1,7 XORLW 1<<2 IFBS t2,7 XORLW 1<<4 IFBS t3,7 XORLW 1<<5 XORLW OUTSOFFVALUE MOVWF GPIO ; TODO: Sleep 0.06 seconds. MOVLF 0,sleep0 MOVLF 10,sleep1 _sleep: DECFSZ sleep0,f GOTO _sleep DECFSZ sleep1,f GOTO _sleep GOTO MainLoop END