; Program ALARMSRC.ASM
;
; PIC program for vibration 446 bike alarm
;
; (c)2003 Tim Dunne
; Version 1.3
; * shorten rangecheck pulse to avoid popping on pager radio
; (added DELAY_MS to wait for no. of mS in W)
;
; Version 1.2
; * press call twice on alarm due to short call tone
; on 'C' radio module
; * timings adjusted for luggage loop alarm also
; * insert delay going into alarm to remove key rollover bug
;
; Version 1.1
; * add luggage loop detection
; * decrease rangecheck to 5 seconds
; aseembler directives
LIST p=16f84
#include <p16f84.inc>
__CONFIG 3FF1H
CONSTANT BASE_VAR=0CH
; variable declarations
LOOP1 EQU BASE_VAR+0
LOOP2 EQU BASE_VAR+1
W_SAVE EQU BASE_VAR+2
STATUS_SAVE EQU BASE_VAR+3
QSECS EQU BASE_VAR+4
COUNTER_SV EQU BASE_VAR+5
LOOP1_SV EQU BASE_VAR+6
LOOP2_SV EQU BASE_VAR+7
QSECS_SV EQU BASE_VAR+8
LOOP1_MS EQU BASE_VAR+9
LOOP2_MS EQU BASE_VAR+10
LOOP1_MS_SV EQU BASE_VAR+11
LOOP2_MS_SV EQU BASE_VAR+12
; program setup
ORG 000H
GOTO MAIN ; main program vector
ORG 004H
GOTO INT_SERV ; interrupt vector
MAIN:
BSF STATUS, RP0 ; select register bank 1
MOVLW B'00000000'
MOVWF TRISA ; set all port a bits to outputs
MOVLW B'00010001'
MOVWF TRISB ; set port b bits RB0 and RB4 to inputs,
; all others outputs
BCF STATUS, RP0 ; select register bank 0
MOVLW B'00011100'
MOVWF PORTA ; set radio control lines high
; and led lines low
MOVLW B'11101110'
MOVWF PORTB ; set unused outputs on port b high
BSF PORTA,0
BSF PORTA,1 ; turn on both leds for orange
MOVLW D'8'
CALL QUARTER ; wait 2 seconds for radio to settle
BCF PORTA,2 ; press power button
MOVLW D'12'
CALL QUARTER ; wait 3 seconds for radio to turn on
BCF PORTA,0
BCF PORTA,1 ; turn off both leds
BSF PORTA,2 ; release POWER button
BSF STATUS, RP0 ; select register bank 1
BSF OPTION_REG, INTEDG ; interupt on positive
BCF STATUS, RP0 ; select register bank 0
BCF INTCON, INTF ; clear interrupt flag
BCF INTCON, RBIF
BSF INTCON, INTE ; enable RB0 interrupts
BSF INTCON, RBIE ; enable RB4-RB7 change interrupt
BSF INTCON, GIE ; enable interrupts
MOVLW D'4'
CALL QUARTER ; 1 second delay before rangecheck
RANGECHECK:
BSF PORTA,1 ; turn on red led
BCF PORTA,3 ; press PTT button
MOVLW D'150'
CALL DELAY_MS ; broadcast for 150mS
BCF PORTA,1 ; turn off red led
BSF PORTA,3 ; release PTT button
MOVLW D'20'
CALL QUARTER ; wait 5 seconds
GOTO RANGECHECK ; go back and do it again
; End of Main
DELAY_250: ; 250 msec delay
MOVLW D'250'
MOVWF LOOP2
DELAY_1:
MOVLW D'110'
MOVWF LOOP1
INNER:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ LOOP1, F
GOTO INNER
DECFSZ LOOP2, F
GOTO DELAY_1
RETURN
DELAY_MS: ; miliseconds delay
MOVWF LOOP2_MS
DELAY1_MS:
MOVLW D'110'
MOVWF LOOP1_MS
INNER_MS:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DECFSZ LOOP1_MS, F
GOTO INNER_MS
DECFSZ LOOP2_MS, F
GOTO DELAY1_MS
RETURN
QUARTER: ; pause for period in W in
; .25 second resolution
MOVWF QSECS
QLOOP:
CALL DELAY_250 ; wait for 250 miliseconds
DECFSZ QSECS,F ; decrement counter
GOTO QLOOP ; loop again if result not zero
RETURN
INT_SERV: ; interrupt service routine
MOVWF W_SAVE ; save W
SWAPF STATUS, W ; save STATUS
MOVWF STATUS_SAVE
BCF STATUS, RP0 ; be sure we are in bank 0
MOVFW LOOP1
MOVWF LOOP1_SV
MOVFW LOOP2
MOVWF LOOP2_SV
MOVFW QSECS
MOVWF QSECS_SV
MOVFW LOOP1_MS
MOVWF LOOP1_MS_SV
MOVFW LOOP2_MS
MOVWF LOOP2_MS_SV ; save current state of variables
BTFSS INTCON, RBIF ; is this the luggage loop interrupt?
GOTO VIBEALARM ; no? must be vibration
BTFSC PORTB, 4 ; has the loop been broken?
GOTO CLEAR_RBINTF ; if not, clear interrupt and return
BCF PORTA,1 ; turn off red led
BSF PORTA,0 ; turn on green led
BSF PORTA,3 ; ensure PTT is not pressed
MOVLW D'4'
CALL QUARTER ; defeat key rollover
LUGGAGEALARM:
BCF PORTA,4 ; press call button
MOVLW D'6'
CALL QUARTER ; wait 1.5 seconds
BSF PORTA,4 ; release call button
MOVLW D'16'
CALL QUARTER ; wait for 4 seconds
BTFSC PORTB,4 ; has loop been restored?
GOTO LUGGAGEALARM ; no? repeat alarm
BCF PORTA,0 ; turn off green led
CLEAR_RBINTF
MOVF PORTB, 1 ; clear portb mismatch
BCF INTCON, RBIF ; clear RB4-RB7 interrupt
GOTO ENDINT ; restore variables and return
VIBEALARM:
BCF PORTA,1 ; turn off red led
BSF PORTA,0 ; turn on green led
BSF PORTA,3 ; ensure PTT is not pressed
MOVLW D'4'
CALL QUARTER ; defeat key rollover
BCF PORTA,4 ; press call button
MOVLW D'6'
CALL QUARTER ; wait 1.5 seconds
BSF PORTA,4 ; release call button
MOVLW D'16'
CALL QUARTER ; wait for 4 seconds
BCF PORTA,4 ; press call button
MOVLW D'6'
CALL QUARTER ; wait 1.5 seconds
BSF PORTA,4 ; release call button
MOVLW D'18'
CALL QUARTER ; wait for 4.5 seconds
BCF PORTA,0 ; turn off green led
BCF INTCON, INTF ; indicate that interrupt has been
; serviced
ENDINT:
MOVFW LOOP1_SV
MOVWF LOOP1
MOVFW LOOP2_SV
MOVWF LOOP2
MOVFW QSECS_SV
MOVWF QSECS
MOVFW LOOP1_MS_SV
MOVWF LOOP1_MS
MOVFW LOOP2_MS_SV
MOVWF LOOP2_MS ; restore variables
SWAPF STATUS_SAVE, W
MOVWF STATUS ; restore W and STATUS
SWAPF W_SAVE, F
SWAPF W_SAVE, W
RETFIE
END