; RCMC accepts "R/C Servo" style input pulses and outputs PWM to MOSFET ; Servo input pulse is normally 1.25 to 1.75 mS, nominally 21 ms frame rate ; file registers 7 to 1F are general pupose TMR0 equ 01 ; address of timer 0 STATUS equ 03 ; STATUS register F3 OSCAL equ 05 ; oscillator calibration register GPIO equ 06 ; I/O file register PWM_UP_COUNT equ 08 ; pwm amount from signal input PWM_DN_COUNT equ 09 ; pwm amount from signal input TEMP equ 0a ; Holds pwm while up/dn counting FLAGS equ 0b ; collection of status flags COUNTER equ 0c ; Loop counter for 100 pwm pulses PWM equ 0d ; used as a working register ; destination declarations W equ 0 ; w register designation FILE equ 1 ; file register destination ; flag bit declarations C_FLAG equ 0 ; Carry bit in status register Z_FLAG equ 2 ; zero bit in status register OFF_MODE equ 1 ; off mode MAX_MODE equ 2 ; 100% on mode BRK_MODE equ 3 ; brake mode SAF_MODE equ 4 ; safe mode LOBAT_FLAG equ 5 ; low battery ; pin declarations (bits) PWROK_PIN equ 0 ; power monitor input pin, input ARM_PIN equ 1 ; arming sw input LED_PIN equ 2 ; LED/diagnostic output RX_PIN equ 3 ; input pin from receiver, input BRK_PIN equ 4 ; output pin for motor brake, output PWM_PIN equ 5 ; output pin to speed control, output ; value declarations BRK_STK equ 028 ; anything less is brake engaged OFF_STK equ 040 ; anything less is PWM off MAX_STK equ 0C0 ; anything greater is 100% output FREQ equ 3 ; equal approx freq in kHz IO_CONF equ b'00001011'; 1=input, 0=output, 6 bits OP_CONF equ b'10000001'; WU disable, PU enable, T0 prescaler=1:4 org 0 movwf OSCAL ; set the oscillator calibration value bcf GPIO, PWM_PIN ; set outputs to value before enable bcf GPIO, BRK_PIN ; brake is off movlw IO_CONF tris GPIO ; enable outputs movlw OP_CONF option ; Timer 0 increments each 4 uS, roll in 1.024 mS clrf FLAGS ; set all flags = 0 btfss GPIO, PWROK_PIN ; test battery bsf FLAGS,LOBAT_FLAG; battery is low ; monitor transmitter for one second before starting clrf TEMP ; 50 x .02 sec/loop = 5.12 sec w1 btfsc GPIO, RX_PIN ; get signal goto w1 ; wait for signal to go low w2 btfss GPIO, RX_PIN ; get signal goto w2 ; wait for input sginal to go high decfsz TEMP, F ; 50 loops goto w1 ; not done yet ; ******************* this is the main routine ***************** main1 bcf FLAGS, SAF_MODE ; clear safe mode flag btfsc GPIO, ARM_PIN ; test arming pin bsf FLAGS, SAF_MODE ; set off mode if arm pin high ; measure the input signal ; set brake, off and max mode flags s0 movwf TMR0 ; set the zero flag btfsc STATUS, Z_FLAG ; test if timer 0 has reached zero incfsz COUNTER, F ; COUNTER was zero upon entry goto off_mode ; 256 mS of input signal low btfsc GPIO, RX_PIN ; wait for low goto s0 ; 7 uS/loop, asynch wrt timer 0 (4 uS) s1 btfss GPIO, RX_PIN ; wait for rising edge goto s1 ; input is low, wait movlw 6 ; want 1.000 mS timer movwf TMR0 ; preload with 6 counts x 4 uS/cout = 24 uS s2 movfw TMR0 btfss STATUS, Z_FLAG goto s2 ; wait 1.000 mS clrf TMR0 ; clear timer0 s3 btfsc GPIO, RX_PIN ; wait for input to fall, loop is 5 uS resolution goto s3 ; signal is still high movfw TMR0 ; get timer 0 = input pulse high time x 4 uS/bit movwf PWM ; store timer 0 result in PWM movlw BRK_STK ; less than 28H is brake mode subwf PWM, W ; test if PWM value is less than threshold btfsc STATUS, C_FLAG ; carry flag clear if result is negative goto s5 ; not in brake mode bsf FLAGS, BRK_MODE ; is in brake mode bcf FLAGS, OFF_MODE ; brake flag is set, off flag cleared bcf FLAGS, MAX_MODE ; max flag is clear goto main2 ; value rx is less than BRK_STICK-> exit s5 movlw OFF_STK ; less than 40H is off mode subwf PWM, W ; test if PWM value is less than threshold btfsc STATUS, C_FLAG ; carry flag clear if result is negative goto s6 ; not in off mode bcf FLAGS, BRK_MODE ; is in off mode bsf FLAGS, OFF_MODE ; off flag is set, brake flag clear bcf FLAGS, MAX_MODE ; clear max flagclear goto main2 ; value rx is less than OFF_STICK-> exit s6 movlw MAX_STK ; greater than C0 is max mode subwf PWM, W ; test if PWM value is greater than threshold btfss STATUS, C_FLAG ; carry=1 if >= goto s7 ; not in max mode, result is 40 to BF bcf FLAGS, BRK_MODE ; is in max mode bcf FLAGS, OFF_MODE ; max flag is set, brake and off flags are cleared bsf FLAGS, MAX_MODE ; set max flag goto main2 ; value rx is more than MAX_STICK-> exit s7 movlw OFF_STK ; PWM contains 40-BF subwf PWM, F ; PWM contains 0-7F rlf PWM, F ; PWM contains 0-FF bcf FLAGS, BRK_MODE ; in PWM mode, brake flag cleared bcf FLAGS, OFF_MODE ; off flag cleared bcf FLAGS, MAX_MODE ; max flag cleared main2 btfsc FLAGS, SAF_MODE goto off_mode btfsc FLAGS, BRK_MODE ; vector to appropriate routine goto brake_mode ; ESC is in brake mode btfsc FLAGS, OFF_MODE ; goto off_mode ; ESC is off btfsc FLAGS, MAX_MODE goto max_mode ; ESC is 100% on PWM_mode btfsc FLAGS, LOBAT_FLAG ; ESC is in PWM mode goto main1 ; batt too low clrf COUNTER ; loop counter pwm2 bsf GPIO, PWM_PIN ; set output pin high movfw PWM ; get PWM value movwf TEMP ; will decr TEMP until<0 movlw FREQ ; decr by constant amount pwm3 subwf TEMP, F ; decrement until <0 btfsc STATUS, C_FLAG ; carry=0 if negative goto pwm3 ; 4 uS/loop, 1Khz if FREQ=1 btfss GPIO, PWROK_PIN ; test battery with motor on bsf FLAGS, LOBAT_FLAG bcf GPIO, PWM_PIN ; set output low movfw PWM ; get PWM movwf TEMP ; will incr TEMP until>FF movlw FREQ ; incr by const amount pwm4 addwf TEMP, F ; incr until >FF btfss STATUS, C_FLAG ; carry=1 when >FF goto pwm4 ; 4 uS/loop, 1Khz if FREQ=1 incfsz COUNTER, F ; test loop counter goto pwm2 ; generate another pulse btfss PWM, 7 ; test PWM MSB goto main1 ; leave PWM output low, <50% bsf GPIO, PWM_PIN ; PWM>50%, set PWM pin high goto main1 ; 256 pulses have been generated brake_mode bcf GPIO, PWM_PIN ; turn off PWM bsf GPIO, BRK_PIN ; turn on brake bcf FLAGS, LOBAT_FLAG ; clear only in brake and off mode btfss GPIO, PWROK_PIN ; test battery bsf FLAGS, LOBAT_FLAG ; power is low goto main1 off_mode bcf GPIO, PWM_PIN ; turn off both bcf GPIO, BRK_PIN bcf FLAGS, LOBAT_FLAG ; clear only in brake and off mode btfss GPIO, PWROK_PIN ; test battery bsf FLAGS, LOBAT_FLAG ; power is low goto main1 max_mode btfsc FLAGS, LOBAT_FLAG goto main1 ; batt too low bcf GPIO, BRK_PIN ; turn off brake bsf GPIO, PWM_PIN ; set PWM on btfss GPIO, PWROK_PIN ; test battery w/ mtr on bsf FLAGS, LOBAT_FLAG ; power is low goto main1 END