;#define eprom ;*** For prototype only - comment out for production *** #define clock_trim 0x70 ;*** clock trim for EPROM chip tailor to suit *** ;*** NOTE: READ THIS VALUE VBEFORE ERASING THE CHIP!! *** ;********************************************************************* ;** pic12c509 based radio control failsafe detector ** ;** (c) copyright 1998 A.D. Kerr all rights reserved ** ;********************************************************************* list p=12c508 #include "p12c508.inc" __config 0x1A ;0000 1110 mclr enabled, cp off, wdt dis, osc intrc ;------------------------- equates ------------------------- ;***** Constants ***** duration equ .10 ;beep duration in chirps chirp_length equ .15 ;no of periods in a chirp hwc_period equ .25 ;output wave cycle period {(n)x20us} outer_time equ .100 ;timeout count inner_time equ .255 ;adjust for 1ms options equ 0x8F ;10001111 ;***** Registers ***** flags equ 0x10 ;flag register, see below for details duration_timer equ 0x11 ;beep duration timer half_cycle_timer equ 0x12 ;half wave period timer chirp_timer equ 0x13 ;10ms chirp wave counter outimer equ 0x14 ;outer loop timer intimer equ 0x15 ;inner loop timer half_cycle equ 0x16 ;wave period variable ;********** bits within registers ********** ;*** flag register pointers - use with bsf, bcf, btfsc and btfss *** pflag1 equ 0x00 ;port 1 flag - indicates that port 1 has gone HI ;***** i/o register ***** ;---------------------------------------------------------------- ;12c509 pin assignments: pin 2 ch1 in gp5 ; pin 3 N/A gp4 ; pin 4 N/A gp3 ; pin 5 N/A gp2 ; pin 6 output2 gp1 ; pin 7 output1 gp0 ;---------------------------------------------------------------- ch1 equ 0x05 ; pin 2, gp5, input output1 equ 0x04 ; pin 7, gp0, output output2 equ 0x01 ; pin 6, gp1, output iostat equ 0x2C ; 0011 1100 i/o direction bits 1=input ;********************************************************************** ;* reset routine * ;********************************************************************** reset org 0x000 movwf 0x05 ;set oscillator trim nop goto start ;put code above 0x40 to hide it start org 0x040 movlw 0x00 ;clear GPIO first of all movwf GPIO movlw iostat ;setup GPIO pins tris GPIO clrwdt ;clear WDT ... clrf TMR0 ;and timer0 just in case movlw options ;everything disabled! option ;set options clrf flags ;clear flag register goto oops ;beep once at startup ;**************************************************************** ;* MAIN ROUTINES START HERE * ;**************************************************************** ;**************************************************************** ;* Does the patient have a pulse, doctor? Clear the WDT, * ;* then wait for an input pulse * ;**************************************************************** checkpulse bcf flags, pflag1 ;clear port 1 flag for use movlw outer_time ; movwf outimer ;clear outer loop timer movlw inner_time ; movwf intimer ;clear inner loop timer checkport1 btfss GPIO, ch1 ;channel 1 high? goto portlow ;no, continue bsf flags, pflag1 ;yes, set port 1 flag decfsz intimer, 1 ;decrement inner loop timer goto checkport1 ;inner loop still running, continue movlw inner_time ;inner loop expired, reset movwf intimer ;reset inner timer decfsz outimer, 1 ;decrement outer loop timer goto checkport1 ;outer loop still running, continue goto oops ;both timers have expired, oops! portlow ;Channel 1 is LOW decfsz intimer, 1 ;decrement inner loop timer goto checkflag ;inner loop timer still running, check flag movlw inner_time ;inner loop expired, reset to &FF movwf intimer ;reset inner timer decfsz outimer, 1 ;decrement outer loop timer goto checkflag ;outer timer still running, check flag goto oops ;both timers have expired, OOPS! checkflag ;channel 1 is low, check if it has been high btfss flags, pflag1 ;was channel1 high? goto checkport1 ;no, keep looking portdetect ;pulse detected on channel 1 bcf flags, pflag1 ;Clear port 1 flag movlw outer_time movwf outimer ;reset outer timer movlw inner_time movwf intimer ;reset inner timer goto checkport1 ;look for the next pulse ;************************************************************************ ;* * ;* Output sound routine. This routine is called every time the * ;* WDT goes off. * ;* * ;* Variables used - * ;* * ;* duration_timer - Remaining chirps in this beep * ;* chirp_timer - Remaining cycles in the current chirp * ;* half_cycle_timer - Remaining 10us delays in the current half cycle* ;* * ;* Constants used - * ;* * ;* duration - Sets the duration of the beep in chirps * ;* chirp_length - Sets the length of a chirp in cycles * ;* hwc_period - Sets the duration of an output half cycle * ;************************************************************************ oops ;WDT went off - no I/P signal! movlw duration ;get the beep duration - 1/2 second or so? movwf duration_timer ;put it in the duration timer movlw hwc_period ; movwf half_cycle ;initialise O/P frequency variable beep movlw chirp_length ;get no cycles/chirp movwf chirp_timer ;put in chirp cycle counter cycle ;*** first half cycle *** movf half_cycle,0 ;get the ouput half wave cycle period movwf half_cycle_timer ;put it in half wave cycle timer bsf GPIO, output1 ;set output1 high bcf GPIO, output2 ;set output2 low half_cycle_1 ;delays x 10us nop nop nop nop nop nop nop decfsz half_cycle_timer, 1 goto half_cycle_1 ;*** now do the second half cycle *** movf half_cycle, 0 ;get the ouput half wave cycle period movwf half_cycle_timer ;put it in hwc timer bcf GPIO, output1 ;set output1 low again bsf GPIO, output2 ;and output2 high half_cycle_2 ;delays x 10us nop nop nop nop nop nop nop decfsz half_cycle_timer, 1 goto half_cycle_2 decfsz chirp_timer,1 ;done all cycles? goto cycle ;no, do another cycle tp1 decfsz duration_timer,1 ;beep finished? goto change_tone goto finish change_tone ;decf half_cycle, 1 ;decrease cycle period nop goto beep ;no, go do another chirp ;*** Beep finished, turn O/P's off finish bcf GPIO, output1 ;set both output pins low bcf GPIO, output2 goto checkpulse ;O.K, go check input ;* the bit below is for use with the EPROM development chip ifdef eprom org 0x3ff movlw clock_trim endif end