MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 1 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00001 ; 00002 ; 00003 ; Code for the 12F675 PIC to manage an ESC for brushed motors. 00004 ; SCCS: @(#) esc.asm 1.5@(#) 00005 00006 processor 12F675 00007 radix dec 00008 00009 ; 00010 ; This module is configurable for a number of different combinations of 00011 ; facilities. Please note that the circuit used for each of the configurations 00012 ; is different. So pay attention to the diagram below. 00013 ; 00014 ; It is *your* responsibility to ensure that the configuration parameters set 00015 ; in the code below match your circuit. 00016 ; 00017 ; The options are: 00018 ; ESC without brake (use 'BRAKE equ 0") 00019 ; ESC with brake (use 'BRAKE equ 1,2") 00020 ; 00021 ; Low Voltage Cutoff (set 'LOWVOLTS' in mV) 00022 ; *NOTE* a LOWVOLTS of 0 will disable the Low Voltage Cutoff 00023 ; 00024 ; Auto throttle adjustment, or fixed throttle stops 00025 ; (Set PULSE_LO_HI to 0 for auto adjust, or width in 0.001msec) 00026 ; 00027 ; 00000002 00028 BRAKE equ 2 ; 0 for no brake, 1 for a hard, 2 for soft 00000001 00029 BRAKEENB equ 1 ; 0 for brake always on, 1 for GP3 control 00001770 00030 LOWVOLTS equ 6000 ; 6 Volt cutoff 00000000 00031 PULSE_LO_HI equ 0 ; auto throttle calibrate 00000002 00032 THROTTLEMAP equ 2 ; 0/1 is linear, 2 is power 00033 00034 ; 00035 ; The reason the circuit is depends on the various options is that there 00036 ; are not quite enough pins on the 12F675 to do everything if you want a brake. 00037 ; The main problem arises because to do accurate PWM in software while reading 00038 ; an accurate value for the throttle pulse width requires the externally gated 00039 ; TIMER1 to be used, and the gate is active low - whereas the r/c control 00040 ; signal is active high. While it is possible to use the PICs comparitor to do 00041 ; the inversion this requires 2 pins. When you have a brake there are not 00042 ; enough pins available. 00043 ; 00044 ; Assumes: 00045 ; Bandgap as calibrated at factory 00046 ; CPD disabled 00047 ; CP disabled 00048 ; BODEN enabled 00049 ; MCLR disabled 00050 ; PWRTE enabled 00051 ; WDT (Watchdog) enabled 00052 ; OSC internal RC (no clockout) 00053 ; MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 2 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00054 ; The basic circuit for the ESC is as follows: 00055 ; 00056 ; 00057 ; power ----------------------- 00058 ; | | 00059 ; ----------------- 00060 ; | + (1) (8) - | 00061 ; | PIC12F675 | 00062 ; | | 00063 ; rx | (3) GP4 |-<- 00064 ; >--XXXX-------| GP1 (6) | | (active low rx pulse) 00065 ; 4k7 | (5) GP2 |->- 00066 ; | | 00067 ; sense >----| GP? (?) | 00068 ; | (2) GP5 | ----------> Motor On (active high) 00069 ;Brake off >----| GP3 (4) | 00070 ; | (7) GP0 | ----------> Brake On (active high) 00071 ; ----------------- 00072 ; 00073 ; 00074 ; See the full circuit diagram for further details. 00075 ; 00076 ; Features of this software are as follows: 00077 ; 00078 ; Watchdog timer ensure the software is running, this is used to ensure 00079 ; that the software always gets back to the main sensing code. If 00080 ; it doesn't the chip is reset. 00081 ; 00082 ; Timer 0 is used to measure the time for the PWM drive to the motor 00083 ; and brake. 00084 ; 00085 ; This timer runs at 1Mhz with a 1:2 prescaler. These interrupt, 00086 ; together with the programable interrupt routine permits PWM 00087 ; frequencies from 8kHz at minimum throttle down to 2kHz at full 00088 ; throttle. 00089 ; 00090 ; Timer 1 is used to measure the input pulse width. Pulse width should be 00091 ; 1.5msec nominal at central position +/- 0.5msec depending on the 00092 ; control direction. 00093 ; 00094 ; At 4Mhz clock timer 1 will run at 0.001msec count rate. This gives 00095 ; count values for 1.5msec that are well within 16-bit resolution. 00096 ; 00097 ; 00098 ; The throttle can either be auto calibrating, or operate over a fixed range. 00099 ; When the throttle operates over a fixed range it is assumed to be centred 00100 ; on 1.500 msec, however in the auto-calibrate mode the throttle will cover 00101 ; the range of values seen during programming. 00102 ; 00103 ; The auto throttle calibration assumes that the first receiver input it sees 00104 ; is throttle off. The ESC then tracks the highest, stable, pulse seen and uses 00105 ; this as the maximum throttle. When the throttle again returns to idle the 00106 ; ESC enters normal operation. A stable pulse is a sequence of 'autopulse' MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 3 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00107 ; pulses that are within +/- autofuzz of the first pulse. 00108 ; 00109 ; The LOS system is based on a software timer in the code that waits for 00110 ; valid throttle pulses. This timer is part of the various loops and so 00111 ; the exact LOS time varies depending on what arrives on the input line. 00112 ; 00113 ; The power up arming delay is 'armpulse' counts from powerup, and 00114 ; 'rearmpulse' after a LOS or power-fail detection. 00115 ; 00116 ; The low supply voltage is checked every time we receive a servo pulse. 00117 ; In theory we don't want to discharge cells below 0.9V/cell, also 00118 ; we want to ensure there is sufficient battery voltage to power the LDO 00119 ; regulator for a reasonable time. The ESC uses the A/D converter in the 00120 ; PIC to measure the battery supply voltage and averages this over 4 (2^lowvavgln2) 00121 ; samples (to stop a single 'spike' in current from turning the ESC off). 00122 ; When low battery voltage is detected this is treated as identical to 00123 ; LOS, this causes the motor to stop and wait for rearming. 00124 ; 00125 ; Possible issues: 00126 ; 00127 ; -> The brake is off when there is no valid receiver input. 00128 ; A: This is probably desireable, if the receiver input is intermittent then 00129 ; applying the brake is probably a bad idea since when the receiver input 00130 ; starts working the power is probably going to be applied. 00131 ; 00132 ; -> The controller switches the brake on immediately that the controller starts up 00133 ; and detects a valid receiver sequence. 00134 ; A: I don't think that this is a problem. 00135 ; 00136 ; Possible enhancements: 00137 ; 00138 ; i) Perhaps a slower soft brake may be required, check this out during 00139 ; testing. No: the current braking rate is very good with the GWS 00140 ; EPS400 gearbox. 00141 ; ii) It may be possible to use the EEPROM to configure brake and other 00142 ; parameters. 00143 ; iii) It may be possible to use the EEPROM to record minimum voltages etc. 00144 ; However, writing the EEPROM requires interrupts are off, this may affect 00145 ; PWM generation. 00146 ; iv) Check the audio level via the motor at low RPM, David reports that 00147 ; there is significant audio artifacts at low RPM - the high frequency 00148 ; PWM is supposed to stop this... This was significantly improved 00149 ; by the change to the PWM engine that replaced the lowest two throttle 00150 ; possitions with idle. The problem was that these PWM rates were 00151 ; insufficient to spin the motor and just caused noise. 00152 ; 00153 00154 #include 00001 LIST 00002 ; P12F675.INC Standard Header File, Version 1.04 Microchip Technology, Inc. 00283 LIST 00155 2007 3FCC 00156 __CONFIG(_BODEN_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT) MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 4 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00157 00158 ; Configuration parameters 00159 00160 00161 ; Main parameters 00000005 00162 autopulse equ 5 ; Required number 'same value' to program 00000003 00163 autofuzz equ 3 ; +/- autofuzz is the same value 00000014 00164 armpulse equ 20 ; Required throttle off to arm at start 00000001 00165 rearmpulse equ 1 ; Immediate rearm after LOS/low volts 00000050 00166 losms equ 80 ; LOS if no signal in 80ms 00000002 00167 lowvavgln2 equ 2 ; ln2(number of low volts avg) 00168 00169 ; GPIO register bits and other constants 00000004 00170 inrxbit equ 4 ; Active low rx input always on GP4 00000005 00171 motoron equ 5 ; Motor is always controlled by GP5 00172 00173 ; If both a brake and low voltage cutout are required then 00174 ; the internal comparitor cannot be used as an inverter and a separate 00175 ; transistor received inverter is required. The options at this stage 00176 ; involving moving the pins around... 00177 if LOWVOLTS > 0 00000000 00178 voltsense equ 0 ; Main battery sense voltage GP0 00179 endif 00180 00181 if BRAKE > 0 && BRAKEENB > 0 00000003 00182 brakeenb equ 3 ; GP3 high to enable brake 00183 endif 00184 00185 if (BRAKE == 0) || (LOWVOLTS == 0) 00186 ; In this case we can use the internal comparitor as an inverter 00187 ; because there are enough pins available 00188 comparitorinuse equ 1 ; Comparitor is in use 00189 inrxraw equ 1 ; Active high receiver input 00190 outrxinv equ 2 ; Active low receiver output (--> inrxbit) 00191 if BRAKE > 0 00192 brakeon equ 0 ; brake FET control on GP0 if no low volts 00193 endif 00194 else 00000000 00195 comparitorinuse equ 0 ; Comparitor is not in use 00000002 00196 brakeon equ 2 ; brake FET control on GP2 if both in use 00197 endif 00198 00199 ; RAM Definitions 00200 cblock 20h 00000020 00201 w_save ; Int save: !! Both banks used !! 00000021 00202 sts_save ; 00203 00000022 00204 escstatus ; Various status bits 00000023 00205 rearmcnt ; Count for next arm operation 00000024 00206 armcnt ; ESC arm counter 00000025 00207 throttle ; Current throttle 00000026 00208 pwmmode ; PWM Interupt offset 00000027 00209 pwmONio ; GPIO value during phase A (on) MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 5 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00000028 00210 pwmONt0 ; TMR0 value during phase A (on) 00000029 00211 pwmOFFt0 ; TMR0 value during phase B (off) 0000002A 00212 newpwmON ; Next PWM 'ON' time 0000002B 00213 newpwmOFF ; Next PWM 'OFF' time 0000002C 00214 cntperth ; # of 0.001 counts per throttle step 0000002D 00215 cntthbl ; Throttle base in counts (LSB) 0000002E 00216 cntthbh ; Throttle base in counts (MSB) 0000002F 00217 lowvoltavg:1< 00406 endif MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 9 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00407 if THROTTLEMAP == 2 00408 #include 00001 ; Generated: Thu Jan 15 22:38:00 2004 00002 ; Using: throttle.pl 00003 ; Version: 1.5 00004 ; 00005 ; **** DO NOT EDIT THIS FILE BY HAND **** 00006 ; **** THIS IS COMPUTER GENERATED CODE **** 00007 ; 00008 ; mapthrottle = 2 00009 ; roundscale = 1 00010 ; 00011 ; min_motor_off = 128 00012 ; throttle_steps = 64 00013 ; minfrequency = 0 00014 ; 00015 ; instruction_clock = 1000000 00016 ; timer0_prescale = 2 00017 ; max_delay = 512 00018 ; 00019 ; int_in_ohead = 8 00020 ; int_out_ohead = 7 00021 ; int_tm0_ohead = 2 00022 ; int_std_pre = 5 00023 ; int_std_post = 3 00024 ; int_spc_pre = 2 00025 ; int_spc_mid = 2 00026 ; int_spc_post = 5 00027 ; min_int_std = 25 00028 ; 00029 ; Trottle Mapped ---- Target PWM ----- ---- Actual PWM ---- ERROR 00030 ; #:%age %age on:off PWM Details on:off PWM Details 00031 ; 0:0.000 -> 0.000 0:512 0.000 @ 1953Hz 0:513 0.000 @ 1949Hz ( 0.00%) 00032 ; 1:0.016 -> 0.126 18:128 0.123 @ 6849Hz 18:129 0.122 @ 6802Hz (-2.81%) 00033 ; 2:0.031 -> 0.178 27:128 0.174 @ 6451Hz 28:128 0.179 @ 6410Hz ( 0.74%) 00034 ; 3:0.047 -> 0.218 35:128 0.215 @ 6134Hz 36:128 0.220 @ 6097Hz ( 0.59%) 00035 ; 4:0.062 -> 0.252 43:128 0.251 @ 5847Hz 44:128 0.256 @ 5813Hz ( 1.52%) 00036 ; 5:0.078 -> 0.282 50:128 0.281 @ 5617Hz 50:128 0.281 @ 5617Hz (-0.29%) 00037 ; 6:0.094 -> 0.309 57:128 0.308 @ 5405Hz 58:128 0.312 @ 5376Hz ( 1.04%) 00038 ; 7:0.109 -> 0.333 63:128 0.330 @ 5235Hz 64:128 0.333 @ 5208Hz ( 0.00%) 00039 ; 8:0.125 -> 0.356 70:128 0.354 @ 5050Hz 70:128 0.354 @ 5050Hz (-0.79%) 00040 ; 9:0.141 -> 0.378 77:128 0.376 @ 4878Hz 78:128 0.379 @ 4854Hz ( 0.18%) 00041 ; 10:0.156 -> 0.398 84:128 0.396 @ 4716Hz 84:128 0.396 @ 4716Hz (-0.55%) 00042 ; 11:0.172 -> 0.418 91:128 0.416 @ 4566Hz 92:128 0.418 @ 4545Hz ( 0.08%) 00043 ; 12:0.188 -> 0.436 99:128 0.436 @ 4405Hz 100:128 0.439 @ 4385Hz ( 0.50%) 00044 ; 13:0.203 -> 0.454 106:128 0.453 @ 4273Hz 106:128 0.453 @ 4273Hz (-0.28%) 00045 ; 14:0.219 -> 0.471 114:128 0.471 @ 4132Hz 114:128 0.471 @ 4132Hz (-0.07%) 00046 ; 15:0.234 -> 0.488 121:128 0.486 @ 4016Hz 122:128 0.488 @ 4000Hz ( 0.01%) 00047 ; 16:0.250 -> 0.504 130:128 0.504 @ 3875Hz 130:128 0.504 @ 3875Hz (-0.02%) 00048 ; 17:0.266 -> 0.519 138:128 0.519 @ 3759Hz 138:128 0.519 @ 3759Hz (-0.13%) 00049 ; 18:0.281 -> 0.535 146:128 0.533 @ 3649Hz 146:128 0.533 @ 3649Hz (-0.31%) 00050 ; 19:0.297 -> 0.549 155:128 0.548 @ 3533Hz 156:128 0.549 @ 3521Hz ( 0.02%) 00051 ; 20:0.312 -> 0.563 165:128 0.563 @ 3412Hz 166:128 0.565 @ 3401Hz ( 0.21%) MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 10 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00052 ; 21:0.328 -> 0.577 174:128 0.576 @ 3311Hz 174:128 0.576 @ 3311Hz (-0.21%) 00053 ; 22:0.344 -> 0.591 184:128 0.590 @ 3205Hz 184:128 0.590 @ 3205Hz (-0.20%) 00054 ; 23:0.359 -> 0.604 195:128 0.604 @ 3095Hz 196:128 0.605 @ 3086Hz ( 0.12%) 00055 ; 24:0.375 -> 0.617 206:128 0.617 @ 2994Hz 206:128 0.617 @ 2994Hz (-0.07%) 00056 ; 25:0.391 -> 0.630 217:128 0.629 @ 2898Hz 218:128 0.630 @ 2890Hz ( 0.02%) 00057 ; 26:0.406 -> 0.642 229:128 0.641 @ 2801Hz 230:128 0.642 @ 2793Hz ( 0.01%) 00058 ; 27:0.422 -> 0.655 242:128 0.654 @ 2702Hz 242:128 0.654 @ 2702Hz (-0.09%) 00059 ; 28:0.438 -> 0.667 255:128 0.666 @ 2610Hz 256:128 0.667 @ 2604Hz ( 0.00%) 00060 ; 29:0.453 -> 0.678 270:128 0.678 @ 2512Hz 270:128 0.678 @ 2512Hz (-0.01%) 00061 ; 30:0.469 -> 0.690 284:128 0.689 @ 2427Hz 284:128 0.689 @ 2427Hz (-0.11%) 00062 ; 31:0.484 -> 0.701 300:128 0.701 @ 2336Hz 300:128 0.701 @ 2336Hz (-0.08%) 00063 ; 32:0.500 -> 0.713 317:128 0.712 @ 2247Hz 318:128 0.713 @ 2242Hz ( 0.04%) 00064 ; 33:0.516 -> 0.724 335:128 0.724 @ 2159Hz 336:128 0.724 @ 2155Hz ( 0.05%) 00065 ; 34:0.531 -> 0.735 354:128 0.734 @ 2074Hz 354:128 0.734 @ 2074Hz (-0.03%) 00066 ; 35:0.547 -> 0.745 374:128 0.745 @ 1992Hz 374:128 0.745 @ 1992Hz (-0.05%) 00067 ; 36:0.562 -> 0.756 396:128 0.756 @ 1908Hz 396:128 0.756 @ 1908Hz (-0.03%) 00068 ; 37:0.578 -> 0.766 419:128 0.766 @ 1828Hz 420:128 0.766 @ 1824Hz ( 0.01%) 00069 ; 38:0.594 -> 0.777 445:128 0.777 @ 1745Hz 446:128 0.777 @ 1742Hz ( 0.05%) 00070 ; 39:0.609 -> 0.787 472:128 0.787 @ 1666Hz 472:128 0.787 @ 1666Hz (-0.02%) 00071 ; 40:0.625 -> 0.797 501:128 0.797 @ 1589Hz 502:128 0.797 @ 1587Hz ( 0.00%) 00072 ; 41:0.641 -> 0.807 512:122 0.808 @ 1577Hz 512:122 0.808 @ 1577Hz ( 0.11%) 00073 ; 42:0.656 -> 0.816 512:115 0.817 @ 1594Hz 512:116 0.815 @ 1592Hz (-0.15%) 00074 ; 43:0.672 -> 0.826 512:107 0.827 @ 1615Hz 512:108 0.826 @ 1612Hz (-0.04%) 00075 ; 44:0.688 -> 0.836 512:100 0.837 @ 1633Hz 512:100 0.837 @ 1633Hz ( 0.11%) 00076 ; 45:0.703 -> 0.845 512: 93 0.846 @ 1652Hz 512: 94 0.845 @ 1650Hz (-0.03%) 00077 ; 46:0.719 -> 0.854 512: 87 0.855 @ 1669Hz 512: 88 0.853 @ 1666Hz (-0.14%) 00078 ; 47:0.734 -> 0.864 512: 80 0.865 @ 1689Hz 512: 80 0.865 @ 1689Hz ( 0.13%) 00079 ; 48:0.750 -> 0.873 512: 74 0.874 @ 1706Hz 512: 74 0.874 @ 1706Hz ( 0.10%) 00080 ; 49:0.766 -> 0.882 512: 68 0.883 @ 1724Hz 512: 68 0.883 @ 1724Hz ( 0.10%) 00081 ; 50:0.781 -> 0.891 512: 62 0.892 @ 1742Hz 512: 62 0.892 @ 1742Hz ( 0.13%) 00082 ; 51:0.797 -> 0.900 512: 57 0.900 @ 1757Hz 512: 58 0.898 @ 1754Hz (-0.17%) 00083 ; 52:0.812 -> 0.909 512: 51 0.909 @ 1776Hz 512: 52 0.908 @ 1773Hz (-0.08%) 00084 ; 53:0.828 -> 0.917 512: 46 0.918 @ 1792Hz 512: 46 0.918 @ 1792Hz ( 0.04%) 00085 ; 54:0.844 -> 0.926 512: 41 0.926 @ 1808Hz 512: 42 0.924 @ 1805Hz (-0.18%) 00086 ; 55:0.859 -> 0.934 512: 35 0.936 @ 1828Hz 512: 36 0.934 @ 1824Hz (-0.00%) 00087 ; 56:0.875 -> 0.943 512: 31 0.943 @ 1841Hz 512: 32 0.941 @ 1838Hz (-0.17%) 00088 ; 57:0.891 -> 0.951 512: 26 0.952 @ 1858Hz 512: 26 0.952 @ 1858Hz ( 0.05%) 00089 ; 58:0.906 -> 0.959 512: 21 0.961 @ 1876Hz 513: 21 0.961 @ 1872Hz ( 0.12%) 00090 ; 59:0.922 -> 0.968 512: 17 0.968 @ 1890Hz 513: 17 0.968 @ 1886Hz ( 0.02%) 00091 ; 60:0.938 -> 0.976 512: 12 0.977 @ 1908Hz 513: 12 0.977 @ 1904Hz ( 0.13%) 00092 ; 61:0.953 -> 0.984 512: 8 0.985 @ 1923Hz 513: 8 0.985 @ 1919Hz ( 0.07%) 00093 ; 62:0.969 -> 0.992 512: 4 0.992 @ 1937Hz 513: 4 0.992 @ 1934Hz ( 0.02%) 00094 ; 63:0.984 -> 1.000 512: 0 1.000 @ 1953Hz 513: 0 1.000 @ 1949Hz ( 0.00%) 00000040 00095 throttlesteps equ 64 0100 00096 int_0on 0100 0185 00097 clrf GPIO 00098 ; Delay 1 0101 0000 00099 nop 0102 29FB 00100 goto rearm_OFFt0 0103 00101 int_18on 0103 0827 00102 movfw pwmONio 0104 0085 00103 movwf GPIO 0105 00104 int_on17off MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 11 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00105 ; Delay 17 0105 21FD 00106 call emptyreturn 0106 21FD 00107 call emptyreturn 0107 21FD 00108 call emptyreturn 0108 21FD 00109 call emptyreturn 0109 0000 00110 nop 010A 0185 00111 clrf GPIO 010B 29FB 00112 goto rearm_OFFt0 010C 00113 int_0off 010C 0827 00114 movfw pwmONio 010D 0085 00115 movwf GPIO 00116 ; Delay 0 010E 29F9 00117 goto rearm_ONt0 010F 00118 int_4off 010F 0000 00119 nop 0110 0185 00120 clrf GPIO 0111 00121 int_off2on 00122 ; Delay 2 0111 2912 00123 goto $+1 0112 0827 00124 movfw pwmONio 0113 0085 00125 movwf GPIO 0114 29F9 00126 goto rearm_ONt0 0115 00127 int_8off 0115 0000 00128 nop 0116 0185 00129 clrf GPIO 0117 00130 int_off6on 00131 ; Delay 2 0117 2918 00132 goto $+1 0118 00133 int_off4on 0118 2911 00134 goto int_off2on 0119 00135 int_12off 0119 0000 00136 nop 011A 0185 00137 clrf GPIO 011B 00138 int_off10on 00139 ; Delay 2 011B 291C 00140 goto $+1 011C 00141 int_off8on 011C 2917 00142 goto int_off6on 011D 00143 int_17off 011D 0000 00144 nop 011E 0185 00145 clrf GPIO 011F 00146 int_off15on 00147 ; Delay 3 011F 2920 00148 goto $+1 0120 0000 00149 nop 0121 00150 int_off12on 0121 291B 00151 goto int_off10on 0122 00152 int_21off 0122 0000 00153 nop 0123 0185 00154 clrf GPIO 0124 00155 int_off19on 00156 ; Delay 2 0124 2925 00157 goto $+1 MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 12 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0125 00158 int_off17on 0125 291F 00159 goto int_off15on 00160 ; Ensure correct alignment of this table for a computed goto 00161 if ($ & ~0FFh) != (($+64-1) & ~0FFh) 00162 org ($+64) & ~0FFh 00163 endif 0126 00164 pwmtype_tbl 0126 3400 00165 retlw int_0on - int_refpoint 0127 3403 00166 retlw int_18on - int_refpoint 0128 34E6 00167 retlw int_std - int_refpoint 0129 34E6 00168 retlw int_std - int_refpoint 012A 34E6 00169 retlw int_std - int_refpoint 012B 34E6 00170 retlw int_std - int_refpoint 012C 34E6 00171 retlw int_std - int_refpoint 012D 34E6 00172 retlw int_std - int_refpoint 012E 34E6 00173 retlw int_std - int_refpoint 012F 34E6 00174 retlw int_std - int_refpoint 0130 34E6 00175 retlw int_std - int_refpoint 0131 34E6 00176 retlw int_std - int_refpoint 0132 34E6 00177 retlw int_std - int_refpoint 0133 34E6 00178 retlw int_std - int_refpoint 0134 34E6 00179 retlw int_std - int_refpoint 0135 34E6 00180 retlw int_std - int_refpoint 0136 34E6 00181 retlw int_std - int_refpoint 0137 34E6 00182 retlw int_std - int_refpoint 0138 34E6 00183 retlw int_std - int_refpoint 0139 34E6 00184 retlw int_std - int_refpoint 013A 34E6 00185 retlw int_std - int_refpoint 013B 34E6 00186 retlw int_std - int_refpoint 013C 34E6 00187 retlw int_std - int_refpoint 013D 34E6 00188 retlw int_std - int_refpoint 013E 34E6 00189 retlw int_std - int_refpoint 013F 34E6 00190 retlw int_std - int_refpoint 0140 34E6 00191 retlw int_std - int_refpoint 0141 34E6 00192 retlw int_std - int_refpoint 0142 34E6 00193 retlw int_std - int_refpoint 0143 34E6 00194 retlw int_std - int_refpoint 0144 34E6 00195 retlw int_std - int_refpoint 0145 34E6 00196 retlw int_std - int_refpoint 0146 34E6 00197 retlw int_std - int_refpoint 0147 34E6 00198 retlw int_std - int_refpoint 0148 34E6 00199 retlw int_std - int_refpoint 0149 34E6 00200 retlw int_std - int_refpoint 014A 34E6 00201 retlw int_std - int_refpoint 014B 34E6 00202 retlw int_std - int_refpoint 014C 34E6 00203 retlw int_std - int_refpoint 014D 34E6 00204 retlw int_std - int_refpoint 014E 34E6 00205 retlw int_std - int_refpoint 014F 34E6 00206 retlw int_std - int_refpoint 0150 34E6 00207 retlw int_std - int_refpoint 0151 34E6 00208 retlw int_std - int_refpoint 0152 34E6 00209 retlw int_std - int_refpoint 0153 34E6 00210 retlw int_std - int_refpoint MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 13 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0154 34E6 00211 retlw int_std - int_refpoint 0155 34E6 00212 retlw int_std - int_refpoint 0156 34E6 00213 retlw int_std - int_refpoint 0157 34E6 00214 retlw int_std - int_refpoint 0158 34E6 00215 retlw int_std - int_refpoint 0159 34E6 00216 retlw int_std - int_refpoint 015A 34E6 00217 retlw int_std - int_refpoint 015B 34E6 00218 retlw int_std - int_refpoint 015C 34E6 00219 retlw int_std - int_refpoint 015D 34E6 00220 retlw int_std - int_refpoint 015E 34E6 00221 retlw int_std - int_refpoint 015F 34E6 00222 retlw int_std - int_refpoint 0160 3422 00223 retlw int_21off - int_refpoint 0161 341D 00224 retlw int_17off - int_refpoint 0162 3419 00225 retlw int_12off - int_refpoint 0163 3415 00226 retlw int_8off - int_refpoint 0164 340F 00227 retlw int_4off - int_refpoint 0165 340C 00228 retlw int_0off - int_refpoint 00229 ; Ensure correct alignment of this table for a computed goto 00230 if ($ & ~0FFh) != (($+64-1) & ~0FFh) 00231 org ($+64) & ~0FFh 00232 endif 0166 00233 pwmONt0_tbl 0166 3400 00234 retlw -0 0167 3400 00235 retlw -0 0168 34FB 00236 retlw -5 0169 34F7 00237 retlw -9 016A 34F3 00238 retlw -13 016B 34F0 00239 retlw -16 016C 34EC 00240 retlw -20 016D 34E9 00241 retlw -23 016E 34E6 00242 retlw -26 016F 34E2 00243 retlw -30 0170 34DF 00244 retlw -33 0171 34DB 00245 retlw -37 0172 34D7 00246 retlw -41 0173 34D4 00247 retlw -44 0174 34D0 00248 retlw -48 0175 34CC 00249 retlw -52 0176 34C8 00250 retlw -56 0177 34C4 00251 retlw -60 0178 34C0 00252 retlw -64 0179 34BB 00253 retlw -69 017A 34B6 00254 retlw -74 017B 34B2 00255 retlw -78 017C 34AD 00256 retlw -83 017D 34A7 00257 retlw -89 017E 34A2 00258 retlw -94 017F 349C 00259 retlw -100 0180 3496 00260 retlw -106 0181 3490 00261 retlw -112 0182 3489 00262 retlw -119 0183 3482 00263 retlw -126 MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 14 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0184 347B 00264 retlw -133 0185 3473 00265 retlw -141 0186 346A 00266 retlw -150 0187 3461 00267 retlw -159 0188 3458 00268 retlw -168 0189 344E 00269 retlw -178 018A 3443 00270 retlw -189 018B 3437 00271 retlw -201 018C 342A 00272 retlw -214 018D 341D 00273 retlw -227 018E 340E 00274 retlw -242 018F 3409 00275 retlw -247 0190 3409 00276 retlw -247 0191 3409 00277 retlw -247 0192 3409 00278 retlw -247 0193 3409 00279 retlw -247 0194 3409 00280 retlw -247 0195 3409 00281 retlw -247 0196 3409 00282 retlw -247 0197 3409 00283 retlw -247 0198 3409 00284 retlw -247 0199 3409 00285 retlw -247 019A 3409 00286 retlw -247 019B 3409 00287 retlw -247 019C 3409 00288 retlw -247 019D 3409 00289 retlw -247 019E 3409 00290 retlw -247 019F 3409 00291 retlw -247 01A0 3408 00292 retlw -248 01A1 3408 00293 retlw -248 01A2 3408 00294 retlw -248 01A3 3408 00295 retlw -248 01A4 3408 00296 retlw -248 01A5 3408 00297 retlw -248 00298 ; Ensure correct alignment of this table for a computed goto 00299 if ($ & ~0FFh) != (($+64-1) & ~0FFh) 00300 org ($+64) & ~0FFh 00301 endif 01A6 00302 pwmOFFt0_tbl 01A6 3408 00303 retlw -248 01A7 34C8 00304 retlw -56 01A8 34C9 00305 retlw -55 01A9 34C9 00306 retlw -55 01AA 34C9 00307 retlw -55 01AB 34C9 00308 retlw -55 01AC 34C9 00309 retlw -55 01AD 34C9 00310 retlw -55 01AE 34C9 00311 retlw -55 01AF 34C9 00312 retlw -55 01B0 34C9 00313 retlw -55 01B1 34C9 00314 retlw -55 01B2 34C9 00315 retlw -55 01B3 34C9 00316 retlw -55 MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 15 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01B4 34C9 00317 retlw -55 01B5 34C9 00318 retlw -55 01B6 34C9 00319 retlw -55 01B7 34C9 00320 retlw -55 01B8 34C9 00321 retlw -55 01B9 34C9 00322 retlw -55 01BA 34C9 00323 retlw -55 01BB 34C9 00324 retlw -55 01BC 34C9 00325 retlw -55 01BD 34C9 00326 retlw -55 01BE 34C9 00327 retlw -55 01BF 34C9 00328 retlw -55 01C0 34C9 00329 retlw -55 01C1 34C9 00330 retlw -55 01C2 34C9 00331 retlw -55 01C3 34C9 00332 retlw -55 01C4 34C9 00333 retlw -55 01C5 34C9 00334 retlw -55 01C6 34C9 00335 retlw -55 01C7 34C9 00336 retlw -55 01C8 34C9 00337 retlw -55 01C9 34C9 00338 retlw -55 01CA 34C9 00339 retlw -55 01CB 34C9 00340 retlw -55 01CC 34C9 00341 retlw -55 01CD 34C9 00342 retlw -55 01CE 34C9 00343 retlw -55 01CF 34CC 00344 retlw -52 01D0 34CF 00345 retlw -49 01D1 34D3 00346 retlw -45 01D2 34D7 00347 retlw -41 01D3 34DA 00348 retlw -38 01D4 34DD 00349 retlw -35 01D5 34E1 00350 retlw -31 01D6 34E4 00351 retlw -28 01D7 34E7 00352 retlw -25 01D8 34EA 00353 retlw -22 01D9 34EC 00354 retlw -20 01DA 34EF 00355 retlw -17 01DB 34F2 00356 retlw -14 01DC 34F4 00357 retlw -12 01DD 34F7 00358 retlw -9 01DE 34F9 00359 retlw -7 01DF 34FC 00360 retlw -4 01E0 3400 00361 retlw -0 01E1 3400 00362 retlw -0 01E2 3400 00363 retlw -0 01E3 3400 00364 retlw -0 01E4 3400 00365 retlw -0 01E5 3400 00366 retlw -0 00409 endif 00410 00411 ; check that this entry point is 'within' the page MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 16 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00412 if (pwm_page >> 8) != ($ >> 8) 00413 fatal error PWM code too large 00414 endif 00415 ; 00416 ; Be careful with this code, the instruction cound has been 00417 ; carefully balanced to provide symetrical paths with GPIO 00418 ; updated at the same point in each flow. 01E6 00419 int_std 01E6 18A2 00420 btfsc escstatus,esc_pwmOFF 01E7 29ED 00421 goto in_pwmOFF 00422 ; We are currently in phaseA (on), so produce phaseB (off) 01E8 14A2 00423 bsf escstatus,esc_pwmOFF 01E9 0000 00424 nop 01EA 0185 00425 clrf GPIO 01EB 0829 00426 movfw pwmOFFt0 01EC 29F2 00427 goto rearm 00428 01ED 00429 in_pwmOFF 00430 ; We are currently in phaseB 01ED 0827 00431 movfw pwmONio 01EE 0085 00432 movwf GPIO 01EF 0828 00433 movfw pwmONt0 01F0 10A2 00434 bcf escstatus,esc_pwmOFF 01F1 0000 00435 nop 00436 01F2 00437 rearm 00438 ; Clear the timer interrupt, and reload counter 01F2 0081 00439 movwf TMR0 01F3 110B 00440 bcf INTCON, T0IF 00441 00442 ; All done, restore status 01F4 0E21 00443 swapf sts_save,w 01F5 0083 00444 movwf STATUS 01F6 0EA0 00445 swapf w_save,f 01F7 0E20 00446 swapf w_save,w 01F8 0009 00447 retfie 00448 01F9 00449 rearm_ONt0 01F9 0828 00450 movfw pwmONt0 01FA 29F2 00451 goto rearm 01FB 00452 rearm_OFFt0 01FB 0829 00453 movfw pwmOFFt0 01FC 29F2 00454 goto rearm 00455 00456 ; Provide a return instruction for software delay timing 01FD 00457 emptyreturn 01FD 0008 00458 return 00459 00460 ; -------------------------- Main ESC code ---------------------- 00461 00462 ; 00463 ; Chip reset, or similar, operation. 01FE 00464 start MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 17 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00465 ; Calibrate the internal oscilator 01FE 1683 00466 bsf STATUS,RP0 01FF 23FF 00467 call 3FFh Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 0200 0090 00468 movwf OSCCAL 0201 1283 00469 bcf STATUS,RP0 00470 00471 ; Initialise PCLATH. WARNING: don't touch this register.... 0202 3001 00472 movlw int_refpoint >> 8 0203 008A 00473 movwf PCLATH 00474 00475 ; Default to output driven low when enabled 0204 0185 00476 clrf GPIO 00477 00478 ; Configure the weak pullups, and analog input bits, and the comparator that 00479 ; is used as an inverter, so that the control signal can control TMR1 00480 if comparitorinuse 00481 bsf STATUS,RP0 00482 movlw 10101000b 00483 movwf VRCON ; Select a 1/3 supply rail reference point 00484 bcf STATUS,RP0 00485 movlw 00000011b ; Comparitor with internal reference 00486 movwf CMCON 00487 endif 0205 1683 00488 bsf STATUS,RP0 0206 3030 00489 movlw 00110000b 00490 if comparitorinuse 00491 iorlw 1< 0 0207 3801 00494 iorlw 1< 0 020E 39FB 00506 andlw ~(1< 0 0214 3001 00518 movlw 00000001b | (voltsense << 2) 0215 009F 00519 movwf ADCON0 ; Enable the A/D converter 00520 endif 00521 00522 ; Initialise RAM 0216 01A2 00523 clrf escstatus 0217 3014 00524 movlw armpulse 0218 00A3 00525 movwf rearmcnt 00526 00527 ; Initialise throttle etc. 0219 01A5 00528 clrf throttle 00529 alloff 021A 01A7 M clrf pwmONio ; Turn off all FETs 021B 01A8 M clrf pwmONt0 ; interrupt every 532usec 021C 01A9 M clrf pwmOFFt0 ; interrupt every 532usec 021D 30E6 M movlw int_std - int_refpoint 021E 00A6 M movwf pwmmode ; Use the standard interrupt 00530 00531 ; Initialise the low voltage averaging 0000 00532 variable i 00000000 00533 i = 0 021F 30FF 00534 movlw 0FFh 00535 while i < (1< 0 00548 ; This is the fixed endpoint version, the arithmetic in this case 00549 ; is done by the assembler 00550 constant counts = PULSE_LO_HI / throttlesteps 00551 constant zerobase = 1500 - (counts * throttlesteps)/2 00552 00553 movlw counts 00554 movwf cntperth ; The width of each step MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 19 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00555 movlw low zerobase 00556 movwf cntthbl 00557 movlw high zerobase 00558 movwf cntthbh 00559 else 00560 ; The variable end point is more complex, we assume that what we are 00561 ; seeing originally is the 'min' setting and then we look for the largest 00562 ; pulse width and that is the 'max' setting. Then we calculate the 00563 ; constants we need. 00564 ; 00565 ; The algorithm is: 00566 ; Wait for ? consecutive pulses within ?us of each other, the smallest 00567 ; of these is the minimum position. 00568 ; 00569 ; Keep reading pulses and wait for ? pulses that are within ?us of each 00570 ; other. If they are > the minimum and > current max then remember this as 00571 ; the maximum. If the repetitive value is the zero throttle position the 00572 ; calculation is complete. 00573 ; 00574 cblock 0000003B 00575 autominl ; minimum pulse seen 0000003C 00576 autominh 0000003D 00577 automaxl ; maximum pulse seen 0000003E 00578 automaxh 00579 endc 00580 0225 00581 waitforset0 0225 22E5 00582 call getstablepulse 0226 1822 00583 btfsc escstatus, esc_LOS 0227 2A25 00584 goto waitforset0 ; Signal has gone away again... 00585 ; This is the zero point.... 0228 0843 00586 movfw stableh 0229 00BC 00587 movwf autominh 022A 00BE 00588 movwf automaxh 022B 0842 00589 movfw stablel 022C 00BB 00590 movwf autominl ; Remmember the minimum 00591 ; Calculate the assumed maximum point... 022D 3E40 00592 addlw throttlesteps 022E 00BD 00593 movwf automaxl 022F 1803 00594 btfsc STATUS,C 0230 0ABE 00595 incf automaxh,f 00596 00597 ; Wait for the throttle to move to at least automaxh... 0231 00598 waitforset1 0231 22E5 00599 call getstablepulse 0232 1822 00600 btfsc escstatus, esc_LOS 0233 2A31 00601 goto waitforset1 ; no signal, still hold low point 00602 ; See if we have reached this limit 0234 0842 00603 movfw stablel 0235 023D 00604 subwf automaxl,w 0236 0843 00605 movfw stableh 0237 1C03 00606 btfss STATUS,C 0238 3E01 00607 addlw 1 MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 20 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0239 023E 00608 subwf automaxh,w 023A 1803 00609 btfsc STATUS,C 023B 2A31 00610 goto waitforset1 ; not enough throttle yet... 00611 ; Recalculate the pulse -> throttle map using the supplied information 023C 00612 waitforset2 023C 0842 00613 movfw stablel 023D 00BD 00614 movwf automaxl 023E 0843 00615 movfw stableh 023F 00BE 00616 movwf automaxh 00617 0240 083B 00618 movfw autominl 0241 023D 00619 subwf automaxl,w 0242 00B3 00620 movwf math_al 0243 00AD 00621 movwf cntthbl 0244 083C 00622 movfw autominh 0245 1C03 00623 btfss STATUS,C 0246 3E01 00624 addlw 1 0247 023E 00625 subwf automaxh,w 0248 00B4 00626 movwf math_ah ; math_a:16 is the range 0249 00AE 00627 movwf cntthbh ; So is cntthb:16 00628 024A 3040 00629 movlw throttlesteps 024B 00B5 00630 movwf math_b ; Divide into steps 024C 2028 00631 call math_a_div_b 00632 024D 0836 00633 movfw math_rl 024E 00AC 00634 movwf cntperth ; That is all divided up... 00635 024F 00B3 00636 movwf math_al 0250 01B4 00637 clrf math_ah ; Multiply back up... 0251 2053 00638 call math_a_mul_b 00639 0252 0836 00640 movfw math_rl ; subtract from initial range 0253 02AD 00641 subwf cntthbl,f 0254 0837 00642 movfw math_rh 0255 1C03 00643 btfss STATUS,C 0256 3E01 00644 addlw 1 0257 02AE 00645 subwf cntthbh,f ; cntthb is now the 'spare' range 00646 0258 1003 00647 bcf STATUS,C 0259 0CAE 00648 rrf cntthbh,f 025A 0CAD 00649 rrf cntthbl,f ; Halve the space (some top, some bottom) 00650 025B 083B 00651 movfw autominl 025C 07AD 00652 addwf cntthbl,f 025D 083C 00653 movfw autominh 025E 1803 00654 btfsc STATUS,C 025F 3E01 00655 addlw 1 0260 07AE 00656 addwf cntthbh,f ; Assign the bottom cutoff 00657 00658 00659 ; Wait now and track the largest throttle we have seen, recompute the 00660 ; throttle mapping until we see zero throttle again..... MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 21 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0261 00661 waitforset3 0261 22E5 00662 call getstablepulse 0262 1822 00663 btfsc escstatus, esc_LOS 0263 2A61 00664 goto waitforset3 ; no signal, keep looking 00665 ; Is this bigger? 0264 083D 00666 movfw automaxl 0265 0242 00667 subwf stablel,w 0266 083E 00668 movfw automaxh 0267 1C03 00669 btfss STATUS,C 0268 3E01 00670 addlw 1 0269 0243 00671 subwf stableh,w 026A 1803 00672 btfsc STATUS,C 026B 2A3C 00673 goto waitforset2 ; new width 00674 ; no it is <=, so can we convert to a zero throttle? 026C 0842 00675 movfw stablel 026D 00B3 00676 movwf math_al 026E 0843 00677 movfw stableh 026F 00B4 00678 movwf math_ah 0270 2310 00679 call math_a_to_throttle 0271 3800 00680 iorlw 0 0272 1D03 00681 btfss STATUS,Z 0273 2A61 00682 goto waitforset3 00683 00684 ; Conversion parameters for pulse -> throttle have now been set. 00685 ; Make a sound with the motor to indicate all OK and ready, the 00686 ; motor is the only transducer we have... 00687 ; Make a two 0.25sec 800hz 'blips' 0.25 sec apart to signal all OK and armed. 00688 ; These blips are not enough to cause the motor to turn, but enough to 00689 ; make an audible sound. 00690 00691 ; Stop the interrupts 0274 178B 00692 bsf INTCON,GIE 00693 0275 22CB 00694 call sound_250 ; Sound for 250ms 0276 22D8 00695 call delay_250 0277 22CB 00696 call sound_250 00697 00698 ; Restart the interrupts 0278 178B 00699 bsf INTCON,GIE 00700 endif 00701 00702 ; Turn off all the drivers and wait for arming 0279 00703 offreset 0279 01A5 00704 clrf throttle ; Throttle is zero 027A 01A7 00705 clrf pwmONio ; All FETs off 027B 22BB 00706 call updatepwm ; Update the PWM engine 00707 00708 ; Initialise for arming state 027C 00709 resettoarm 027C 0823 00710 movfw rearmcnt 027D 00A4 00711 movwf armcnt 00712 00713 ; Wait for valid arming state MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 22 LOC OBJECT CODE LINE SOURCE TEXT VALUE 027E 00714 waitforarm 027E 2309 00715 call getthrottle 027F 1822 00716 btfsc escstatus, esc_LOS 0280 2A7C 00717 goto resettoarm ; Signal has gone away again... 0281 2068 00718 call g_pwmmode ; Convert to a PWM mode 0282 3C00 00719 sublw int_0on - int_refpoint ; check for idle position 0283 1D03 00720 btfss STATUS,Z 0284 2A7C 00721 goto resettoarm ; Throttle not idle 0285 0BA4 00722 decfsz armcnt,F 0286 2A7E 00723 goto waitforarm 00724 00725 ; Arming period has expired, adjust the rearm timer for next time 0287 3001 00726 movlw rearmpulse 0288 00A3 00727 movwf rearmcnt 00728 00729 ; The brake is now off, time to throttle up 0289 00730 usemotor 0289 01A7 00731 clrf pwmONio ; Turn off all FETs in interrupt code 028A 0185 00732 clrf GPIO ; Force FETs off anyway 00733 028B 01A5 00734 clrf throttle ; Set throttle to zero 028C 22BB 00735 call updatepwm ; And set the PWM system 00736 028D 3020 00737 movlw 1< 0 02A6 1D85 00784 btfss GPIO,brakeenb 02A7 2A8F 00785 goto running ; Ignore braking 00786 endif 00787 00788 ; 00789 ; The throttle is now at zero, and has been for the last 20ms or so 00790 ; start the brake... 02A8 3004 00791 movlw 1< 1 02B4 0A25 00812 incf throttle,w 02B5 3C3F 00813 sublw throttlesteps-1 02B6 1C03 00814 btfss STATUS,C 02B7 2AAD 00815 goto braking ; Throttle is already >= throttlesteps-1 02B8 0AA5 00816 incf throttle,f 02B9 22BB 00817 call updatepwm ; Apply more braking throttle 00818 endif 02BA 2AAD 00819 goto braking MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 24 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00820 endif 00821 00822 ; 00823 ; Update the PWM with the throttle setting, this code attempts to minimise the 00824 ; time that TMR0 is disabled. Currently this is 6uS, with any luck this is 00825 ; not going to disturb the PWM too much. 02BB 00826 updatepwm 02BB 0825 00827 movfw throttle 02BC 206A 00828 call g_pwmONt0 ; Locate the ON time 02BD 00AA 00829 movwf newpwmON 02BE 0825 00830 movfw throttle 02BF 206C 00831 call g_pwmOFFt0 ; And the OFF time 02C0 00AB 00832 movwf newpwmOFF 02C1 0825 00833 movfw throttle 02C2 2068 00834 call g_pwmmode ; And the PWM mode 00835 02C3 128B 00836 bcf INTCON, T0IE 02C4 00A6 00837 movwf pwmmode 02C5 082A 00838 movfw newpwmON 02C6 00A8 00839 movwf pwmONt0 02C7 082B 00840 movfw newpwmOFF 02C8 00A9 00841 movwf pwmOFFt0 02C9 168B 00842 bsf INTCON, T0IE 00843 02CA 0008 00844 return 00845 00846 if PULSE_LO_HI == 0 00847 ; This is the code used to produce 'armed' noises via the motor 00848 ; Local storage 00849 cblock 0000003F 00850 delaycnt1 ; Delay counters 00000040 00851 delaycnt2 00852 endc 00853 ; 00854 ; Sound 400hz via the motor for 250msec 02CB 00855 sound_250 02CB 30C8 00856 movlw 200 02CC 00BF 00857 movwf delaycnt1 02CD 00858 s250_1 02CD 3020 00859 movlw 1< 255 so must be at max 031E 3040 00990 movlw throttlesteps 031F 0236 00991 subwf math_rl,W 0320 1803 00992 btfsc STATUS,C 0321 343F 00993 retlw throttlesteps-1 ; throttle >= throttle steps so must be max 00994 ; Between 0 and throttlesteps-1 so just return it 0322 0836 00995 movfw math_rl 0323 0008 00996 return 00997 00998 ; 00999 ; This subrouting returns when a valid RX pulse is seen. 01000 ; The return value is in the TMR1 registers.... 01001 ; Note caller must check the sts_validrx prior to proceeding, valid signal 01002 ; may have stopped, or low voltage has occured - low voltage is treated 01003 ; as loss of signal for the purposes of this code. 01004 ; Return value is between 0300h (0.768msec) and 09ffh (2.559msec) and 01005 ; represents a 'valid' sort of pulse. 01006 ; 01007 ; Local data 01008 cblock 00000044 01009 loscntL ; LOS counter low 00000045 01010 loscntH ; LOS counter high 01011 endc 01012 0324 01013 getrxpulse 01014 ; Arm the LOS information 0324 1022 01015 bcf escstatus, esc_LOS 0325 3040 01016 movlw (losms * (1000/12+1)) & 0FFh 0326 00C4 01017 movwf loscntL 0327 301B 01018 movlw ((losms * (1000/12+1)) >> 8) + 1 0328 00C5 01019 movwf loscntH 0329 01020 pulselp 01021 ; Rearm the R/C pulse counter 0329 018E 01022 clrf TMR1L ; start at 0 032A 018F 01023 clrf TMR1H 01024 ; Enable Timer 1 for pulse width counting 032B 3041 01025 movlw 01000001b ; Enable 032C 0090 01026 movwf T1CON 01027 01028 ; While there is nothing to do just stay here and check for LOS .... 032D 01029 whileoff 032D 2351 01030 call checklos 032E 1822 01031 btfsc escstatus,esc_LOS MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 28 LOC OBJECT CODE LINE SOURCE TEXT VALUE 032F 3400 01032 retlw 0 0330 080E 01033 movfw TMR1L 0331 040F 01034 iorwf TMR1H,W ; Anything on the counter? 0332 1903 01035 btfsc STATUS,Z 0333 2B2D 01036 goto whileoff 01037 ; Trigger a A/D voltage check on the lowvolts signal when we see the start 01038 ; of a receiver pulse 01039 if LOWVOLTS > 0 0334 3003 01040 movlw 00000011b | (voltsense << 2) 0335 009F 01041 movwf ADCON0 ; Commence operation of the A/D 01042 endif 01043 ; Now wait for the pulse to end 0336 01044 whileon 0336 2351 01045 call checklos 0337 1822 01046 btfsc escstatus,esc_LOS 0338 3400 01047 retlw 0 0339 3009 01048 movlw 9 ; If counter >= 2.303 msec signal pulse is faulty 033A 020F 01049 subwf TMR1H,W 033B 1803 01050 btfsc STATUS,C 033C 2B4B 01051 goto toolong 033D 1E05 01052 btfss GPIO,inrxbit 033E 2B36 01053 goto whileon 01054 01055 ; Stop timer so we can convert things 033F 0190 01056 clrf T1CON 01057 01058 ; Check the A/D for low voltage... 01059 if LOWVOLTS > 0 0340 189F 01060 btfsc ADCON0,1 0341 2B56 01061 goto itislos ; No A/D completion, stop motor... 01062 ; Perform averaging if required, else just get the AD value 01063 if lowvavgln2 > 0 0342 2358 01064 call checklowv 01065 else 01066 movfw ADRESH 01067 endif 01068 ; Now consider the voltage... 0343 3C55 01069 sublw (LOWVOLTS * 10 / (10+27)) / (1000/(255/5)) 0344 1803 01070 btfsc STATUS,C 0345 2B56 01071 goto itislos ; Low voltage... 01072 endif 01073 01074 ; Now the pulse has ended and we are ready to consider the outcome of this... 01075 ; First drop pulses that are too small to be valid, these must be an error... 0346 3003 01076 movlw 3 0347 020F 01077 subwf TMR1H,W 0348 1C03 01078 btfss STATUS,C 0349 2B29 01079 goto pulselp ; < 0.768msec 034A 0008 01080 return 01081 01082 ; A pulse > 2.560msec is present, wait for it to end and ignore it 034B 01083 toolong 034B 2351 01084 call checklos MPASM 03.60 Released ESC.ASM 1-27-2004 22:26:49 PAGE 29 LOC OBJECT CODE LINE SOURCE TEXT VALUE 034C 1822 01085 btfsc escstatus,esc_LOS 034D 3400 01086 retlw 0 034E 1E05 01087 btfss GPIO,inrxbit 034F 2B4B 01088 goto toolong 0350 2B29 01089 goto pulselp 01090 01091 ; Watch for LOS, this routine is called about once every 12 cycles, 01092 ; or every 0.012msec and if 80msec expires then LOS is detected 01093 ; this requires a count of ~8000/12... 01094 ; 01095 ; Similarly the watchdog is cleared so that if the PIC doesn't get back to 01096 ; processing the next receiver pulse in 18msec the chip resets... 01097 ; 0351 01098 checklos 0351 0064 01099 clrwdt ; track software is working... 0352 0BC4 01100 decfsz loscntL,F 0353 0008 01101 return 0354 0BC5 01102 decfsz loscntH,F 0355 0008 01103 return 0356 01104 itislos 0356 1422 01105 bsf escstatus,esc_LOS ; Flag LOS 0357 0008 01106 return 01107 ; 01108 ; If low voltage averaging is active then compute and return the average 01109 if lowvavgln2 > 0 01110 cblock 00000046 01111 lvt_l ; Low Voltage Total LSB 00000047 01112 lvt_h ; Low Voltage Total MSB 01113 endc 01114 0358 01115 checklowv 01116 ; Shift down the averaging registers 00000003 01117 i = (1<= 1 0358 0831 01119 movfw lowvoltavg+i-1 0359 00B2 01120 movwf lowvoltavg+i 00000002 01121 i -= 1 035A 0830 01119 movfw lowvoltavg+i-1 035B 00B1 01120 movwf lowvoltavg+i 00000001 01121 i -= 1 035C 082F 01119 movfw lowvoltavg+i-1 035D 00B0 01120 movwf lowvoltavg+i 00000000 01121 i -= 1 01122 endw 01123 ; Grab the current A/D value and put it the the most recent slot 035E 081E 01124 movfw ADRESH 035F 00AF 01125 movwf lowvoltavg 01126 ; Add up all the values to form a total 0360 00C6 01127 movwf lvt_l 0361 01C7 01128 clrf lvt_h 00000001 01129 i = 1 01130 while i < (1<