;************************************************************************** ; FILE: shooter.asm * ; CONTENTS: "Sharpshooter" * ; COPYRIGHT: MadLab Ltd. 1999-2003 * ; AUTHOR: James Hutchby * ; UPDATED: 22/10/03 * ;************************************************************************** list p=12C508A include "p12c508a.inc" __config _IntRC_OSC & _WDT_ON & _MCLRE_OFF & _CP_ON __idlocs h'BF11' errorlevel -305 ;************************************************************************** ; * ; Specification * ; * ;************************************************************************** ; gun: ; power-up self-test - double beep sounds ; IR burst transmitted and sfx when pushbutton pressed ; target: ; power-up self-test - all LEDs flash twice and double beep sounds ; sound and/or light cue after random time (both cues for first 3 bullseyes) ; 4 LEDs in compass pattern indicate hits on target ; 2 or more hits = bullseye, increasing with number of bullseyes to 4 hits ; time limit to hits ; single long beep if times out and at least one bullseye ; time limit reduces with number of bullseyes ; after 10 bullseyes single LED on means hit indicated LED, ; failure if opposite LED hit ;************************************************************************** ; * ; Port assignments * ; * ;************************************************************************** #define DIFF GPIO,0 ; differentiator (pulled low on target) GUN_IO equ b'001001' ; gun I/O status BUTTON equ 3 ; pushbutton - gun SPEAKER1 equ 0 ; speaker - gun IR_MASK equ b'110110' ; IR transmitters mask - gun IR1 equ 4 ; IR transmitter #1 (left) IR2 equ 2 ; IR transmitter #2 (right) IR3 equ 5 ; IR transmitter #3 (upper) IR4 equ 1 ; IR transmitter #4 (lower) TARGET_IO equ b'101000' ; target I/O status SENSOR equ 3 ; IR sensor - target SPEAKER2 equ 5 ; speaker - target LED_MASK equ b'010111' ; LEDs mask - target LED1 equ 1 ; LED #1 (left) LED2 equ 4 ; LED #2 (right) LED3 equ 2 ; LED #3 (upper) LED4 equ 0 ; LED #4 (lower) ;************************************************************************** ; * ; Constants and timings * ; * ;************************************************************************** CLOCK equ d'4000000' ; processor clock frequency in Hz ENABLE_WPS equ b'10000000' ; weak pull-ups enabled DISABLE_WPS equ b'11000000' ; weak pull-ups disabled POLL_DELAY equ d'20' ; button poll delay in ms BEEP_PITCH equ d'30' ; beep pitch BEEP_PERIOD equ d'150' ; beep period BEEP_FAIL equ d'25' ; failure beep BIT_PERIOD equ d'50' ; bit period in us PULSE_GAP equ d'20' ; pulse gap in ms RX_TIMEOUT equ d'100' ; receive timeout in ms TRIGGER_MIN equ d'5' ; trigger delay minimum TRIGGER_MASK equ d'31' ; trigger delay mask HIT_TIMEOUT equ d'45' ; hit timeout in 1/10 s MIN_TIMEOUT equ d'9' ; minimum timeout in 1/10 s SFX_HI equ d'5' ; sfx ramp high frequency SFX_LO equ d'80' ; sfx ramp low frequency SFX_RISE equ d'250' ; sfx ramp rise time FLASH_DELAY equ d'10' ; LED flash delay in 1/100 s ;************************************************************************** ; * ; File register usage * ; * ;************************************************************************** cblock h'07' flags ; pulse code flags unit ; unit - 0 = gun, 1 = target pcode ; pulse code (0 to 3) leds ; LED state bulls ; number of bullseyes repeat ; repeat counter timeout ; timeout counter hit_mask ; hit mask miss_mask ; miss mask rand_l, rand_h ; random number count1, count2 ; scratch counters timer_h, timer_l ; timer work1, work2 ; work registers endc CODE1 equ LED1 ; pulse code 1 received CODE2 equ LED2 ; pulse code 2 received CODE3 equ LED3 ; pulse code 3 received CODE4 equ LED4 ; pulse code 4 received ERR equ 7 ; receive error BULLSEYE equ (1< 0 nop ; [4] i set i-4 endw endm movfw pcode index tx_table movwf work1 rrf pcode,w ; calculate check bit xorwf pcode,w andlw 1 skpz bsf pcode,2 tx_on ; transmit start bit tx_wait d'20' btfss pcode,0 ; transmit code bits goto tx1 nop tx_on goto tx2 tx1 tx_off goto tx2 tx2 tx_wait d'28' btfss pcode,1 ; [8/4] goto tx3 ; [0/8] nop ; [4/0] tx_on ; [8/0] goto tx4 ; [8/0] tx3 tx_off ; [0/8] goto tx4 ; [0/8] tx4 tx_wait d'28' btfss pcode,2 ; transmit check bit goto tx5 nop tx_on goto tx6 tx5 tx_off goto tx6 tx6 tx_wait d'16' tx_on ; transmit stop bit tx_wait d'8' tx_off bcf pcode,2 retlw 0 ;-------------------------------------------------------------------------- ; transmits a burst ;-------------------------------------------------------------------------- tx_burst macro movlf d'4',repeat tx7 clrf pcode tx8 call tx_pulse movlw PULSE_GAP call delay incf pcode btfss pcode,2 goto tx8 decfsz repeat goto tx7 endm ;-------------------------------------------------------------------------- ; receives a pulse, returns Z flag set if timeout or C flag set if error ;-------------------------------------------------------------------------- routine rx_pulse rx_wait macro us local wait1 CYCLES set (CLOCK/d'1000000')*(us)-d'8' movlf CYCLES/d'12',count1 ; [8] wait1 decfsz count1 ; [4] goto wait1 ; [8] clrwdt ; [4] variable i = CYCLES%d'12' while i > 0 nop ; [4] i set i-4 endw endm bcf flags,ERR TIMEOUT set ((CLOCK/d'1000')*RX_TIMEOUT)/(d'24'*d'256')+1 movlf TIMEOUT,timer_h clrf timer_l bsf GPIO,SENSOR ; wait for low rx1 clrwdt ; [4] btfss GPIO,SENSOR ; [8] goto rx2 decfsz timer_l ; [4] goto rx1 ; [8] decfsz timer_h goto rx1 goto rx4 ; timeout PERIOD set BIT_PERIOD/2-(d'24'/(CLOCK/d'1000000')) rx2 bsf GPIO,SENSOR ; test start bit rx_wait PERIOD btfsc GPIO,SENSOR bsf flags,ERR PERIOD set BIT_PERIOD-(d'32'/(CLOCK/d'1000000')) movlf d'5',count2 ; receive code, check and stop bits rx3 rx_wait PERIOD bsf GPIO,SENSOR ; [4] clrc ; [4] btfss GPIO,SENSOR ; [4] setc ; [4] rrf pcode ; [4] decfsz count2 ; [4] goto rx3 ; [8] rrf pcode rrf pcode rrf pcode btfss pcode,3 ; test stop bit bsf flags,ERR btfsc pcode,4 ; test gap bsf flags,ERR rrf pcode,w ; test check bit xorwf pcode,w andlw 1 movlw 1<<2 skpz xorwf pcode btfsc pcode,2 bsf flags,ERR movlw b'11' andwf pcode clrz goto rx5 rx4 setz ; signal timeout rx5 clrc ; return error status btfsc flags,ERR setc retlw 0 ;-------------------------------------------------------------------------- ; gun sound fx ;-------------------------------------------------------------------------- gun_sfx macro movlf d'2',repeat sfx1 movlf SFX_HI,count1 sfx2 movlf SFX_RISE,work1 sfx3 bcf GPIO,SPEAKER1 ; speaker on movlw GUN_IO&~(1<