;; servo-decoder.asm (c) Ben Levitt 2006-2007 ;; ;; A pic10f220 programmed with this code will listen to servo signals ;; on GPIO3, and send a 250ms pulse on GPIO0 whenever the servo signal ;; switches from above-center to below-center, or back. ;; ;; I use it to electronically trigger a digital video camera's ;; start-recording/stop-recording button. ;; ;; I connect GPIO0 to the shutter button connection through a 1kOhm ;; resistor. ;; ;; I compile using the open assembler gpasm. #include __config (_IOFSCS_8MHZ & _WDT_OFF & _MCPU_OFF & _MCLRE_OFF & _CP_OFF) ;; Variable cblock 0x10 Length ; how long high? State ; 0=middle, 1=low, 2=high DelayCounter:3 ; counters for Delay subroutines endc org 0x00 Start call Init10f220 clrf GPIO ; ShutterTrigger off, Vars to 0 clrf Length clrf State call Delay250 ; Wait a second for power to stabilize call Delay250 call Delay250 call Delay250 Main call GetPulseLength btfsc State,0 ; if State=1 goto AlreadyLow goto AlreadyLow btfsc State,1 ; if State=2 goto AlreadyHigh goto AlreadyHigh btfss Length,7 ; if Length is low -> DoLow goto DoLow btfsc Length,7 ; if Length is high -> DoHigh goto DoHigh goto Main AlreadyLow btfsc Length,7 ; if Length is high -> DoMiddle goto DoMiddle goto Main AlreadyHigh btfss Length,7 ; if Length is low -> DoMiddle goto DoMiddle goto Main DoLow bsf State,0 ; Set State to 1 (Low) bsf GPIO,0 ; Set GPIO0 (ShutterTrigger) on call Delay250 bcf GPIO,0 ; Set GPIO0 (ShutterTrigger) off goto Main DoHigh bsf State,1 ; Set State to 2 (High) bsf GPIO,0 ; Set GPIO1 (ShutterTrigger) on call Delay250 bcf GPIO,0 ; Set GPIO1 (ShutterTrigger) off goto Main DoMiddle clrf State ; Set State to 0/Middle clrf GPIO ; Set ShutterTrigger off goto Main ;; Chip Initialization Routine Init10f220 movwf OSCCAL ; load factory osccal value at start-up bcf OSCCAL,0 ; do NOT output osc/4 on GP2 clrf ADCON0 ; Disable A2D module movlw b'00000000' ; All GPIO pins off on power-up movwf GPIO ; load port latches movlw b'00001100' ; GP2,GP3 = input, rest outputs tris GPIO ; set I/O directions movlw b'11110000' ; wake-up on pin change disabled, weak pull-ups off option ; Timer0 clock select on GP2 internal write to OPTION_REG retlw 0 ;; Handy Delay Routines Delay250 ; preload 2 into W for a 250ms delay movlw 2 Delay movwf DelayCounter; pre-load W & enter at Delay2 for different delays movlw D'232' ; (250ms per 2 in W on entry at 8MHZ) movwf DelayCounter+1 movlw D'255' movwf DelayCounter+2 Dloop nop ; 1 decfsz DelayCounter+2,f ; 1 goto $-2 ; 2/1 decfsz DelayCounter+1,f ; 1 goto $-4 ; 2/1 decfsz DelayCounter,f ; 1 goto $-6 ; 2/1 retlw 0 ; 2 ;; Wait for a pulse on GPIO3, store the duration of the pulse in Length GetPulseLength btfss GPIO,3 ; wait here until GPIO3 is low goto $-1 btfss GPIO,3 ; wait here until GPIO3 is high goto $-1 clrf Length LengthLoop ; 12 cycles per loop nop nop nop nop nop nop nop nop incf Length,F btfsc GPIO,3 ; wait here until GPIO3 is low goto LengthLoop retlw 0 end