;************************************************************************** ; FILE: mice.asm * ; CONTENTS: "You've got mice" * ; COPYRIGHT: MadLab Ltd. 2003 * ; AUTHOR: James Hutchby * ; UPDATED: 07/04/03 * ;************************************************************************** ; list p=12F629 list p=12C508A ifdef __12F629 #include "p12f629.inc" endif ifdef __12C508A #include "p12c508a.inc" endif ifdef __12F629 __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _PWRTE_ON & _BODEN_ON & _CP_OFF & _CPD_OFF ; __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _PWRTE_ON & _BODEN_ON & _CP_ON & _CPD_ON endif ifdef __12C508A ; __config _IntRC_OSC & _WDT_ON & _MCLRE_OFF & _CP_OFF __config _IntRC_OSC & _WDT_ON & _MCLRE_OFF & _CP_ON endif __idlocs h'DD10' errorlevel -207,-302,-305,-306 ;************************************************************************** ; * ; Specification * ; * ;************************************************************************** ; power-up self-test - double beep and motor runs briefly ; pushbutton cycles through modes (light, moderate, heavy infestation) ; 1 to 3 beeps indicates mode, initially mode 2 ; pushbutton held down for 2s toggles demo mode (long beep) ; mice activity (squeaks and feet/tail movement) triggered periodically ; frequency and level dependent on mode, semi-continuous in demo mode ; position on sheet of paper or in open cardboard box for maximum effect ; hide in inaccessible place (under bed, on top of wardrobe etc.) ;************************************************************************** ; * ; Port assignments * ; * ;************************************************************************** GPIO_IO equ b'101010' ; port I/O status MOTOR equ 0 ; motor BUTTON equ 1 ; pushbutton SPEAKER1 equ 2 ; speaker SPEAKER2 equ 4 ;************************************************************************** ; * ; Constants and timings * ; * ;************************************************************************** CLOCK equ d'4000000' ; processor clock frequency in Hz MOTOR_PERIOD equ d'4' ; motor duty cycle period in ms MAX_SPEED equ d'50' ; maximum motor speed BEEP_PITCH equ d'30' ; beep pitch BEEP_PERIOD equ d'200' ; beep period SQUEAK_PITCH equ d'18' ; squeak pitch SQUEAK_PERIOD equ d'175' ; squeak period SQUEAK_SPREAD equ h'3f' ; squeak spread ACTIVITY1 equ d'20' ; periods between ACTIVITY2 equ d'15' ; mice activity ACTIVITY3 equ d'10' ; in minutes ;************************************************************************** ; * ; File register usage * ; * ;************************************************************************** ifdef __12F629 RAM equ h'20' endif ifdef __12C508A RAM equ h'07' endif cblock RAM flags ; various flags mode ; mode, 0 to 2 duty ; motor duty cycle, 0 (off) to 100 (on) speed ; motor speed, 0 to 100 timer:2 ; timer ndx ; table index loop ; loop counter repeat ; repeat counter count:2 ; scratch counter rand_l, rand_h ; random number work1, work2 ; work registers endc ; flags POLL equ 0 ; set if pushbutton polled DEMO equ 1 ; set if demo mode ;************************************************************************** ; * ; Macros * ; * ;************************************************************************** routine macro label ; routine label endm table macro label ; define lookup table label addwf PCL endm entry macro value ; define table entry retlw value endm index macro label ; index lookup table call label endm jump macro label ; jump through table goto label endm tstw macro ; test w register iorlw 0 endm movff macro f1,f2 ; move file to file movfw f1 movwf f2 endm movlf macro n,f ; move literal to file movlw n movwf f endm tris_ macro t movlw t ifdef __12F629 bsf STATUS,RP0 movwf TRISIO bcf STATUS,RP0 endif ifdef __12C508A tris GPIO endif endm ;-------------------------------------------------------------------------- ; reset vector ;-------------------------------------------------------------------------- org 0 ifdef __12F629 bsf STATUS,RP0 call h'3ff' movwf OSCCAL bcf STATUS,RP0 endif ifdef __12C508A movwf OSCCAL endif goto main_entry ;************************************************************************** ; * ; Lookup tables * ; * ;************************************************************************** table moves_table range macro base,spread entry base entry spread endm ; repeat - period - wait - loop - wait range d'2',h'02' ; mode 1 range d'18',h'03' range d'12',h'0f' range d'2',h'03' range d'15',h'0f' range d'3',h'03' ; mode 2 range d'16',h'07' range d'12',h'0f' range d'3',h'03' range d'12',h'0f' range d'4',h'03' ; mode 3 range d'14',h'0f' range d'10',h'1f' range d'5',h'03' range d'12',h'0f' ;************************************************************************** ; * ; Procedures * ; * ;************************************************************************** ;-------------------------------------------------------------------------- ; delay ;-------------------------------------------------------------------------- nop ; [4] nop ; [4] nop ; [4] nop ; [4] nop ; [4] nop ; [4] delay16 retlw 0 ; [8] nop ; [4] nop ; [4] ldelay movwf work1 ; [4] ldel1 decfsz work1 ; [4/8] goto ldel1 ; [8/0] retlw 0 ; [8] delay macro cycles ; delay for a number of cycles if (cycles) < 0 error "Delay negative cycles" endif variable i = cycles if i > d'40' variable n = (i-d'20')/d'12' i -= (n*d'12')+d'20' variable m = i/d'4' i = 0 movlw n ; [4] call ldelay-m ; [8] else if i >= d'16' variable n = (i-d'16')/d'4' i -= (n*d'4')+d'16' call delay16-n ; [8] endif endif while i > 0 nop ; [4] i -= d'4' endw endm ;-------------------------------------------------------------------------- ; waits, fed with the wait in 10ms in the w reg ;-------------------------------------------------------------------------- routine wait movwf count wait1 movlf d'10',work1 wait2 movlf CLOCK/(d'1000'*d'20'),work2 wait3 clrwdt ; [4] nop ; [4] decfsz work2 ; [4] goto wait3 ; [8] decfsz work1 goto wait2 btfss flags,POLL ; button polled ? goto wait4 ; branch if not bsf GPIO,BUTTON ; button pressed ? nop btfss GPIO,BUTTON goto next_mode ; branch if yes wait4 decfsz count goto wait1 retlw 0 ;-------------------------------------------------------------------------- ; generates a pseudo random number in the range 0 to 15 ;-------------------------------------------------------------------------- routine get_random movfw rand_l iorwf rand_h,w bnz getr1 movfw TMR0 ; seed generator movwf rand_l xorlw h'ff' movwf rand_h getr1 rlf rand_h,w ; calculate next in sequence xorwf rand_h,w movwf work1 ; msb <= Q15 ^ Q14 swapf rand_l,w btfsc rand_h,4 xorlw h'80' ; msb <= Q12 ^ Q3 xorwf work1 rlf work1 rlf rand_l rlf rand_h ; << 1 + (Q15 ^ Q14 ^ Q12 ^ Q3) retlw 0 ;-------------------------------------------------------------------------- ; beeps ;-------------------------------------------------------------------------- routine beep movlf BEEP_PERIOD,work1 beep1 movlf 1<