MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 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 ; 00000000 00028 BRAKE equ 0 ; 0 for no brake, 1 for a hard, 2 for soft 00000000 00029 BRAKEENB equ 0 ; 0 for brake always on, 1 for GP3 control 00001770 00030 LOWVOLTS equ 6000 ; 6.5 Volt cutoff (.81V per cell - 8 cells) 00000000 00031 PULSE_LO_HI equ 0 ; auto throttle calibrate 00000001 00032 THROTTLEMAP equ 1 ; 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:22:22 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:22:22 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:22:22 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 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 00000001 00188 comparitorinuse equ 1 ; Comparitor is in use 00000001 00189 inrxraw equ 1 ; Active high receiver input 00000002 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 00195 comparitorinuse equ 0 ; Comparitor is not in use 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:22:22 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< 00001 ; Generated: Sat Dec 20 18:26:54 2003 MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 9 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00002 ; Using: throttle.pl 00003 ; Version: 1.4 00004 ; 00005 ; **** DO NOT EDIT THIS FILE BY HAND **** 00006 ; **** THIS IS COMPUTER GENERATED CODE **** 00007 ; 00008 ; mapthrottle = 1 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.000 0:512 0.000 @ 1953Hz 0:513 0.000 @ 1949Hz ( 0.00%) 00033 ; 2:0.031 -> 0.000 0:512 0.000 @ 1953Hz 0:513 0.000 @ 1949Hz ( 0.00%) 00034 ; 3:0.047 -> 0.048 6:128 0.045 @ 7462Hz 6:129 0.044 @ 7407Hz (-6.67%) 00035 ; 4:0.062 -> 0.063 8:128 0.059 @ 7352Hz 8:129 0.058 @ 7299Hz (-8.03%) 00036 ; 5:0.078 -> 0.079 11:128 0.079 @ 7194Hz 11:129 0.079 @ 7142Hz (-1.00%) 00037 ; 6:0.094 -> 0.095 13:128 0.092 @ 7092Hz 13:129 0.092 @ 7042Hz (-3.87%) 00038 ; 7:0.109 -> 0.111 16:128 0.111 @ 6944Hz 16:129 0.110 @ 6896Hz (-0.69%) 00039 ; 8:0.125 -> 0.127 18:128 0.123 @ 6849Hz 18:129 0.122 @ 6802Hz (-3.57%) 00040 ; 9:0.141 -> 0.143 21:128 0.141 @ 6711Hz 21:129 0.140 @ 6666Hz (-2.00%) 00041 ; 10:0.156 -> 0.159 24:128 0.158 @ 6578Hz 24:129 0.157 @ 6535Hz (-1.18%) 00042 ; 11:0.172 -> 0.175 27:128 0.174 @ 6451Hz 28:128 0.179 @ 6410Hz ( 2.80%) 00043 ; 12:0.188 -> 0.190 30:128 0.190 @ 6329Hz 30:128 0.190 @ 6329Hz (-0.32%) 00044 ; 13:0.203 -> 0.206 33:128 0.205 @ 6211Hz 34:128 0.210 @ 6172Hz ( 1.71%) 00045 ; 14:0.219 -> 0.222 36:128 0.220 @ 6097Hz 36:128 0.220 @ 6097Hz (-1.22%) 00046 ; 15:0.234 -> 0.238 40:128 0.238 @ 5952Hz 40:128 0.238 @ 5952Hz ( 0.00%) 00047 ; 16:0.250 -> 0.254 43:128 0.251 @ 5847Hz 44:128 0.256 @ 5813Hz ( 0.73%) 00048 ; 17:0.266 -> 0.270 47:128 0.269 @ 5714Hz 48:128 0.273 @ 5681Hz ( 1.07%) 00049 ; 18:0.281 -> 0.286 51:128 0.285 @ 5586Hz 52:128 0.289 @ 5555Hz ( 1.11%) 00050 ; 19:0.297 -> 0.302 55:128 0.301 @ 5464Hz 56:128 0.304 @ 5434Hz ( 0.92%) 00051 ; 20:0.312 -> 0.317 59:128 0.316 @ 5347Hz 60:128 0.319 @ 5319Hz ( 0.53%) 00052 ; 21:0.328 -> 0.333 63:128 0.330 @ 5235Hz 64:128 0.333 @ 5208Hz ( 0.00%) 00053 ; 22:0.344 -> 0.349 68:128 0.347 @ 5102Hz 68:128 0.347 @ 5102Hz (-0.65%) 00054 ; 23:0.359 -> 0.365 73:128 0.363 @ 4975Hz 74:128 0.366 @ 4950Hz ( 0.34%) MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 10 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00055 ; 24:0.375 -> 0.381 78:128 0.379 @ 4854Hz 78:128 0.379 @ 4854Hz (-0.61%) 00056 ; 25:0.391 -> 0.397 84:128 0.396 @ 4716Hz 84:128 0.396 @ 4716Hz (-0.15%) 00057 ; 26:0.406 -> 0.413 89:128 0.410 @ 4608Hz 90:128 0.413 @ 4587Hz ( 0.04%) 00058 ; 27:0.422 -> 0.429 96:128 0.429 @ 4464Hz 96:128 0.429 @ 4464Hz ( 0.00%) 00059 ; 28:0.438 -> 0.444 102:128 0.443 @ 4347Hz 102:128 0.443 @ 4347Hz (-0.22%) 00060 ; 29:0.453 -> 0.460 109:128 0.460 @ 4219Hz 110:128 0.462 @ 4201Hz ( 0.41%) 00061 ; 30:0.469 -> 0.476 116:128 0.475 @ 4098Hz 116:128 0.475 @ 4098Hz (-0.16%) 00062 ; 31:0.484 -> 0.492 124:128 0.492 @ 3968Hz 124:128 0.492 @ 3968Hz ( 0.00%) 00063 ; 32:0.500 -> 0.508 132:128 0.508 @ 3846Hz 132:128 0.508 @ 3846Hz (-0.05%) 00064 ; 33:0.516 -> 0.524 140:128 0.522 @ 3731Hz 140:128 0.522 @ 3731Hz (-0.27%) 00065 ; 34:0.531 -> 0.540 150:128 0.540 @ 3597Hz 150:128 0.540 @ 3597Hz (-0.02%) 00066 ; 35:0.547 -> 0.556 160:128 0.556 @ 3472Hz 160:128 0.556 @ 3472Hz ( 0.00%) 00067 ; 36:0.562 -> 0.571 170:128 0.570 @ 3355Hz 170:128 0.570 @ 3355Hz (-0.17%) 00068 ; 37:0.578 -> 0.587 182:128 0.587 @ 3225Hz 182:128 0.587 @ 3225Hz (-0.03%) 00069 ; 38:0.594 -> 0.603 194:128 0.602 @ 3105Hz 194:128 0.602 @ 3105Hz (-0.11%) 00070 ; 39:0.609 -> 0.619 208:128 0.619 @ 2976Hz 208:128 0.619 @ 2976Hz ( 0.00%) 00071 ; 40:0.625 -> 0.635 222:128 0.634 @ 2857Hz 222:128 0.634 @ 2857Hz (-0.10%) 00072 ; 41:0.641 -> 0.651 238:128 0.650 @ 2732Hz 238:128 0.650 @ 2732Hz (-0.08%) 00073 ; 42:0.656 -> 0.667 255:128 0.666 @ 2610Hz 256:128 0.667 @ 2604Hz ( 0.00%) 00074 ; 43:0.672 -> 0.683 275:128 0.682 @ 2481Hz 276:128 0.683 @ 2475Hz ( 0.09%) 00075 ; 44:0.688 -> 0.698 296:128 0.698 @ 2358Hz 296:128 0.698 @ 2358Hz (-0.04%) 00076 ; 45:0.703 -> 0.714 320:128 0.714 @ 2232Hz 320:128 0.714 @ 2232Hz ( 0.00%) 00077 ; 46:0.719 -> 0.730 346:128 0.730 @ 2109Hz 346:128 0.730 @ 2109Hz (-0.03%) 00078 ; 47:0.734 -> 0.746 376:128 0.746 @ 1984Hz 376:128 0.746 @ 1984Hz ( 0.00%) 00079 ; 48:0.750 -> 0.762 409:128 0.762 @ 1862Hz 410:128 0.762 @ 1858Hz ( 0.02%) 00080 ; 49:0.766 -> 0.778 448:128 0.778 @ 1736Hz 448:128 0.778 @ 1736Hz ( 0.00%) 00081 ; 50:0.781 -> 0.794 492:128 0.794 @ 1612Hz 492:128 0.794 @ 1612Hz (-0.01%) 00082 ; 51:0.797 -> 0.810 512:120 0.810 @ 1582Hz 512:120 0.810 @ 1582Hz ( 0.07%) 00083 ; 52:0.812 -> 0.825 512:108 0.826 @ 1612Hz 512:108 0.826 @ 1612Hz ( 0.05%) 00084 ; 53:0.828 -> 0.841 512: 96 0.842 @ 1644Hz 512: 96 0.842 @ 1644Hz ( 0.10%) 00085 ; 54:0.844 -> 0.857 512: 85 0.858 @ 1675Hz 512: 86 0.856 @ 1672Hz (-0.11%) 00086 ; 55:0.859 -> 0.873 512: 74 0.874 @ 1706Hz 512: 74 0.874 @ 1706Hz ( 0.08%) 00087 ; 56:0.875 -> 0.889 512: 64 0.889 @ 1736Hz 512: 64 0.889 @ 1736Hz ( 0.00%) 00088 ; 57:0.891 -> 0.905 512: 53 0.906 @ 1769Hz 512: 54 0.905 @ 1766Hz (-0.02%) 00089 ; 58:0.906 -> 0.921 512: 44 0.921 @ 1798Hz 512: 44 0.921 @ 1798Hz ( 0.02%) 00090 ; 59:0.922 -> 0.937 512: 34 0.938 @ 1831Hz 512: 34 0.938 @ 1831Hz ( 0.13%) 00091 ; 60:0.938 -> 0.952 512: 25 0.953 @ 1862Hz 512: 26 0.952 @ 1858Hz (-0.07%) 00092 ; 61:0.953 -> 0.968 512: 16 0.970 @ 1893Hz 513: 16 0.970 @ 1890Hz ( 0.15%) 00093 ; 62:0.969 -> 0.984 512: 8 0.985 @ 1923Hz 513: 8 0.985 @ 1919Hz ( 0.05%) 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 2A06 00100 goto rearm_OFFt0 0103 00101 int_6on 0103 0827 00102 movfw pwmONio 0104 0085 00103 movwf GPIO 0105 00104 int_on5off 00105 ; Delay 5 0105 2208 00106 call emptyreturn 0106 0000 00107 nop MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 11 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0107 0185 00108 clrf GPIO 0108 2A06 00109 goto rearm_OFFt0 0109 00110 int_8on 0109 0827 00111 movfw pwmONio 010A 0085 00112 movwf GPIO 010B 00113 int_on7off 010B 2905 00114 goto int_on5off 010C 00115 int_11on 010C 0827 00116 movfw pwmONio 010D 0085 00117 movwf GPIO 010E 00118 int_on10off 00119 ; Delay 1 010E 0000 00120 nop 010F 00121 int_on9off 010F 290B 00122 goto int_on7off 0110 00123 int_13on 0110 0827 00124 movfw pwmONio 0111 0085 00125 movwf GPIO 0112 00126 int_on12off 0112 290E 00127 goto int_on10off 0113 00128 int_16on 0113 0827 00129 movfw pwmONio 0114 0085 00130 movwf GPIO 0115 00131 int_on15off 00132 ; Delay 1 0115 0000 00133 nop 0116 00134 int_on14off 0116 2912 00135 goto int_on12off 0117 00136 int_18on 0117 0827 00137 movfw pwmONio 0118 0085 00138 movwf GPIO 0119 00139 int_on17off 0119 2915 00140 goto int_on15off 011A 00141 int_21on 011A 0827 00142 movfw pwmONio 011B 0085 00143 movwf GPIO 011C 00144 int_on20off 00145 ; Delay 1 011C 0000 00146 nop 011D 00147 int_on19off 011D 2919 00148 goto int_on17off 011E 00149 int_24on 011E 0827 00150 movfw pwmONio 011F 0085 00151 movwf GPIO 0120 00152 int_on23off 00153 ; Delay 1 0120 0000 00154 nop 0121 00155 int_on22off 0121 291C 00156 goto int_on20off 0122 00157 int_0off 0122 0827 00158 movfw pwmONio 0123 0085 00159 movwf GPIO 00160 ; Delay 0 MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 12 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0124 2A04 00161 goto rearm_ONt0 0125 00162 int_8off 0125 0000 00163 nop 0126 0185 00164 clrf GPIO 0127 00165 int_off6on 00166 ; Delay 6 0127 2208 00167 call emptyreturn 0128 2929 00168 goto $+1 0129 0827 00169 movfw pwmONio 012A 0085 00170 movwf GPIO 012B 2A04 00171 goto rearm_ONt0 012C 00172 int_16off 012C 0000 00173 nop 012D 0185 00174 clrf GPIO 012E 00175 int_off14on 00176 ; Delay 6 012E 2208 00177 call emptyreturn 012F 2930 00178 goto $+1 0130 00179 int_off8on 0130 2927 00180 goto int_off6on 00181 ; Ensure correct alignment of this table for a computed goto 00182 if ($ & ~0FFh) != (($+64-1) & ~0FFh) 00183 org ($+64) & ~0FFh 00184 endif 0131 00185 pwmtype_tbl 0131 3400 00186 retlw int_0on - int_refpoint 0132 3400 00187 retlw int_0on - int_refpoint 0133 3400 00188 retlw int_0on - int_refpoint 0134 3403 00189 retlw int_6on - int_refpoint 0135 3409 00190 retlw int_8on - int_refpoint 0136 340C 00191 retlw int_11on - int_refpoint 0137 3410 00192 retlw int_13on - int_refpoint 0138 3413 00193 retlw int_16on - int_refpoint 0139 3417 00194 retlw int_18on - int_refpoint 013A 341A 00195 retlw int_21on - int_refpoint 013B 341E 00196 retlw int_24on - int_refpoint 013C 34F1 00197 retlw int_std - int_refpoint 013D 34F1 00198 retlw int_std - int_refpoint 013E 34F1 00199 retlw int_std - int_refpoint 013F 34F1 00200 retlw int_std - int_refpoint 0140 34F1 00201 retlw int_std - int_refpoint 0141 34F1 00202 retlw int_std - int_refpoint 0142 34F1 00203 retlw int_std - int_refpoint 0143 34F1 00204 retlw int_std - int_refpoint 0144 34F1 00205 retlw int_std - int_refpoint 0145 34F1 00206 retlw int_std - int_refpoint 0146 34F1 00207 retlw int_std - int_refpoint 0147 34F1 00208 retlw int_std - int_refpoint 0148 34F1 00209 retlw int_std - int_refpoint 0149 34F1 00210 retlw int_std - int_refpoint 014A 34F1 00211 retlw int_std - int_refpoint 014B 34F1 00212 retlw int_std - int_refpoint 014C 34F1 00213 retlw int_std - int_refpoint MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 13 LOC OBJECT CODE LINE SOURCE TEXT VALUE 014D 34F1 00214 retlw int_std - int_refpoint 014E 34F1 00215 retlw int_std - int_refpoint 014F 34F1 00216 retlw int_std - int_refpoint 0150 34F1 00217 retlw int_std - int_refpoint 0151 34F1 00218 retlw int_std - int_refpoint 0152 34F1 00219 retlw int_std - int_refpoint 0153 34F1 00220 retlw int_std - int_refpoint 0154 34F1 00221 retlw int_std - int_refpoint 0155 34F1 00222 retlw int_std - int_refpoint 0156 34F1 00223 retlw int_std - int_refpoint 0157 34F1 00224 retlw int_std - int_refpoint 0158 34F1 00225 retlw int_std - int_refpoint 0159 34F1 00226 retlw int_std - int_refpoint 015A 34F1 00227 retlw int_std - int_refpoint 015B 34F1 00228 retlw int_std - int_refpoint 015C 34F1 00229 retlw int_std - int_refpoint 015D 34F1 00230 retlw int_std - int_refpoint 015E 34F1 00231 retlw int_std - int_refpoint 015F 34F1 00232 retlw int_std - int_refpoint 0160 34F1 00233 retlw int_std - int_refpoint 0161 34F1 00234 retlw int_std - int_refpoint 0162 34F1 00235 retlw int_std - int_refpoint 0163 34F1 00236 retlw int_std - int_refpoint 0164 34F1 00237 retlw int_std - int_refpoint 0165 34F1 00238 retlw int_std - int_refpoint 0166 34F1 00239 retlw int_std - int_refpoint 0167 34F1 00240 retlw int_std - int_refpoint 0168 34F1 00241 retlw int_std - int_refpoint 0169 34F1 00242 retlw int_std - int_refpoint 016A 34F1 00243 retlw int_std - int_refpoint 016B 34F1 00244 retlw int_std - int_refpoint 016C 34F1 00245 retlw int_std - int_refpoint 016D 34F1 00246 retlw int_std - int_refpoint 016E 342C 00247 retlw int_16off - int_refpoint 016F 3425 00248 retlw int_8off - int_refpoint 0170 3422 00249 retlw int_0off - int_refpoint 00250 ; Ensure correct alignment of this table for a computed goto 00251 if ($ & ~0FFh) != (($+64-1) & ~0FFh) 00252 org ($+64) & ~0FFh 00253 endif 0171 00254 pwmONt0_tbl 0171 3400 00255 retlw -0 0172 3400 00256 retlw -0 0173 3400 00257 retlw -0 0174 3400 00258 retlw -0 0175 3400 00259 retlw -0 0176 3400 00260 retlw -0 0177 3400 00261 retlw -0 0178 3400 00262 retlw -0 0179 3400 00263 retlw -0 017A 3400 00264 retlw -0 017B 3400 00265 retlw -0 017C 34FB 00266 retlw -5 MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 14 LOC OBJECT CODE LINE SOURCE TEXT VALUE 017D 34FA 00267 retlw -6 017E 34F8 00268 retlw -8 017F 34F7 00269 retlw -9 0180 34F5 00270 retlw -11 0181 34F3 00271 retlw -13 0182 34F1 00272 retlw -15 0183 34EF 00273 retlw -17 0184 34ED 00274 retlw -19 0185 34EB 00275 retlw -21 0186 34E9 00276 retlw -23 0187 34E7 00277 retlw -25 0188 34E4 00278 retlw -28 0189 34E2 00279 retlw -30 018A 34DF 00280 retlw -33 018B 34DC 00281 retlw -36 018C 34D9 00282 retlw -39 018D 34D6 00283 retlw -42 018E 34D2 00284 retlw -46 018F 34CF 00285 retlw -49 0190 34CB 00286 retlw -53 0191 34C7 00287 retlw -57 0192 34C3 00288 retlw -61 0193 34BE 00289 retlw -66 0194 34B9 00290 retlw -71 0195 34B4 00291 retlw -76 0196 34AE 00292 retlw -82 0197 34A8 00293 retlw -88 0198 34A1 00294 retlw -95 0199 349A 00295 retlw -102 019A 3492 00296 retlw -110 019B 3489 00297 retlw -119 019C 347F 00298 retlw -129 019D 3475 00299 retlw -139 019E 3469 00300 retlw -151 019F 345C 00301 retlw -164 01A0 344D 00302 retlw -179 01A1 343C 00303 retlw -196 01A2 3429 00304 retlw -215 01A3 3413 00305 retlw -237 01A4 3409 00306 retlw -247 01A5 3409 00307 retlw -247 01A6 3409 00308 retlw -247 01A7 3409 00309 retlw -247 01A8 3409 00310 retlw -247 01A9 3409 00311 retlw -247 01AA 3409 00312 retlw -247 01AB 3409 00313 retlw -247 01AC 3409 00314 retlw -247 01AD 3409 00315 retlw -247 01AE 3408 00316 retlw -248 01AF 3408 00317 retlw -248 01B0 3408 00318 retlw -248 00319 ; Ensure correct alignment of this table for a computed goto MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 15 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00320 if ($ & ~0FFh) != (($+64-1) & ~0FFh) 00321 org ($+64) & ~0FFh 00322 endif 01B1 00323 pwmOFFt0_tbl 01B1 3408 00324 retlw -248 01B2 3408 00325 retlw -248 01B3 3408 00326 retlw -248 01B4 34C8 00327 retlw -56 01B5 34C8 00328 retlw -56 01B6 34C8 00329 retlw -56 01B7 34C8 00330 retlw -56 01B8 34C8 00331 retlw -56 01B9 34C8 00332 retlw -56 01BA 34C8 00333 retlw -56 01BB 34C8 00334 retlw -56 01BC 34C9 00335 retlw -55 01BD 34C9 00336 retlw -55 01BE 34C9 00337 retlw -55 01BF 34C9 00338 retlw -55 01C0 34C9 00339 retlw -55 01C1 34C9 00340 retlw -55 01C2 34C9 00341 retlw -55 01C3 34C9 00342 retlw -55 01C4 34C9 00343 retlw -55 01C5 34C9 00344 retlw -55 01C6 34C9 00345 retlw -55 01C7 34C9 00346 retlw -55 01C8 34C9 00347 retlw -55 01C9 34C9 00348 retlw -55 01CA 34C9 00349 retlw -55 01CB 34C9 00350 retlw -55 01CC 34C9 00351 retlw -55 01CD 34C9 00352 retlw -55 01CE 34C9 00353 retlw -55 01CF 34C9 00354 retlw -55 01D0 34C9 00355 retlw -55 01D1 34C9 00356 retlw -55 01D2 34C9 00357 retlw -55 01D3 34C9 00358 retlw -55 01D4 34C9 00359 retlw -55 01D5 34C9 00360 retlw -55 01D6 34C9 00361 retlw -55 01D7 34C9 00362 retlw -55 01D8 34C9 00363 retlw -55 01D9 34C9 00364 retlw -55 01DA 34C9 00365 retlw -55 01DB 34C9 00366 retlw -55 01DC 34C9 00367 retlw -55 01DD 34C9 00368 retlw -55 01DE 34C9 00369 retlw -55 01DF 34C9 00370 retlw -55 01E0 34C9 00371 retlw -55 01E1 34C9 00372 retlw -55 MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 16 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01E2 34C9 00373 retlw -55 01E3 34C9 00374 retlw -55 01E4 34CD 00375 retlw -51 01E5 34D3 00376 retlw -45 01E6 34D9 00377 retlw -39 01E7 34DE 00378 retlw -34 01E8 34E4 00379 retlw -28 01E9 34E9 00380 retlw -23 01EA 34EE 00381 retlw -18 01EB 34F3 00382 retlw -13 01EC 34F8 00383 retlw -8 01ED 34FC 00384 retlw -4 01EE 3400 00385 retlw -0 01EF 3400 00386 retlw -0 01F0 3400 00387 retlw -0 00406 endif 00407 if THROTTLEMAP == 2 00408 #include 00409 endif 00410 00411 ; check that this entry point is 'within' the page 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. 01F1 00419 int_std 01F1 18A2 00420 btfsc escstatus,esc_pwmOFF 01F2 29F8 00421 goto in_pwmOFF 00422 ; We are currently in phaseA (on), so produce phaseB (off) 01F3 14A2 00423 bsf escstatus,esc_pwmOFF 01F4 0000 00424 nop 01F5 0185 00425 clrf GPIO 01F6 0829 00426 movfw pwmOFFt0 01F7 29FD 00427 goto rearm 00428 01F8 00429 in_pwmOFF 00430 ; We are currently in phaseB 01F8 0827 00431 movfw pwmONio 01F9 0085 00432 movwf GPIO 01FA 0828 00433 movfw pwmONt0 01FB 10A2 00434 bcf escstatus,esc_pwmOFF 01FC 0000 00435 nop 00436 01FD 00437 rearm 00438 ; Clear the timer interrupt, and reload counter 01FD 0081 00439 movwf TMR0 01FE 110B 00440 bcf INTCON, T0IF 00441 00442 ; All done, restore status 01FF 0E21 00443 swapf sts_save,w MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 17 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0200 0083 00444 movwf STATUS 0201 0EA0 00445 swapf w_save,f 0202 0E20 00446 swapf w_save,w 0203 0009 00447 retfie 00448 0204 00449 rearm_ONt0 0204 0828 00450 movfw pwmONt0 0205 29FD 00451 goto rearm 0206 00452 rearm_OFFt0 0206 0829 00453 movfw pwmOFFt0 0207 29FD 00454 goto rearm 00455 00456 ; Provide a return instruction for software delay timing 0208 00457 emptyreturn 0208 0008 00458 return 00459 00460 ; -------------------------- Main ESC code ---------------------- 00461 00462 ; 00463 ; Chip reset, or similar, operation. 0209 00464 start 00465 ; Calibrate the internal oscilator 0209 1683 00466 bsf STATUS,RP0 020A 23FF 00467 call 3FFh Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 020B 0090 00468 movwf OSCCAL 020C 1283 00469 bcf STATUS,RP0 00470 00471 ; Initialise PCLATH. WARNING: don't touch this register.... 020D 3001 00472 movlw int_refpoint >> 8 020E 008A 00473 movwf PCLATH 00474 00475 ; Default to output driven low when enabled 020F 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 0210 1683 00481 bsf STATUS,RP0 0211 30A8 00482 movlw 10101000b Message[302]: Register in operand not in bank 0. Ensure that bank bits are correct. 0212 0099 00483 movwf VRCON ; Select a 1/3 supply rail reference point 0213 1283 00484 bcf STATUS,RP0 0214 3003 00485 movlw 00000011b ; Comparitor with internal reference 0215 0099 00486 movwf CMCON 00487 endif 0216 1683 00488 bsf STATUS,RP0 0217 3030 00489 movlw 00110000b 00490 if comparitorinuse 0218 3802 00491 iorlw 1< 0 0219 3801 00494 iorlw 1< 0 00506 andlw ~(1< 0 0226 3001 00518 movlw 00000001b | (voltsense << 2) 0227 009F 00519 movwf ADCON0 ; Enable the A/D converter 00520 endif 00521 00522 ; Initialise RAM 0228 01A2 00523 clrf escstatus 0229 3014 00524 movlw armpulse 022A 00A3 00525 movwf rearmcnt 00526 00527 ; Initialise throttle etc. 022B 01A5 00528 clrf throttle 00529 alloff 022C 01A7 M clrf pwmONio ; Turn off all FETs 022D 01A8 M clrf pwmONt0 ; interrupt every 532usec 022E 01A9 M clrf pwmOFFt0 ; interrupt every 532usec 022F 30F1 M movlw int_std - int_refpoint 0230 00A6 M movwf pwmmode ; Use the standard interrupt 00530 00531 ; Initialise the low voltage averaging 0000 00532 variable i 00000000 00533 i = 0 0231 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 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 0237 00581 waitforset0 0237 22DF 00582 call getstablepulse 0238 1822 00583 btfsc escstatus, esc_LOS 0239 2A37 00584 goto waitforset0 ; Signal has gone away again... 00585 ; This is the zero point.... MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 20 LOC OBJECT CODE LINE SOURCE TEXT VALUE 023A 0843 00586 movfw stableh 023B 00BC 00587 movwf autominh 023C 00BE 00588 movwf automaxh 023D 0842 00589 movfw stablel 023E 00BB 00590 movwf autominl ; Remmember the minimum 00591 ; Calculate the assumed maximum point... 023F 3E40 00592 addlw throttlesteps 0240 00BD 00593 movwf automaxl 0241 1803 00594 btfsc STATUS,C 0242 0ABE 00595 incf automaxh,f 00596 00597 ; Wait for the throttle to move to at least automaxh... 0243 00598 waitforset1 0243 22DF 00599 call getstablepulse 0244 1822 00600 btfsc escstatus, esc_LOS 0245 2A43 00601 goto waitforset1 ; no signal, still hold low point 00602 ; See if we have reached this limit 0246 0842 00603 movfw stablel 0247 023D 00604 subwf automaxl,w 0248 0843 00605 movfw stableh 0249 1C03 00606 btfss STATUS,C 024A 3E01 00607 addlw 1 024B 023E 00608 subwf automaxh,w 024C 1803 00609 btfsc STATUS,C 024D 2A43 00610 goto waitforset1 ; not enough throttle yet... 00611 ; Recalculate the pulse -> throttle map using the supplied information 024E 00612 waitforset2 024E 0842 00613 movfw stablel 024F 00BD 00614 movwf automaxl 0250 0843 00615 movfw stableh 0251 00BE 00616 movwf automaxh 00617 0252 083B 00618 movfw autominl 0253 023D 00619 subwf automaxl,w 0254 00B3 00620 movwf math_al 0255 00AD 00621 movwf cntthbl 0256 083C 00622 movfw autominh 0257 1C03 00623 btfss STATUS,C 0258 3E01 00624 addlw 1 0259 023E 00625 subwf automaxh,w 025A 00B4 00626 movwf math_ah ; math_a:16 is the range 025B 00AE 00627 movwf cntthbh ; So is cntthb:16 00628 025C 3040 00629 movlw throttlesteps 025D 00B5 00630 movwf math_b ; Divide into steps 025E 2028 00631 call math_a_div_b 00632 025F 0836 00633 movfw math_rl 0260 00AC 00634 movwf cntperth ; That is all divided up... 00635 0261 00B3 00636 movwf math_al 0262 01B4 00637 clrf math_ah ; Multiply back up... 0263 2053 00638 call math_a_mul_b MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 21 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00639 0264 0836 00640 movfw math_rl ; subtract from initial range 0265 02AD 00641 subwf cntthbl,f 0266 0837 00642 movfw math_rh 0267 1C03 00643 btfss STATUS,C 0268 3E01 00644 addlw 1 0269 02AE 00645 subwf cntthbh,f ; cntthb is now the 'spare' range 00646 026A 1003 00647 bcf STATUS,C 026B 0CAE 00648 rrf cntthbh,f 026C 0CAD 00649 rrf cntthbl,f ; Halve the space (some top, some bottom) 00650 026D 083B 00651 movfw autominl 026E 07AD 00652 addwf cntthbl,f 026F 083C 00653 movfw autominh 0270 1803 00654 btfsc STATUS,C 0271 3E01 00655 addlw 1 0272 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..... 0273 00661 waitforset3 0273 22DF 00662 call getstablepulse 0274 1822 00663 btfsc escstatus, esc_LOS 0275 2A73 00664 goto waitforset3 ; no signal, keep looking 00665 ; Is this bigger? 0276 083D 00666 movfw automaxl 0277 0242 00667 subwf stablel,w 0278 083E 00668 movfw automaxh 0279 1C03 00669 btfss STATUS,C 027A 3E01 00670 addlw 1 027B 0243 00671 subwf stableh,w 027C 1803 00672 btfsc STATUS,C 027D 2A4E 00673 goto waitforset2 ; new width 00674 ; no it is <=, so can we convert to a zero throttle? 027E 0842 00675 movfw stablel 027F 00B3 00676 movwf math_al 0280 0843 00677 movfw stableh 0281 00B4 00678 movwf math_ah 0282 230A 00679 call math_a_to_throttle 0283 3800 00680 iorlw 0 0284 1D03 00681 btfss STATUS,Z 0285 2A73 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 MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 22 LOC OBJECT CODE LINE SOURCE TEXT VALUE 0286 178B 00692 bsf INTCON,GIE 00693 0287 22C5 00694 call sound_250 ; Sound for 250ms 0288 22D2 00695 call delay_250 0289 22C5 00696 call sound_250 00697 00698 ; Restart the interrupts 028A 178B 00699 bsf INTCON,GIE 00700 endif 00701 00702 ; Turn off all the drivers and wait for arming 028B 00703 offreset 028B 01A5 00704 clrf throttle ; Throttle is zero 028C 01A7 00705 clrf pwmONio ; All FETs off 028D 22B5 00706 call updatepwm ; Update the PWM engine 00707 00708 ; Initialise for arming state 028E 00709 resettoarm 028E 0823 00710 movfw rearmcnt 028F 00A4 00711 movwf armcnt 00712 00713 ; Wait for valid arming state 0290 00714 waitforarm 0290 2303 00715 call getthrottle 0291 1822 00716 btfsc escstatus, esc_LOS 0292 2A8E 00717 goto resettoarm ; Signal has gone away again... 0293 2068 00718 call g_pwmmode ; Convert to a PWM mode 0294 3C00 00719 sublw int_0on - int_refpoint ; check for idle position 0295 1D03 00720 btfss STATUS,Z 0296 2A8E 00721 goto resettoarm ; Throttle not idle 0297 0BA4 00722 decfsz armcnt,F 0298 2A90 00723 goto waitforarm 00724 00725 ; Arming period has expired, adjust the rearm timer for next time 0299 3001 00726 movlw rearmpulse 029A 00A3 00727 movwf rearmcnt 00728 00729 ; The brake is now off, time to throttle up 029B 00730 usemotor 029B 01A7 00731 clrf pwmONio ; Turn off all FETs in interrupt code 029C 0185 00732 clrf GPIO ; Force FETs off anyway 00733 029D 01A5 00734 clrf throttle ; Set throttle to zero 029E 22B5 00735 call updatepwm ; And set the PWM system 00736 029F 3020 00737 movlw 1< 0 00784 btfss GPIO,brakeenb 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... 00791 movlw 1< 1 00812 incf throttle,w 00813 sublw throttlesteps-1 00814 btfss STATUS,C 00815 goto braking ; Throttle is already >= throttlesteps-1 00816 incf throttle,f 00817 call updatepwm ; Apply more braking throttle 00818 endif 00819 goto braking 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. 02B5 00826 updatepwm 02B5 0825 00827 movfw throttle 02B6 206A 00828 call g_pwmONt0 ; Locate the ON time 02B7 00AA 00829 movwf newpwmON 02B8 0825 00830 movfw throttle 02B9 206C 00831 call g_pwmOFFt0 ; And the OFF time 02BA 00AB 00832 movwf newpwmOFF 02BB 0825 00833 movfw throttle 02BC 2068 00834 call g_pwmmode ; And the PWM mode 00835 02BD 128B 00836 bcf INTCON, T0IE 02BE 00A6 00837 movwf pwmmode 02BF 082A 00838 movfw newpwmON 02C0 00A8 00839 movwf pwmONt0 02C1 082B 00840 movfw newpwmOFF 02C2 00A9 00841 movwf pwmOFFt0 02C3 168B 00842 bsf INTCON, T0IE 00843 02C4 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 MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 25 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00000040 00851 delaycnt2 00852 endc 00853 ; 00854 ; Sound 400hz via the motor for 250msec 02C5 00855 sound_250 02C5 30C8 00856 movlw 200 02C6 00BF 00857 movwf delaycnt1 02C7 00858 s250_1 02C7 3020 00859 movlw 1< 255 so must be at max 0318 3040 00990 movlw throttlesteps 0319 0236 00991 subwf math_rl,W 031A 1803 00992 btfsc STATUS,C 031B 343F 00993 retlw throttlesteps-1 ; throttle >= throttle steps so must be max 00994 ; Between 0 and throttlesteps-1 so just return it 031C 0836 00995 movfw math_rl 031D 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 MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 28 LOC OBJECT CODE LINE SOURCE TEXT VALUE 00000045 01010 loscntH ; LOS counter high 01011 endc 01012 031E 01013 getrxpulse 01014 ; Arm the LOS information 031E 1022 01015 bcf escstatus, esc_LOS 031F 3040 01016 movlw (losms * (1000/12+1)) & 0FFh 0320 00C4 01017 movwf loscntL 0321 301B 01018 movlw ((losms * (1000/12+1)) >> 8) + 1 0322 00C5 01019 movwf loscntH 0323 01020 pulselp 01021 ; Rearm the R/C pulse counter 0323 018E 01022 clrf TMR1L ; start at 0 0324 018F 01023 clrf TMR1H 01024 ; Enable Timer 1 for pulse width counting 0325 3041 01025 movlw 01000001b ; Enable 0326 0090 01026 movwf T1CON 01027 01028 ; While there is nothing to do just stay here and check for LOS .... 0327 01029 whileoff 0327 234B 01030 call checklos 0328 1822 01031 btfsc escstatus,esc_LOS 0329 3400 01032 retlw 0 032A 080E 01033 movfw TMR1L 032B 040F 01034 iorwf TMR1H,W ; Anything on the counter? 032C 1903 01035 btfsc STATUS,Z 032D 2B27 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 032E 3003 01040 movlw 00000011b | (voltsense << 2) 032F 009F 01041 movwf ADCON0 ; Commence operation of the A/D 01042 endif 01043 ; Now wait for the pulse to end 0330 01044 whileon 0330 234B 01045 call checklos 0331 1822 01046 btfsc escstatus,esc_LOS 0332 3400 01047 retlw 0 0333 3009 01048 movlw 9 ; If counter >= 2.303 msec signal pulse is faulty 0334 020F 01049 subwf TMR1H,W 0335 1803 01050 btfsc STATUS,C 0336 2B45 01051 goto toolong 0337 1E05 01052 btfss GPIO,inrxbit 0338 2B30 01053 goto whileon 01054 01055 ; Stop timer so we can convert things 0339 0190 01056 clrf T1CON 01057 01058 ; Check the A/D for low voltage... 01059 if LOWVOLTS > 0 033A 189F 01060 btfsc ADCON0,1 033B 2B50 01061 goto itislos ; No A/D completion, stop motor... 01062 ; Perform averaging if required, else just get the AD value MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 29 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01063 if lowvavgln2 > 0 033C 2352 01064 call checklowv 01065 else 01066 movfw ADRESH 01067 endif 01068 ; Now consider the voltage... 033D 3C55 01069 sublw (LOWVOLTS * 10 / (10+27)) / (1000/(255/5)) 033E 1803 01070 btfsc STATUS,C 033F 2B50 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... 0340 3003 01076 movlw 3 0341 020F 01077 subwf TMR1H,W 0342 1C03 01078 btfss STATUS,C 0343 2B23 01079 goto pulselp ; < 0.768msec 0344 0008 01080 return 01081 01082 ; A pulse > 2.560msec is present, wait for it to end and ignore it 0345 01083 toolong 0345 234B 01084 call checklos 0346 1822 01085 btfsc escstatus,esc_LOS 0347 3400 01086 retlw 0 0348 1E05 01087 btfss GPIO,inrxbit 0349 2B45 01088 goto toolong 034A 2B23 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 ; 034B 01098 checklos 034B 0064 01099 clrwdt ; track software is working... 034C 0BC4 01100 decfsz loscntL,F 034D 0008 01101 return 034E 0BC5 01102 decfsz loscntH,F 034F 0008 01103 return 0350 01104 itislos 0350 1422 01105 bsf escstatus,esc_LOS ; Flag LOS 0351 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 0352 01115 checklowv MPASM 03.60 Released ESC.ASM 1-27-2004 22:22:22 PAGE 30 LOC OBJECT CODE LINE SOURCE TEXT VALUE 01116 ; Shift down the averaging registers 00000003 01117 i = (1<= 1 0352 0831 01119 movfw lowvoltavg+i-1 0353 00B2 01120 movwf lowvoltavg+i 00000002 01121 i -= 1 0354 0830 01119 movfw lowvoltavg+i-1 0355 00B1 01120 movwf lowvoltavg+i 00000001 01121 i -= 1 0356 082F 01119 movfw lowvoltavg+i-1 0357 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 0358 081E 01124 movfw ADRESH 0359 00AF 01125 movwf lowvoltavg 01126 ; Add up all the values to form a total 035A 00C6 01127 movwf lvt_l 035B 01C7 01128 clrf lvt_h 00000001 01129 i = 1 01130 while i < (1<