;*************************************************************************** ; lights.asm Scale LED Lighting System ;*************************************************************************** ; Bruce Abbott bhabbott@paradise.net.nz ; ; for Microchip PIC 12C508, 12C509, 12F629 or 12F675. ; ;============================= Description ================================= ; ; ============================================================================= ; Summary of Changes ; ; 2005/03/15 V0.0 - Created from RXDecode.asm ; 2005/03/19 V0.1 - Reduced strobe flash time ; 2005/05/20 V0.2 - Changed strobe flash sequence again! ; ; ----------------------------------------------------------------------------- #DEFINE TIME 4 ; number of servo pulses per strobe state #DEFINE version "0.2" ;#DEFINE __12C508 ; enable if processor not specified elsewhere ;#DEFINE __12F675 ; MPLAB users should use menu ;#DEFINE NO_OSCCAL ; enable if OSCCAL value was erased! ifdef __12C508 PROCESSOR PIC12C508 INCLUDE __CONFIG _MCLRE_OFF&_CP_OFF&_WDT_ON&_IntRC_OSC else PROCESSOR PIC12F675 INCLUDE __CONFIG _MCLRE_OFF&_CP_OFF&_WDT_ON&_BODEN_ON&_INTRC_OSC_NOCLKOUT endif radix dec errorlevel 0,-305,-302 ; Bit definitions for the GPIO register and the TRIS register #DEFINE STRB1 0 ; pin 7 strobe light #1 (switched) WHITE #DEFINE STRB2 1 ; pin 6 strobe light #2 (not switched) RED #DEFINE NAV 2 ; pin 5 navigation lights (switched) RED/GREEN #DEFINE SERVO 3 ; pin 4 servo pulse input #DEFINE AUX1 4 ; pin 3 auxilary output 1 #DEFINE AUX2 5 ; pin 2 auxilary output 2 #DEFINE TrisBits (1<1 goto $+1 ; 2 clocks NO_OP_COUNT SET NO_OP_COUNT-2 ENDW IF NO_OP_COUNT nop ; 1 clock ENDIF ENDM ;=========================================================================== ; Macro to create offsets for variables in RAM ; ifdef __12C508 ByteAddr SET 7 else ByteAddr SET 32 ; user RAM starts here endif BYTE MACRO ByteName ByteName EQU ByteAddr ByteAddr SET ByteAddr+1 ENDM ; ========================================================================== ; RAM Variable Definitions ; BYTE Flags ; various boolean flags BYTE ServoCount ; servo pulse length. 1~255 = 0.01~2.55mS BYTE Timer ; delay timer for strobes BYTE Strobe1 ; strobe 1 sequencer BYTE Strobe2 ; strobe 2 sequencer BYTE Temp1 BYTE Temp2 ; flag values ; #DEFINE WATCH 0 ; Watchdog timeout #DEFINE STROBE1 1 ; strobe 1 is on #DEFINE STROBE2 2 ; strobe 2 is on #DEFINE SWITCH 4 ; switch is on (controlled by servo input) ;**************************************************************************** ; Code ; ORG 0 goto ColdStart ;-------------------------- version string ---------------------------------- org 8 ifdef __12C508 dt "RYANL508" endif ifdef __12F629 dt "RYANL629" endif ifdef __12F675 dt "RYANL675" endif dt "--V" dt version dt "--" ;============================================================================ ColdStart: bcf Flags,WATCH btfss STATUS,NOT_TO ; copy Watchdog timeout flag bsf Flags,WATCH ; get oscillator calibration value and use it to fine-tune clock frequency. ; 12C508/9 has value in W at startup, 12F629/75 gets it from RETLW at 0x3ff. ifdef __12C508 ifdef NO_OSCCAL movlw 0x90 ; replace with value for your PIC! endif movwf OSCCAL ; set oscillator calibration else bsf STATUS,RP0 ; register bank 1 (12F629/75) call 0x3ff ; get OSCCAL value movwf OSCCAL ; set oscillator calibration bcf STATUS, RP0 ; register bank 0 endif ; ========================================================================== ; Moves the prescaler from tmr0 to the watchdog without accidental resets. ; clrwdt clrf TMR0 movlw OptionBits | 7 option clrwdt movlw OptionBits option clrwdt ifdef __12C508 clrwdt clrf TMR0 movlw OptionBits | 7 option clrwdt movlw OptionBits option clrwdt else clrwdt clrf TMR0 bsf STATUS,RP0 ; register bank 1 (12F629/75) movlw OptionBits | 7 movwf OPTION_REG clrwdt movlw OptionBits movwf OPTION_REG bcf STATUS,RP0 ; register bank 0 clrwdt endif ;======================================================================== ; initialise I/O registers ifdef __12C508 clrf GPIO ; all outputs low movlw TrisBits TRIS GPIO ; set I/O pin directions else clrf GPIO ; all outputs low bsf STATUS,RP0 ; register bank 1 (12F629/75) movlw TrisBits movwf TRISIO ; set I/O pin directions ifdef ANSEL clrf ANSEL ; disable analog inputs (12F675) endif bcf STATUS,RP0 ; register bank 0 ifdef CMCON movlw b'00000111' movwf CMCON ; Comparator off endif endif ; CPU specific stuff done, now we can start the main program! goto Main SeqStrobe1: ifdef PCLATH clrf PCLATH endif movf Strobe1,w addwf PCL retlw b'00000001' retlw b'00000000' retlw b'00000001' retlw b'00000000' retlw b'00000001' retlw b'00000000' retlw b'00000001' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'10000000' SeqStrobe2: ifdef PCLATH clrf PCLATH endif movf Strobe2,w addwf PCL retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'00000001' retlw b'00000000' retlw b'00000001' retlw b'00000000' retlw b'00000001' retlw b'00000000' retlw b'00000000' retlw b'00000000' retlw b'10000000' ;------------------------------------------------------------------------------- ; Millisecond Delay Timer ;------------------------------------------------------------------------------- ; Input: W = number of milliseconds to wait (max 256mS) ; dx1k: movwf Temp1 _dx1k1: movlw (1000-5)/5 movwf Temp2 _dx1k2: clrwdt ; avoid watchdog timeout nop decfsz Temp2 ; wait 1mS goto _dx1k2 decfsz Temp1 goto _dx1k1 retlw 0 ;******************************************************************************* ; Main ;******************************************************************************* Main: btfsc Flags,WATCH ; did the watchdog timeout ? goto MainLoop ; oops! try to keep going ... clrf Flags ; clear all flags movlw 250 ; wait 500mS for power to stabilise call dx1k movlw 250 call dx1k movlw TIME movwf Timer clrf Strobe1 clrf Strobe2 MainLoop: clrwdt ; avoid watchdog timeout btfsc GPIO,SERVO ; wait for no servo pulse goto MainLoop waitpulse: clrwdt ; avoid watchdog timeout btfss GPIO,SERVO ; wait for start of servo pulse goto waitpulse clrf ServoCount measure: incf ServoCount ;1 count * 10uS skpnz ;2 goto ServoError ;3 >2.55mS ? clrwdt ; 4 avoid watchdog timeout NO_OP 3 ;5~7 btfsc GPIO,SERVO ;8 servo pulse finished ? goto measure ;9,10 no, continue measuring movlw 150 subwf ServoCount,w ; less than 1.5mS ? bcf Flags,SWITCH ; assume no skpc bsf Flags,SWITCH ; yes decfsz Timer goto MainLoop ; time for next change? movlw TIME movwf Timer call SeqStrobe1 ; get Strobe 1 state movwf Temp1 incf Strobe1 ; next state btfsc Temp1,7 ; end of sequence ? clrf Strobe1 ; restart sequence bcf Flags,STROBE1 btfsc Temp1,0 ; strobe 1 to be on ? bsf Flags,STROBE1 call SeqStrobe2 ; get Strobe2 state movwf Temp1 incf Strobe2 ; next state btfsc Temp1,7 ; end of sequence ? clrf Strobe2 ; restart sequence bcf Flags,STROBE2 btfsc Temp1,0 ; strobe 2 to be on ? bsf Flags,STROBE2 btfsc Flags,SWITCH ; switch on ? goto switch_on switch_off: bcf GPIO,NAV ; no, turn off NAV lights bcf GPIO,STRB1 ; turn of strobe 1 goto switch_done switch_on: bsf GPIO,NAV ; yes, turn on NAV lights btfss Flags,STROBE1 ; flash strobe 1 bcf GPIO,STRB1 btfsc Flags,STROBE1 bsf GPIO,STRB1 switch_done: btfss Flags,STROBE2 ; flash strobe 2 bcf GPIO,STRB2 btfsc Flags,STROBE2 bsf GPIO,STRB2 ServoError: done: goto MainLoop ;---------- Oscillator Calibration Subroutine (12F629/75 only) -------------- ifdef __12F675 org 0x3ff retlw 0x90 ; replace with oscal value for your PIC! endif END