diff --git a/SiLabs/EMAX_BLHeli.a51 b/SiLabs/EMAX_BLHeli.a51 new file mode 100644 index 00000000..ade1090d --- /dev/null +++ b/SiLabs/EMAX_BLHeli.a51 @@ -0,0 +1,6848 @@ +$NOMOD51 +;**** **** **** **** **** +; +; BLHeli program for controlling brushless motors in helicopters +; +; Copyright 2011, 2012 Steffen Skaug +; This program is distributed under the terms of the GNU General Public License +; +; This file is part of BLHeli. +; +; BLHeli is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; BLHeli is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with BLHeli. If not, see . +; +;**** **** **** **** **** +; +; The software was initially designed for use with Eflite mCP X, but is now adapted to a copters/planes in general +; +; The software was inspired by and started from from Bernard Konze's BLMC: http://home.versanet.de/~bkonze/blc_6a/blc_6a.htm +; And also Simon Kirby's TGY: https://github.com/sim-/tgy +; +; This file is best viewed with tab width set to 5 +; +; The input signal can be positive 1kHz, 2kHz, 4kHz or 8kHz PWM (taken from the "resistor tap" on mCPx) +; And the input signal can be PPM (1-2ms) at rates up to several hundred Hz. +; The code adapts itself to the various input modes/frequencies +; The code ESC can also be programmed to accept inverted input signal. +; +; The first lines of the software must be modified according to the chosen environment: +; Uncomment the selected ESC and main/tail/multi mode +; BESC EQU "ESC"_"mode" +; +;**** **** **** **** **** +; Revision history: +; - Rev1.0: Initial revision based upon BLHeli for AVR controllers +; - Rev2.0: Changed "Eeprom" initialization, layout and defaults +; Various changes and improvements to comparator reading. Now using timer1 for time from pwm on/off +; Beeps are made louder +; Added programmable low voltage limit +; Added programmable damped tail mode (only for 1S ESCs) +; Added programmable motor rotation direction +; - Rev2.1: (minor changes by 4712) +; Added Disable TX Programming by PC Setup Application +; therfore changed EEPROM_LAYOUT_REVISION = 8 +; Added Vdd Monitor as reset source when writing to "EEProm" +; Changed for use of batch file to assemble, link and make hex files +; - Rev2.2: (minor changes by 4712) +; Added Disable Throttle Re-Arming every motor start by PC Setup Application +; - Rev2.3: (minor changes by 4712) +; Added bugfixed (2x CLR C before j(n)c operations)thx Steffen! +; - Rev2.4: Revisions 2.1 to 2.3 integrated +; - Rev3.0: Added PPM (1050us-1866us) as accepted input signal +; Added startup rpm as a programming parameter +; Added startup acceleration as a programming parameter +; Added option for using voltage measurements to compensate motor power +; Added governor target by setup as a governor mode option +; Governor is kept active regardless of rpm +; Smooth governor spoolup/down in arm and setup modes +; Increased governor P and I gain programming ranges +; Increased and changed low voltage limit programming range +; Disabled tx programming entry for all but the first arming sequence after power on +; Made it possible to skip parameters in tx programming by setting throttle midstick +; Made it default not to rearm for every restart +; - Rev3.1: Fixed bug that prevented chosen parameter to be set in tx programming +; - Rev3.2: ...also updated the EEPROM revision parameter +; - Rev3.3: Fixed negative number bug in voltage compensation +; Fixed bug in startup power calculation for non-default power +; Prevented possibility for voltage compensation fighting low voltage limiting +; Applied overall spoolup control to ensure soft spoolup in any mode +; Added a delay of 3 seconds from initiation of main motor stop until new startup is allowed +; Reduced beep power to reduce power consumption for very strong motors/ESCs +; - Rev3.4: Fixed bug that prevented full power in governor arm and setup modes +; Increased NFETON_DELAY for XP_7A and XP_12A to allow for more powerful fets +; Increased initial spoolup power, and linked to startup power +; - Rev4.0: Fixed bug that made tail tx program beeps very weak +; Added thermal protection feature +; Governor P and I gain ranges are extended up to 8.0x gain +; Startup sequence is aborted upon zero throttle +; Avoided voltage compensation function induced latency for tail when voltage compensation is not enabled +; Improved input signal frequency detection robustness +; - Rev4.1: Increased thermal protection temperature limits +; - Rev5.0: Added multi(copter) operating mode. TAIL define changed to MODE with three modes: MAIN, TAIL and MULTI +; Added programmable commutation timing +; Added a damped light mode that has less damping, but that can be used with all escs +; Added programmable damping force +; Added thermal protection for startup too +; Added wait beeps when waiting more than 30 sec for throttle above zero (after having been armed) +; Modified tail idling to provide option for very low speeds +; Changed PPM range to 1150-1830us +; Arming sequence is dropped for PPM input, unless it is governor arm mode +; Loss of input signal will immediately stop the motor for PPM input +; Bug corrected in Turnigy Plush 6A voltage measurement setup +; FET switching delays are set for original fets. Stronger/doubled/tripled etc fets may require faster pfet off switching +; Miscellaneous other changes +; - Rev6.0: Reverted comparator reading routine to rev5.0 equivalent, in order to avoid tail motor stops +; Added governor range programmability +; Implemented startup retry sequence with varying startup power for multi mode +; In damped light mode, damping is now applied to the active nfet phase for fully damped capable ESCs +; - Rev6.1: Added input signal qualification criteria for PPM, to avoid triggering on noise spikes (fix for plush hardware) +; Changed main and multi mode stop criteria. Will now be in run mode, even if RC pulse input is zero +; Fixed bug in commutation that caused rough running in damped light mode +; Miscellaneous other changes +; - Rev7.0 Added direct startup mode programmability +; Added throttle calibration. Min>=1000us and Max<=2000us. Difference must be >520us, otherwise max is shifted so that difference=520us +; Added programmable throttle change rate +; Added programmable beep strength, beacon strength and beacon delay +; Reduced power step to full power significantly +; Miscellaneous other changes +; - Rev8.0 Added a 2 second delay after power up, to wait for receiver initialization +; Added a programming option for disabling low voltage limit, and made it default for MULTI +; Added programable demag compensation, using the concept of SimonK +; Improved robustness against noisy input signal +; Refined direct startup +; Removed voltage compensation +; Miscellaneous other changes +; - Rev9.0 Increased programming range for startup power, and made it's default ESC dependent +; Made default startup method ESC dependent +; Even more smooth and gentle spoolup for MAIN, to suit larger helis +; Improved transition from stepped startup to run +; Refined direct startup +; - Rev9.1 Fixed bug that changed FW revision after throttle calibration or TX programming +; - Rev9.2 Altered timing of throttle calibration in order to work with MultiWii calibration firmware +; Reduced main spoolup time to around 5 seconds +; Changed default beacon delay to 3 minutes +; - Rev9.3 Fixed bug in Plush 60/80A temperature reading, that caused failure in operation above 4S +; Corrected temperature limit for HiModel cool 22/33/41A, RCTimer 6A, Skywalker 20/40A, Turnigy AE45A, Plush 40/60/80A. Limit was previously set too high +; - Rev9.4 Improved timing for increased maximum rpm limit +; - Rev10.0 Added closed loop mode for multi +; Added high/low BEC voltage option (for the ESCs where HW supports it) +; Added method of resetting all programmed parameter values to defaults by TX programming +; Added Turnigy K-force 40A and Turnigy K-force 120A HV ESCs +; Enabled fully damped mode for several ESCs +; Extended startup power range downwards to enable very smooth start for large heli main motors +; Extended damping force with a highest setting +; Corrected temperature limits for F310 chips (Plush 40A and AE 45A) +; Implemented temperature reading average in order to avoid problems with ADC noise on Skywalkers +; Increased switching delays for XP 7A fast, in order to avoid cross conduction of N and P fets +; Miscellaneous other changes +; - Rev10.1 Relaxed RC signal jitter requirement during frequency measurement +; Corrected bug that prevented using governor low +; Enabled vdd monitor always, in order to reduce likelihood of accidental overwriting of adjustments +; Fixed bug that caused stop for PPM input above 2048us, and moved upper accepted limit to 2160us +; - Rev10.2 Corrected temperature limit for AE20-30/XP7-25, where limit was too high +; Corrected temperature limit for 120HV, where limit was too low +; Fixed bug that caused AE20/25/30A not to run in reverse +; +; +;**** **** **** **** **** +; Up to 8K Bytes of In-System Self-Programmable Flash +; 768 Bytes Internal SRAM +; +;**** **** **** **** **** +; Master clock is internal 24MHz oscillator +; Timer 0 (167/500ns counts) always counts up and is used for +; - PWM generation +; Timer 1 (167/500ns counts) always counts up and is not used +; - Time from pwm on/off event +; Timer 2 (500ns counts) always counts up and is used for +; - RC pulse timeout/skip counts and commutation times +; Timer 3 (500ns counts) always counts up and is used for +; - Commutation timeouts +; PCA0 (500ns counts) always counts up and is used for +; - RC pulse measurement +; +;**** **** **** **** **** +; Interrupt handling +; The F330/2 does not disable interrupts when entering an interrupt routine. +; Also some interrupt flags need to be cleared by software +; The code disables interrupts in interrupt routines, in order to avoid nested interrupts +; - Interrupts are disabled during beeps, to avoid audible interference from interrupts +; - RC pulse interrupts are periodically disabled in order to reduce interference with pwm interrupts. +; +;**** **** **** **** **** +; Motor control: +; - Brushless motor control with 6 states for each electrical 360 degrees +; - An advance timing of 0deg has zero cross 30deg after one commutation and 30deg before the next +; - Timing advance in this implementation is set to 15deg nominally +; - "Damped" commutation schemes are available, where more than one pfet is on when pwm is off. This will absorb energy from bemf and make step settling more damped. +; Motor sequence starting from zero crossing: +; - Timer wait: Wt_Comm 15deg ; Time to wait from zero cross to actual commutation +; - Timer wait: Wt_Advance 15deg ; Time to wait for timing advance. Nominal commutation point is after this +; - Timer wait: Wt_Zc_Scan 7.5deg ; Time to wait before looking for zero cross +; - Scan for zero cross 22.5deg , Nominal, with some motor variations +; +; Motor startup in stepper mode: +; Initial motor rotations are done with the motor controlled as a stepper motor. +; In this stepper motor mode comparator information is not used. +; Settle phase is the first, where there are a few commutations with increasing step length, in order to settle the motor in a predefined position. +; Stepper phase comes next, where there is a step length decrease sequence. +; Direct startup is the last phase, for synchronization before normal bemf commutation run begins. +; Motor startup in direct mode: +; Direct startup is the only phase, before normal bemf commutation run begins. +; +;**** **** **** **** **** +; List of enumerated supported ESCs and modes (main, tail or multi) +XP_3A_Main EQU 1 +XP_3A_Tail EQU 2 +XP_3A_Multi EQU 3 +XP_7A_Main EQU 4 +XP_7A_Tail EQU 5 +XP_7A_Multi EQU 6 +XP_7A_Fast_Main EQU 7 +XP_7A_Fast_Tail EQU 8 +XP_7A_Fast_Multi EQU 9 +XP_12A_Main EQU 10 +XP_12A_Tail EQU 11 +XP_12A_Multi EQU 12 +XP_18A_Main EQU 13 +XP_18A_Tail EQU 14 +XP_18A_Multi EQU 15 +XP_25A_Main EQU 16 +XP_25A_Tail EQU 17 +XP_25A_Multi EQU 18 +DP_3A_Main EQU 19 +DP_3A_Tail EQU 20 +DP_3A_Multi EQU 21 +Supermicro_3p5A_Main EQU 22 +Supermicro_3p5A_Tail EQU 23 +Supermicro_3p5A_Multi EQU 24 +Turnigy_Plush_6A_Main EQU 25 +Turnigy_Plush_6A_Tail EQU 26 +Turnigy_Plush_6A_Multi EQU 27 +Turnigy_Plush_10A_Main EQU 28 +Turnigy_Plush_10A_Tail EQU 29 +Turnigy_Plush_10A_Multi EQU 30 +Turnigy_Plush_12A_Main EQU 31 +Turnigy_Plush_12A_Tail EQU 32 +Turnigy_Plush_12A_Multi EQU 33 +Turnigy_Plush_18A_Main EQU 34 +Turnigy_Plush_18A_Tail EQU 35 +Turnigy_Plush_18A_Multi EQU 36 +Turnigy_Plush_25A_Main EQU 37 +Turnigy_Plush_25A_Tail EQU 38 +Turnigy_Plush_25A_Multi EQU 39 +Turnigy_Plush_30A_Main EQU 40 +Turnigy_Plush_30A_Tail EQU 41 +Turnigy_Plush_30A_Multi EQU 42 +Turnigy_Plush_40A_Main EQU 43 +Turnigy_Plush_40A_Tail EQU 44 +Turnigy_Plush_40A_Multi EQU 45 +Turnigy_Plush_60A_Main EQU 46 +Turnigy_Plush_60A_Tail EQU 47 +Turnigy_Plush_60A_Multi EQU 48 +Turnigy_Plush_80A_Main EQU 49 +Turnigy_Plush_80A_Tail EQU 50 +Turnigy_Plush_80A_Multi EQU 51 +Turnigy_AE_20A_Main EQU 52 +Turnigy_AE_20A_Tail EQU 53 +Turnigy_AE_20A_Multi EQU 54 +Turnigy_AE_25A_Main EQU 55 +Turnigy_AE_25A_Tail EQU 56 +Turnigy_AE_25A_Multi EQU 57 +Turnigy_AE_30A_Main EQU 58 +Turnigy_AE_30A_Tail EQU 59 +Turnigy_AE_30A_Multi EQU 60 +Turnigy_AE_45A_Main EQU 61 +Turnigy_AE_45A_Tail EQU 62 +Turnigy_AE_45A_Multi EQU 63 +Turnigy_KForce_40A_Main EQU 64 +Turnigy_KForce_40A_Tail EQU 65 +Turnigy_KForce_40A_Multi EQU 66 +Turnigy_KForce_120A_HV_Main EQU 67 +Turnigy_KForce_120A_HV_Tail EQU 68 +Turnigy_KForce_120A_HV_Multi EQU 69 +Skywalker_20A_Main EQU 70 +Skywalker_20A_Tail EQU 71 +Skywalker_20A_Multi EQU 72 +Skywalker_40A_Main EQU 73 +Skywalker_40A_Tail EQU 74 +Skywalker_40A_Multi EQU 75 +HiModel_Cool_22A_Main EQU 76 +HiModel_Cool_22A_Tail EQU 77 +HiModel_Cool_22A_Multi EQU 78 +HiModel_Cool_33A_Main EQU 79 +HiModel_Cool_33A_Tail EQU 80 +HiModel_Cool_33A_Multi EQU 81 +HiModel_Cool_41A_Main EQU 82 +HiModel_Cool_41A_Tail EQU 83 +HiModel_Cool_41A_Multi EQU 84 +RCTimer_6A_Main EQU 85 +RCTimer_6A_Tail EQU 86 +RCTimer_6A_Multi EQU 87 +Align_RCE_BL15X_Main EQU 88 +Align_RCE_BL15X_Tail EQU 89 +Align_RCE_BL15X_Multi EQU 90 +Align_RCE_BL35X_Main EQU 91 +Align_RCE_BL35X_Tail EQU 92 +Align_RCE_BL35X_Multi EQU 93 +Align_RCE_BL35P_Main EQU 94 +Align_RCE_BL35P_Tail EQU 95 +Align_RCE_BL35P_Multi EQU 96 +H_King_10A_Main EQU 97 +H_King_10A_Tail EQU 98 +H_King_10A_Multi EQU 99 + +;**** **** **** **** **** +; Select the ESC and mode to use (or unselect all for use with external batch compile file) +;BESC EQU XP_3A_Main +;BESC EQU XP_3A_Tail +;BESC EQU XP_3A_Multi +;BESC EQU XP_7A_Main +;BESC EQU XP_7A_Tail +;BESC EQU XP_7A_Multi +;BESC EQU XP_7A_Fast_Main +;BESC EQU XP_7A_Fast_Tail +;BESC EQU XP_7A_Fast_Multi +;BESC EQU XP_12A_Main +;BESC EQU XP_12A_Tail +;BESC EQU XP_12A_Multi +;BESC EQU XP_18A_Main +;BESC EQU XP_18A_Tail +BESC EQU XP_18A_Multi +;BESC EQU XP_25A_Main +;BESC EQU XP_25A_Tail +;BESC EQU XP_25A_Multi +;BESC EQU DP_3A_Main +;BESC EQU DP_3A_Tail +;BESC EQU DP_3A_Multi +;BESC EQU Supermicro_3p5A_Main +;BESC EQU Supermicro_3p5A_Tail +;BESC EQU Supermicro_3p5A_Multi +;BESC EQU Turnigy_Plush_6A_Main +;BESC EQU Turnigy_Plush_6A_Tail +;BESC EQU Turnigy_Plush_6A_Multi +;BESC EQU Turnigy_Plush_10A_Main +;BESC EQU Turnigy_Plush_10A_Tail +;BESC EQU Turnigy_Plush_10A_Multi +;BESC EQU Turnigy_Plush_12A_Main +;BESC EQU Turnigy_Plush_12A_Tail +;BESC EQU Turnigy_Plush_12A_Multi +;BESC EQU Turnigy_Plush_18A_Main +;BESC EQU Turnigy_Plush_18A_Tail +;BESC EQU Turnigy_Plush_18A_Multi +;BESC EQU Turnigy_Plush_25A_Main +;BESC EQU Turnigy_Plush_25A_Tail +;BESC EQU Turnigy_Plush_25A_Multi +;BESC EQU Turnigy_Plush_30A_Main +;BESC EQU Turnigy_Plush_30A_Tail +;BESC EQU Turnigy_Plush_30A_Multi +;BESC EQU Turnigy_Plush_40A_Main +;BESC EQU Turnigy_Plush_40A_Tail +;BESC EQU Turnigy_Plush_40A_Multi +;BESC EQU Turnigy_Plush_60A_Main +;BESC EQU Turnigy_Plush_60A_Tail +;BESC EQU Turnigy_Plush_60A_Multi +;BESC EQU Turnigy_Plush_80A_Main +;BESC EQU Turnigy_Plush_80A_Tail +;BESC EQU Turnigy_Plush_80A_Multi +;BESC EQU Turnigy_AE_20A_Main +;BESC EQU Turnigy_AE_20A_Tail +;BESC EQU Turnigy_AE_20A_Multi +;BESC EQU Turnigy_AE_25A_Main +;BESC EQU Turnigy_AE_25A_Tail +;BESC EQU Turnigy_AE_25A_Multi +;BESC EQU Turnigy_AE_30A_Main +;BESC EQU Turnigy_AE_30A_Tail +;BESC EQU Turnigy_AE_30A_Multi +;BESC EQU Turnigy_AE_45A_Main +;BESC EQU Turnigy_AE_45A_Tail +;BESC EQU Turnigy_AE_45A_Multi +;BESC EQU Turnigy_KForce_40A_Main +;BESC EQU Turnigy_KForce_40A_Tail +;BESC EQU Turnigy_KForce_40A_Multi +;BESC EQU Turnigy_KForce_120A_HV_Main +;BESC EQU Turnigy_KForce_120A_HV_Tail +;BESC EQU Turnigy_KForce_120A_HV_Multi +;BESC EQU Skywalker_20A_Main +;BESC EQU Skywalker_20A_Tail +;BESC EQU Skywalker_20A_Multi +;BESC EQU Skywalker_40A_Main +;BESC EQU Skywalker_40A_Tail +;BESC EQU Skywalker_40A_Multi +;BESC EQU HiModel_Cool_22A_Main +;BESC EQU HiModel_Cool_22A_Tail +;BESC EQU HiModel_Cool_22A_Multi +;BESC EQU HiModel_Cool_33A_Main +;BESC EQU HiModel_Cool_33A_Tail +;BESC EQU HiModel_Cool_33A_Multi +;BESC EQU HiModel_Cool_41A_Main +;BESC EQU HiModel_Cool_41A_Tail +;BESC EQU HiModel_Cool_41A_Multi +;BESC EQU RCTimer_6A_Main +;BESC EQU RCTimer_6A_Tail +;BESC EQU RCTimer_6A_Multi +;BESC EQU Align_RCE_BL15X_Main +;BESC EQU Align_RCE_BL15X_Tail +;BESC EQU Align_RCE_BL15X_Multi +;BESC EQU Align_RCE_BL35X_Main +;BESC EQU Align_RCE_BL35X_Tail +;BESC EQU Align_RCE_BL35X_Multi +;BESC EQU Align_RCE_BL35P_Main +;BESC EQU Align_RCE_BL35P_Tail +;BESC EQU Align_RCE_BL35P_Multi +;BESC EQU H_King_10A_Main +;BESC EQU H_King_10A_Tail +;BESC EQU H_King_10A_Multi + + +;**** **** **** **** **** +; ESC selection statements +IF BESC == XP_3A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (XP_3A.inc) ; Select XP 3A pinout +ENDIF + +IF BESC == XP_3A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (XP_3A.inc) ; Select XP 3A pinout +ENDIF + +IF BESC == XP_3A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (XP_3A.inc) ; Select XP 3A pinout +ENDIF + +IF BESC == XP_7A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (XP_7A.inc) ; Select XP 7A pinout +ENDIF + +IF BESC == XP_7A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (XP_7A.inc) ; Select XP 7A pinout +ENDIF + +IF BESC == XP_7A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (XP_7A.inc) ; Select XP 7A pinout +ENDIF + +IF BESC == XP_7A_Fast_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (XP_7A_Fast.inc) ; Select XP 7A Fast pinout +ENDIF + +IF BESC == XP_7A_Fast_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (XP_7A_Fast.inc) ; Select XP 7A Fast pinout +ENDIF + +IF BESC == XP_7A_Fast_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (XP_7A_Fast.inc) ; Select XP 7A Fast pinout +ENDIF + +IF BESC == XP_12A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (XP_12A.inc) ; Select XP 12A pinout +ENDIF + +IF BESC == XP_12A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (XP_12A.inc) ; Select XP 12A pinout +ENDIF + +IF BESC == XP_12A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (XP_12A.inc) ; Select XP 12A pinout +ENDIF + +IF BESC == XP_18A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (XP_18A.inc) ; Select XP 18A pinout +ENDIF + +IF BESC == XP_18A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (XP_18A.inc) ; Select XP 18A pinout +ENDIF + +IF BESC == XP_18A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (XP_18A.inc) ; Select XP 18A pinout +ENDIF + +IF BESC == XP_25A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (XP_25A.inc) ; Select XP 25A pinout +ENDIF + +IF BESC == XP_25A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (XP_25A.inc) ; Select XP 25A pinout +ENDIF + +IF BESC == XP_25A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (XP_25A.inc) ; Select XP 25A pinout +ENDIF + +IF BESC == DP_3A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (DP_3A.inc) ; Select DP 3A pinout +ENDIF + +IF BESC == DP_3A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (DP_3A.inc) ; Select DP 3A pinout +ENDIF + +IF BESC == DP_3A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (DP_3A.inc) ; Select DP 3A pinout +ENDIF + +IF BESC == Supermicro_3p5A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Supermicro_3p5A.inc) ; Select Supermicro 3.5A pinout +ENDIF + +IF BESC == Supermicro_3p5A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Supermicro_3p5A.inc) ; Select Supermicro 3.5A pinout +ENDIF + +IF BESC == Supermicro_3p5A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Supermicro_3p5A.inc) ; Select Supermicro 3.5A pinout +ENDIF + +IF BESC == Turnigy_Plush_6A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_6A.inc) ; Select Turnigy Plush 6A pinout +ENDIF + +IF BESC == Turnigy_Plush_6A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_6A.inc) ; Select Turnigy Plush 6A pinout +ENDIF + +IF BESC == Turnigy_Plush_6A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_6A.inc) ; Select Turnigy Plush 6A pinout +ENDIF + +IF BESC == Turnigy_Plush_10A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_10A.inc) ; Select Turnigy Plush 10A pinout +ENDIF + +IF BESC == Turnigy_Plush_10A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_10A.inc) ; Select Turnigy Plush 10A pinout +ENDIF + +IF BESC == Turnigy_Plush_10A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_10A.inc) ; Select Turnigy Plush 10A pinout +ENDIF + +IF BESC == Turnigy_Plush_12A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_12A.inc) ; Select Turnigy Plush 12A pinout +ENDIF + +IF BESC == Turnigy_Plush_12A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_12A.inc) ; Select Turnigy Plush 12A pinout +ENDIF + +IF BESC == Turnigy_Plush_12A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_12A.inc) ; Select Turnigy Plush 12A pinout +ENDIF + +IF BESC == Turnigy_Plush_18A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_18A.inc) ; Select Turnigy Plush 18A pinout +ENDIF + +IF BESC == Turnigy_Plush_18A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_18A.inc) ; Select Turnigy Plush 18A pinout +ENDIF + +IF BESC == Turnigy_Plush_18A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_18A.inc) ; Select Turnigy Plush 18A pinout +ENDIF + +IF BESC == Turnigy_Plush_25A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_25A.inc) ; Select Turnigy Plush 25A pinout +ENDIF + +IF BESC == Turnigy_Plush_25A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_25A.inc) ; Select Turnigy Plush 25A pinout +ENDIF + +IF BESC == Turnigy_Plush_25A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_25A.inc) ; Select Turnigy Plush 25A pinout +ENDIF + +IF BESC == Turnigy_Plush_30A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_30A.inc) ; Select Turnigy Plush 30A pinout +ENDIF + +IF BESC == Turnigy_Plush_30A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_30A.inc) ; Select Turnigy Plush 30A pinout +ENDIF + +IF BESC == Turnigy_Plush_30A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_30A.inc) ; Select Turnigy Plush 30A pinout +ENDIF + +IF BESC == Turnigy_Plush_40A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_40A.inc) ; Select Turnigy Plush 40A pinout +ENDIF + +IF BESC == Turnigy_Plush_40A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_40A.inc) ; Select Turnigy Plush 40A pinout +ENDIF + +IF BESC == Turnigy_Plush_40A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_40A.inc) ; Select Turnigy Plush 40A pinout +ENDIF + +IF BESC == Turnigy_Plush_60A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_60A.inc) ; Select Turnigy Plush 60A pinout +ENDIF + +IF BESC == Turnigy_Plush_60A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_60A.inc) ; Select Turnigy Plush 60A pinout +ENDIF + +IF BESC == Turnigy_Plush_60A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_60A.inc) ; Select Turnigy Plush 60A pinout +ENDIF + +IF BESC == Turnigy_Plush_80A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_Plush_80A.inc) ; Select Turnigy Plush 80A pinout +ENDIF + +IF BESC == Turnigy_Plush_80A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_Plush_80A.inc) ; Select Turnigy Plush 80A pinout +ENDIF + +IF BESC == Turnigy_Plush_80A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_Plush_80A.inc) ; Select Turnigy Plush 80A pinout +ENDIF + +IF BESC == Turnigy_AE_20A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_AE_20A.inc) ; Select Turnigy AE-20A pinout +ENDIF + +IF BESC == Turnigy_AE_20A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_AE_20A.inc) ; Select Turnigy AE-20A pinout +ENDIF + +IF BESC == Turnigy_AE_20A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_AE_20A.inc) ; Select Turnigy AE-20A pinout +ENDIF + +IF BESC == Turnigy_AE_25A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_AE_25A.inc) ; Select Turnigy AE-25A pinout +ENDIF + +IF BESC == Turnigy_AE_25A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_AE_25A.inc) ; Select Turnigy AE-25A pinout +ENDIF + +IF BESC == Turnigy_AE_25A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_AE_25A.inc) ; Select Turnigy AE-25A pinout +ENDIF + +IF BESC == Turnigy_AE_30A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_AE_30A.inc) ; Select Turnigy AE-30A pinout +ENDIF + +IF BESC == Turnigy_AE_30A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_AE_30A.inc) ; Select Turnigy AE-30A pinout +ENDIF + +IF BESC == Turnigy_AE_30A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_AE_30A.inc) ; Select Turnigy AE-30A pinout +ENDIF + +IF BESC == Turnigy_AE_45A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_AE_45A.inc) ; Select Turnigy AE-45A pinout +ENDIF + +IF BESC == Turnigy_AE_45A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_AE_45A.inc) ; Select Turnigy AE-45A pinout +ENDIF + +IF BESC == Turnigy_AE_45A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_AE_45A.inc) ; Select Turnigy AE-45A pinout +ENDIF + +IF BESC == Turnigy_KForce_40A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_KForce_40A.inc) ; Select Turnigy KForce 40A pinout +ENDIF + +IF BESC == Turnigy_KForce_40A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_KForce_40A.inc) ; Select Turnigy KForce 40A pinout +ENDIF + +IF BESC == Turnigy_KForce_40A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_KForce_40A.inc) ; Select Turnigy KForce 40A pinout +ENDIF + +IF BESC == Turnigy_KForce_120A_HV_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Turnigy_KForce_120A_HV.inc) ; Select Turnigy KForce 120A HV pinout +ENDIF + +IF BESC == Turnigy_KForce_120A_HV_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Turnigy_KForce_120A_HV.inc) ; Select Turnigy KForce 120A HV pinout +ENDIF + +IF BESC == Turnigy_KForce_120A_HV_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Turnigy_KForce_120A_HV.inc) ; Select Turnigy KForce 120A HV pinout +ENDIF + +IF BESC == Skywalker_20A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Skywalker_20A.inc) ; Select Skywalker 20A pinout +ENDIF + +IF BESC == Skywalker_20A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Skywalker_20A.inc) ; Select Skywalker 20A pinout +ENDIF + +IF BESC == Skywalker_20A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Skywalker_20A.inc) ; Select Skywalker 20A pinout +ENDIF + +IF BESC == Skywalker_40A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Skywalker_40A.inc) ; Select Skywalker 40A pinout +ENDIF + +IF BESC == Skywalker_40A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Skywalker_40A.inc) ; Select Skywalker 40A pinout +ENDIF + +IF BESC == Skywalker_40A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Skywalker_40A.inc) ; Select Skywalker 40A pinout +ENDIF + +IF BESC == HiModel_Cool_22A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (HiModel_Cool_22A.inc) ; Select HiModel Cool 22A pinout +ENDIF + +IF BESC == HiModel_Cool_22A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (HiModel_Cool_22A.inc) ; Select HiModel Cool 22A pinout +ENDIF + +IF BESC == HiModel_Cool_22A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (HiModel_Cool_22A.inc) ; Select HiModel Cool 22A pinout +ENDIF + +IF BESC == HiModel_Cool_33A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (HiModel_Cool_33A.inc) ; Select HiModel Cool 33A pinout +ENDIF + +IF BESC == HiModel_Cool_33A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (HiModel_Cool_33A.inc) ; Select HiModel Cool 33A pinout +ENDIF + +IF BESC == HiModel_Cool_33A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (HiModel_Cool_33A.inc) ; Select HiModel Cool 33A pinout +ENDIF + +IF BESC == HiModel_Cool_41A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (HiModel_Cool_41A.inc) ; Select HiModel Cool 41A pinout +ENDIF + +IF BESC == HiModel_Cool_41A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (HiModel_Cool_41A.inc) ; Select HiModel Cool 41A pinout +ENDIF + +IF BESC == HiModel_Cool_41A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (HiModel_Cool_41A.inc) ; Select HiModel Cool 41A pinout +ENDIF + +IF BESC == RCTimer_6A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (RCTimer_6A.inc) ; Select RC Timer 6A pinout +ENDIF + +IF BESC == RCTimer_6A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (RCTimer_6A.inc) ; Select RC Timer 6A pinout +ENDIF + +IF BESC == RCTimer_6A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (RCTimer_6A.inc) ; Select RC Timer 6A pinout +ENDIF + +IF BESC == Align_RCE_BL15X_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Align_RCE_BL15X.inc) ; Select Align RCE-BL15X pinout +ENDIF + +IF BESC == Align_RCE_BL15X_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Align_RCE_BL15X.inc) ; Select Align RCE-BL15X pinout +ENDIF + +IF BESC == Align_RCE_BL15X_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Align_RCE_BL15X.inc) ; Select Align RCE-BL15X pinout +ENDIF + +IF BESC == Align_RCE_BL35X_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Align_RCE_BL35X.inc) ; Select Align RCE-BL35X pinout +ENDIF + +IF BESC == Align_RCE_BL35X_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Align_RCE_BL35X.inc) ; Select Align RCE-BL35X pinout +ENDIF + +IF BESC == Align_RCE_BL35X_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Align_RCE_BL35X.inc) ; Select Align RCE-BL35X pinout +ENDIF + +IF BESC == Align_RCE_BL35P_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (Align_RCE_BL35P.inc) ; Select Align RCE-BL35P pinout +ENDIF + +IF BESC == Align_RCE_BL35P_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (Align_RCE_BL35P.inc) ; Select Align RCE-BL35P pinout +ENDIF + +IF BESC == Align_RCE_BL35P_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (Align_RCE_BL35P.inc) ; Select Align RCE-BL35P pinout +ENDIF + +IF BESC == H_King_10A_Main +MODE EQU 0 ; Choose mode. Set to 0 for main motor +$include (H_King_10A.inc) ; Select H-King 10A pinout +ENDIF + +IF BESC == H_King_10A_Tail +MODE EQU 1 ; Choose mode. Set to 1 for tail motor +$include (H_King_10A.inc) ; Select H-King 10A pinout +ENDIF + +IF BESC == H_King_10A_Multi +MODE EQU 2 ; Choose mode. Set to 2 for multirotor +$include (H_King_10A.inc) ; Select H-King 10A pinout +ENDIF + +;**** **** **** **** **** +; TX programming defaults +; +; Parameter dependencies: +; - Governor P gain, I gain and Range is only used if one of the three governor modes is selected +; - Governor setup target is only used if Setup governor mode is selected (or closed loop mode is on for multi) +; - Startup rpm and startup accel is only used if stepped startup method is selected +; - Damping force is only used if DampedLight or Damped is selected +; +; Main +DEFAULT_PGM_MAIN_P_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0 +DEFAULT_PGM_MAIN_I_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0 +DEFAULT_PGM_MAIN_GOVERNOR_MODE EQU 1 ; 1=Tx 2=Arm 3=Setup 4=Off +DEFAULT_PGM_MAIN_GOVERNOR_RANGE EQU 1 ; 1=High 2=Low +DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM EQU 4 ; 1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c +DEFAULT_PGM_MAIN_STARTUP_RPM EQU 3 ; 1=0.67 2=0.8 3=1.00 4=1.25 5=1.5 +DEFAULT_PGM_MAIN_STARTUP_ACCEL EQU 1 ; 1=0.4 2=0.7 3=1.0 4=1.5 5=2.3 +DEFAULT_PGM_MAIN_COMM_TIMING EQU 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +DEFAULT_PGM_MAIN_THROTTLE_RATE EQU 13 ; 1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255 +DEFAULT_PGM_MAIN_DAMPING_FORCE EQU 1 ; 1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest +DEFAULT_PGM_MAIN_PWM_FREQ EQU 2 ; 1=High 2=Low 3=DampedLight +DEFAULT_PGM_MAIN_DEMAG_COMP EQU 1 ; 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off) +DEFAULT_PGM_MAIN_DIRECTION_REV EQU 1 ; 1=Normal 2=Reversed +DEFAULT_PGM_MAIN_RCP_PWM_POL EQU 1 ; 1=Positive 2=Negative +DEFAULT_PGM_MAIN_GOV_SETUP_TARGET EQU 180 ; Target for governor in setup mode. Corresponds to 70% throttle +DEFAULT_PGM_MAIN_REARM_START EQU 0 ; 1=Enabled 0=Disabled +DEFAULT_PGM_MAIN_BEEP_STRENGTH EQU 80 ; Beep strength +DEFAULT_PGM_MAIN_BEACON_STRENGTH EQU 100 ; Beacon strength +DEFAULT_PGM_MAIN_BEACON_DELAY EQU 2 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite +; Tail +DEFAULT_PGM_TAIL_GAIN EQU 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25 +DEFAULT_PGM_TAIL_IDLE_SPEED EQU 4 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +DEFAULT_PGM_TAIL_STARTUP_RPM EQU 3 ; 1=0.67 2=0.8 3=1.00 4=1.25 5=1.5 +DEFAULT_PGM_TAIL_STARTUP_ACCEL EQU 5 ; 1=0.4 2=0.7 3=1.0 4=1.5 5=2.3 +DEFAULT_PGM_TAIL_COMM_TIMING EQU 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +DEFAULT_PGM_TAIL_THROTTLE_RATE EQU 13 ; 1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255 +DEFAULT_PGM_TAIL_DAMPING_FORCE EQU 5 ; 1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest +IF DAMPED_MODE_ENABLE == 1 +DEFAULT_PGM_TAIL_PWM_FREQ EQU 1 ; 1=High 2=Low 3=DampedLight 4=Damped +ELSE +DEFAULT_PGM_TAIL_PWM_FREQ EQU 1 ; 1=High 2=Low 3=DampedLight +ENDIF +DEFAULT_PGM_TAIL_DEMAG_COMP EQU 1 ; 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off) +DEFAULT_PGM_TAIL_DIRECTION_REV EQU 1 ; 1=Normal 2=Reversed +DEFAULT_PGM_TAIL_RCP_PWM_POL EQU 1 ; 1=Positive 2=Negative +DEFAULT_PGM_TAIL_BEEP_STRENGTH EQU 250 ; Beep strength +DEFAULT_PGM_TAIL_BEACON_STRENGTH EQU 250 ; Beacon strength +DEFAULT_PGM_TAIL_BEACON_DELAY EQU 4 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite +; Multi +DEFAULT_PGM_MULTI_FIRST_KEYWORD EQU 66h ;增加首个关键字 2013.8.27 +DEFAULT_PGM_MULTI_P_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0 +DEFAULT_PGM_MULTI_I_GAIN EQU 9 ; 1=0.13 2=0.17 3=0.25 4=0.38 5=0.50 6=0.75 7=1.00 8=1.5 9=2.0 10=3.0 11=4.0 12=6.0 13=8.0 +DEFAULT_PGM_MULTI_GOVERNOR_MODE EQU 1 ; 1=Off 2=LoRange 3=MidRange 4=HiRange +DEFAULT_PGM_MULTI_GAIN EQU 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25 +DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM EQU 2 +;DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM EQU 1 ; 1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c +DEFAULT_PGM_MULTI_LOW_VOLTAGE_CTL EQU 1 ;增加低压保护控制方式默认值 1=功率逐渐降到31% 2=关闭输出 +DEFAULT_PGM_MULTI_STARTUP_RPM EQU 1 ; 1=0.67 2=0.8 3=1.00 4=1.25 5=1.5 +DEFAULT_PGM_MULTI_STARTUP_ACCEL EQU 5 ; 1=0.4 2=0.7 3=1.0 4=1.5 5=2.3 +DEFAULT_PGM_MULTI_COMM_TIMING EQU 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +DEFAULT_PGM_MULTI_THROTTLE_RATE EQU 13 ; 1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255 +DEFAULT_PGM_MULTI_DAMPING_FORCE EQU 1 ; 1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest +IF DAMPED_MODE_ENABLE == 1 +DEFAULT_PGM_MULTI_PWM_FREQ EQU 1 ; 1=Low 2=High +ELSE +DEFAULT_PGM_MULTI_PWM_FREQ EQU 1 ; 1=Low 2=High +ENDIF +DEFAULT_PGM_MULTI_DEMAG_COMP EQU 2 ; 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off) +DEFAULT_PGM_MULTI_DIRECTION_REV EQU 1 ; 1=Normal 2=Reversed +DEFAULT_PGM_MULTI_RCP_PWM_POL EQU 1 ; 1=Positive 2=Negative +;DEFAULT_PGM_MULTI_BEEP_STRENGTH EQU 40 ; Beep strength +;DEFAULT_PGM_MULTI_BEACON_STRENGTH EQU 80 ; Beacon strength 等待摇杆操作声强 +;DEFAULT_PGM_MULTI_BEACON_DELAY EQU 4 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite +DEFAULT_PGM_MULTI_BEEP_STRENGTH EQU 80 ; Beep strength 上电到一次信号拉到最低声强 +DEFAULT_PGM_MULTI_BEACON_STRENGTH EQU 100 ; Beacon strength 等待摇杆操作声强 +DEFAULT_PGM_MULTI_BEACON_DELAY EQU 2 ; 1=30s 2=1m 3=2m 4=3m 5=Infinite 等待摇杆操作时间 +; Common +DEFAULT_PGM_ENABLE_TX_PROGRAM EQU 1 ; 1=Enabled 0=Disabled +DEFAULT_PGM_PPM_MIN_THROTTLE EQU 37 ; 4*37+1000=1148 +DEFAULT_PGM_PPM_MAX_THROTTLE EQU 208 ; 4*208+1000=1832 +DEFAULT_PGM_BEC_VOLTAGE_HIGH EQU 0 ; 0=Low 1= High + +;**** **** **** **** **** +; Constant definitions for main +IF MODE == 0 + +GOV_SPOOLRATE EQU 1 ; Number of steps for governor requested pwm per 32ms + +RCP_TIMEOUT_PPM EQU 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost +RCP_TIMEOUT EQU 64 ; Number of timer2L overflows (about 128us) before considering rc pulse lost +RCP_SKIP_RATE EQU 32 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection +RCP_MIN EQU 0 ; This is minimum RC pulse length +RCP_MAX EQU 254 ; This is maximum RC pulse length +RCP_VALIDATE EQU 2 ; Require minimum this pulse length to validate RC pulse +RCP_STOP EQU 1 ; Stop motor at or below this pulse length +RCP_STOP_LIMIT EQU 3 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit + +PWM_SETTLE EQU 50 ; PWM used when in start settling phase (also max power during direct start) +PWM_STEPPER EQU 80 ; PWM used when in start stepper phase + +COMM_TIME_RED EQU 8 ; Fixed reduction (in us) for commutation wait (to account for fixed delays) +COMM_TIME_MIN EQU 1 ; Minimum time (in us) for commutation wait + +TEMP_CHECK_RATE EQU 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage) + +ENDIF +; Constant definitions for tail +IF MODE == 1 + +GOV_SPOOLRATE EQU 1 ; Number of steps for governor requested pwm per 32ms +RCP_TIMEOUT_PPM EQU 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost +RCP_TIMEOUT EQU 24 ; Number of timer2L overflows (about 128us) before considering rc pulse lost +RCP_SKIP_RATE EQU 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection +RCP_MIN EQU 0 ; This is minimum RC pulse length +RCP_MAX EQU 255 ; This is maximum RC pulse length +RCP_VALIDATE EQU 2 ; Require minimum this pulse length to validate RC pulse +RCP_STOP EQU 1 ; Stop motor at or below this pulse length +RCP_STOP_LIMIT EQU 130 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit + +PWM_SETTLE EQU 50 ; PWM used when in start settling phase (also max power during direct start) +PWM_STEPPER EQU 120 ; PWM used when in start stepper phase + +COMM_TIME_RED EQU 8 ; Fixed reduction (in us) for commutation wait (to account for fixed delays) +COMM_TIME_MIN EQU 1 ; Minimum time (in us) for commutation wait + +TEMP_CHECK_RATE EQU 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage) + +ENDIF +; Constant definitions for multi +IF MODE == 2 + +GOV_SPOOLRATE EQU 1 ; Number of steps for governor requested pwm per 32ms + +RCP_TIMEOUT_PPM EQU 64 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost +RCP_TIMEOUT EQU 40 ; Number of timer2L overflows (about 128us) before considering rc pulse lost +RCP_SKIP_RATE EQU 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection +RCP_MIN EQU 0 ; This is minimum RC pulse length +RCP_MAX EQU 255 ; This is maximum RC pulse length +RCP_VALIDATE EQU 2 ; Require minimum this pulse length to validate RC pulse +RCP_STOP EQU 1 ; Stop motor at or below this pulse length +;//////RCP_STOP_LIMIT EQU 20 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit + +PWM_SETTLE EQU 50 ; PWM used when in start settling phase (also max power during direct start) +PWM_STEPPER EQU 120 ; PWM used when in start stepper phase + +COMM_TIME_RED EQU 8 ; Fixed reduction (in us) for commutation wait (to account for fixed delays) +COMM_TIME_MIN EQU 1 ; Minimum time (in us) for commutation wait + +TEMP_CHECK_RATE EQU 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage) + +ENDIF + +;**** **** **** **** **** +; Temporary register definitions +Temp1 EQU R0 +Temp2 EQU R1 +Temp3 EQU R2 +Temp4 EQU R3 +Temp5 EQU R4 +Temp6 EQU R5 +Temp7 EQU R6 +Temp8 EQU R7 + +;**** **** **** **** **** +; Register definitions +DSEG AT 20h ; Variables segment + +Bit_Access: DS 1 ; Variable at bit accessible address (for non interrupt routines) +Bit_Access_Int: DS 1 ; Variable at bit accessible address (for interrupts) + +Requested_Pwm: DS 1 ; Requested pwm (from RC pulse value) +Governor_Req_Pwm: DS 1 ; Governor requested pwm (sets governor target) +Current_Pwm: DS 1 ; Current pwm +Current_Pwm_Limited: DS 1 ; Current pwm that is limited (applied to the motor output) +Rcp_Prev_Edge_L: DS 1 ; RC pulse previous edge timer3 timestamp (lo byte) +Rcp_Prev_Edge_H: DS 1 ; RC pulse previous edge timer3 timestamp (hi byte) +Rcp_Timeout_Cnt: DS 1 ; RC pulse timeout counter (decrementing) +Rcp_Skip_Cnt: DS 1 ; RC pulse skip counter (decrementing) +Rcp_Edge_Cnt: DS 1 ; RC pulse edge counter +Rcp_Stop_Limit: DS 1 ;增加刹车速度 + +Flags0: DS 1 ; State flags. Reset upon init_start +T3_PENDING EQU 0 ; Timer3 pending flag +RCP_MEAS_PWM_FREQ EQU 1 ; Measure RC pulse pwm frequency +PWM_ON EQU 2 ; Set in on part of pwm cycle +DEMAG_DETECTED EQU 3 ; Set when excessive demag time is detected +DEMAG_CUT_POWER EQU 4 ; Set when demag compensation cuts power +; EQU 5 +PROGRAM_FUNC_FLAG EQU 6 +SUCCESS_BEEP_FLAG EQU 7 + +Flags1: DS 1 ; State flags. Reset upon init_start +MOTOR_SPINNING EQU 0 ; Set when in motor is spinning +SETTLE_PHASE EQU 1 ; Set when in motor start settling phase +STEPPER_PHASE EQU 2 ; Set when in motor start stepper motor phase +DIRECT_STARTUP_PHASE EQU 3 ; Set when in direct startup phase +INITIAL_RUN_PHASE EQU 4 ; Set when in initial run phase, before synchronized run is achieved +; EQU 5 +; EQU 6 +LOW_LIMIT_STOP EQU 7 + +Flags2: DS 1 ; State flags. NOT reset upon init_start +RCP_UPDATED EQU 0 ; New RC pulse length value available +RCP_EDGE_NO EQU 1 ; RC pulse edge no. 0=rising, 1=falling +PGM_PWMOFF_DAMPED EQU 2 ; Programmed pwm off damped mode. Set when fully damped or damped light mode is selected +PGM_PWMOFF_DAMPED_FULL EQU 3 ; Programmed pwm off fully damped mode. Set when all pfets shall be on in pwm_off period +PGM_PWMOFF_DAMPED_LIGHT EQU 4 ; Programmed pwm off damped light mode. Set when only 2 pfets shall be on in pwm_off period +PGM_PWM_HIGH_FREQ EQU 5 ; Progremmed pwm high frequency +CURR_PWMOFF_DAMPED EQU 6 ; Currently running pwm off cycle is damped +CURR_PWMOFF_COMP_ABLE EQU 7 ; Currently running pwm off cycle is usable for comparator + +Flags3: DS 1 ; State flags. NOT reset upon init_start +RCP_PWM_FREQ_1KHZ EQU 0 ; RC pulse pwm frequency is 1kHz +RCP_PWM_FREQ_2KHZ EQU 1 ; RC pulse pwm frequency is 2kHz +RCP_PWM_FREQ_4KHZ EQU 2 ; RC pulse pwm frequency is 4kHz +RCP_PWM_FREQ_8KHZ EQU 3 ; RC pulse pwm frequency is 8kHz +PGM_DIR_REV EQU 4 ; Programmed direction. 0=normal, 1=reversed +PGM_RCP_PWM_POL EQU 5 ; Programmed RC pulse pwm polarity. 0=positive, 1=negative +FULL_THROTTLE_RANGE EQU 6 ; When set full throttle range is used (1000-2000us) and stored calibration values are ignored +ERRO_DATA EQU 7 ;增加编程卡数据错误标志 2013.8.27 +;**** **** **** **** **** +; RAM definitions +DSEG AT 30h ; Ram data segment, direct addressing + +Initial_Arm: DS 1 ; Variable that is set during the first arm sequence after power on +;Pca_First_Int: DS 1 +Power_On_Wait_Cnt_L: DS 1 ; Power on wait counter (lo byte) +Power_On_Wait_Cnt_H: DS 1 ; Power on wait counter (hi byte) +Pgm_Pulse_Cnt: DS 1 +;Stepper_Step_Beg_L: DS 1 ; Stepper phase step time at the beginning (lo byte) +;Stepper_Step_Beg_H: DS 1 ; Stepper phase step time at the beginning (hi byte) +;Stepper_Step_End_L: DS 1 ; Stepper phase step time at the end (lo byte) +;Stepper_Step_End_H: DS 1 ; Stepper phase step time at the end (hi byte) +Startup_Rot_Cnt: DS 1 ; Startup phase rotations counter +Direct_Startup_Ok_Cnt: DS 1 ; Direct startup phase ok comparator waits counter (incrementing) + +Prev_Comm_L: DS 1 ; Previous commutation timer3 timestamp (lo byte) +Prev_Comm_H: DS 1 ; Previous commutation timer3 timestamp (hi byte) +Comm_Period4x_L: DS 1 ; Timer3 counts between the last 4 commutations (lo byte) +Comm_Period4x_H: DS 1 ; Timer3 counts between the last 4 commutations (hi byte) +Comm_Phase: DS 1 ; Current commutation phase +Comp_Wait_Reads: DS 1 ; Comparator wait comparator reads + +Gov_Target_L: DS 1 ; Governor target (lo byte) +Gov_Target_H: DS 1 ; Governor target (hi byte) +Gov_Integral_L: DS 1 ; Governor integral error (lo byte) +Gov_Integral_H: DS 1 ; Governor integral error (hi byte) +Gov_Integral_X: DS 1 ; Governor integral error (ex byte) +Gov_Proportional_L: DS 1 ; Governor proportional error (lo byte) +Gov_Proportional_H: DS 1 ; Governor proportional error (hi byte) +Gov_Prop_Pwm: DS 1 ; Governor calculated new pwm based upon proportional error +Gov_Arm_Target: DS 1 ; Governor arm target value +Gov_Active: DS 1 ; Governor active (enabled when speed is above minimum) + +Wt_Advance_L: DS 1 ; Timer3 counts for commutation advance timing (lo byte) +Wt_Advance_H: DS 1 ; Timer3 counts for commutation advance timing (hi byte) +Wt_Zc_Scan_L: DS 1 ; Timer3 counts from commutation to zero cross scan (lo byte) +Wt_Zc_Scan_H: DS 1 ; Timer3 counts from commutation to zero cross scan (hi byte) +Wt_Comm_L: DS 1 ; Timer3 counts from zero cross to commutation (lo byte) +Wt_Comm_H: DS 1 ; Timer3 counts from zero cross to commutation (hi byte) +;Wt_Stepper_Step_L: DS 1 ; Timer3 counts for stepper step (lo byte) +;Wt_Stepper_Step_H: DS 1 ; Timer3 counts for stepper step (hi byte) + +Rcp_PrePrev_Edge_L: DS 1 ; RC pulse pre previous edge pca timestamp (lo byte) +Rcp_PrePrev_Edge_H: DS 1 ; RC pulse pre previous edge pca timestamp (hi byte) +Rcp_Edge_L: DS 1 ; RC pulse edge pca timestamp (lo byte) +Rcp_Edge_H: DS 1 ; RC pulse edge pca timestamp (hi byte) +Rcp_Prev_Period_L: DS 1 ; RC pulse previous period (lo byte) +Rcp_Prev_Period_H: DS 1 ; RC pulse previous period (hi byte) +Rcp_Period_Diff_Accepted: DS 1 ; RC pulse period difference acceptable +New_Rcp: DS 1 ; New RC pulse value in pca counts +Prev_Rcp_Pwm_Freq: DS 1 ; Previous RC pulse pwm frequency (used during pwm frequency measurement) +Curr_Rcp_Pwm_Freq: DS 1 ; Current RC pulse pwm frequency (used during pwm frequency measurement) +Rcp_Stop_Cnt: DS 1 ; Counter for RC pulses below stop value + +Pwm_Limit: DS 1 ; Maximum allowed pwm +Pwm_Limit_Spoolup: DS 1 ; Maximum allowed pwm during spoolup of main +Pwm_Spoolup_Beg: DS 1 ; Pwm to begin main spoolup with +Pwm_Motor_Idle: DS 1 ; Motor idle speed pwm +Pwm_On_Cnt: DS 1 ; Pwm on event counter (used to increase pwm off time for low pwm) +Pwm_Off_Cnt: DS 1 ; Pwm off event counter (used to run some pwm cycles without damping) + +Spoolup_Limit_Cnt: DS 1 ; Interrupt count for spoolup limit +Spoolup_Limit_Skip: DS 1 ; Interrupt skips for spoolup limit increment (0=no skips, 1=skip one etc) + +Damping_Period: DS 1 ; Damping on/off period +Damping_On: DS 1 ; Damping on part of damping period + +;Lipo_Adc_Reference_L: DS 1 ; Voltage reference adc value (lo byte) +;Lipo_Adc_Reference_H: DS 1 ; Voltage reference adc value (hi byte) +Lipo_Adc_Limit_L: DS 1 ; Low voltage limit adc value (lo byte) +Lipo_Adc_Limit_H: DS 1 ; Low voltage limit adc value (hi byte) +Adc_Conversion_Cnt: DS 1 ; Adc conversion counter +Lipo_Cell_Count: DS 1 ;增加电池节数累计变量 2013.5.29 +Limit_Count: DS 1 ;增加逐渐递减计数变量 2013.7.5 + +Current_Average_Temp: DS 1 ; Current average temperature (lo byte ADC reading, assuming hi byte is 1) + +Ppm_Throttle_Gain: DS 1 ; Gain to be applied to RCP value for PPM input +Beep_Strength: DS 1 ; Strength of beeps + +Tx_Pgm_Func_No: DS 1 ; Function number when doing programming by tx +Tx_Pgm_Paraval_No: DS 1 ; Parameter value number when doing programming by tx +Tx_Pgm_Beep_No: DS 1 ; Beep number when doing programming by tx +Commu_Data_Buffer: DS 1 ;编程卡接收,发送数据暂存 2013.8.27 +Commu_Sum: DS 1 ;增加编程卡校验和 2013.8.27 +Min_Throttle: DS 1 + +; Indirect addressing data segment +ISEG AT 080h +Pgm_Fir_Key: DS 1 ;增加首个关键字 2013.8.27 +Pgm_Gov_P_Gain: DS 1 ; Programmed governor P gain +Pgm_Gov_I_Gain: DS 1 ; Programmed governor I gain +Pgm_Gov_Mode: DS 1 ; Programmed governor mode + +Pgm_Low_Voltage_Lim: DS 1 ; Programmed low voltage limit +Pgm_Low_Voltage_Ctl: DS 1 ;增加低压保护控制方式编程项 2013.7.5 +Pgm_Motor_Gain: DS 1 ; Programmed motor gain +Pgm_Motor_Idle: DS 1 ; Programmed motor idle speed +Pgm_Startup_Pwr: DS 1 ; Programmed startup power +Pgm_Pwm_Freq: DS 1 ; Programmed pwm frequency +Pgm_Direction_Rev: DS 1 ; Programmed rotation direction +Pgm_Input_Pol: DS 1 ; Programmed input pwm polarity +Initialized_L_Dummy: DS 1 ; Place holder +Initialized_H_Dummy: DS 1 ; Place holder +Pgm_Enable_TX_Program: DS 1 ; Programmed enable/disable value for TX programming +Pgm_Main_Rearm_Start: DS 1 ; Programmed enable/disable re-arming main every start +Pgm_Gov_Setup_Target: DS 1 ; Programmed main governor setup target +Pgm_Startup_Rpm: DS 1 ; Programmed startup rpm +Pgm_Startup_Accel: DS 1 ; Programmed startup acceleration +Pgm_Volt_Comp_Dummy: DS 1 ; Place holder +Pgm_Comm_Timing: DS 1 ; Programmed commutation timing +Pgm_Damping_Force: DS 1 ; Programmed damping force +Pgm_Gov_Range: DS 1 ; Programmed governor range +;Pgm_Startup_Method: DS 1 ; Programmed startup method +Pgm_Ppm_Min_Throttle: DS 1 ; Programmed throttle minimum +Pgm_Ppm_Max_Throttle: DS 1 ; Programmed throttle maximum +Pgm_Beep_Strength: DS 1 ; Programmed beep strength +Pgm_Beacon_Strength: DS 1 ; Programmed beacon strength +Pgm_Beacon_Delay: DS 1 ; Programmed beacon delay +Pgm_Throttle_Rate: DS 1 ; Programmed throttle rate +Pgm_Demag_Comp: DS 1 ; Programmed demag compensation +Pgm_BEC_Voltage_High: DS 1 ; Programmed BEC voltage + +Pgm_Gov_P_Gain_Decoded: DS 1 ; Programmed governor decoded P gain +Pgm_Gov_I_Gain_Decoded: DS 1 ; Programmed governor decoded I gain +Pgm_Throttle_Rate_Decoded: DS 1 ; Programmed throttle rate decoded +Pgm_Startup_Pwr_Decoded: DS 1 ; Programmed startup power decoded +Pgm_Demag_Comp_Wait_Decoded: DS 1 ; Programmed demag compensation wait decoded +Pgm_Demag_Comp_Power_Decoded: DS 1 ; Programmed demag compensation power cut decoded + + +; Indirect addressing data segment +ISEG AT 0D0h +Tag_Temporary_Storage: DS 48 ; Temporary storage for tags when updating "Eeprom" + + +;**** **** **** **** **** +CSEG AT 1A00h ; "Eeprom" segment +EEPROM_FW_MAIN_REVISION EQU 10 ; Main revision of the firmware +EEPROM_FW_SUB_REVISION EQU 2 ; Sub revision of the firmware +EEPROM_LAYOUT_REVISION EQU 16 ; Revision of the EEPROM layout + +Eep_FW_Main_Revision: DB EEPROM_FW_MAIN_REVISION ; EEPROM firmware main revision number +Eep_FW_Sub_Revision: DB EEPROM_FW_SUB_REVISION ; EEPROM firmware sub revision number +Eep_Layout_Revision: DB EEPROM_LAYOUT_REVISION ; EEPROM layout revision number + +IF MODE == 0 +Eep_Pgm_Gov_P_Gain: DB DEFAULT_PGM_MAIN_P_GAIN ; EEPROM copy of programmed governor P gain +Eep_Pgm_Gov_I_Gain: DB DEFAULT_PGM_MAIN_I_GAIN ; EEPROM copy of programmed governor I gain +Eep_Pgm_Gov_Mode: DB DEFAULT_PGM_MAIN_GOVERNOR_MODE ; EEPROM copy of programmed governor mode + +Eep_Pgm_Low_Voltage_Lim: DB DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM ; EEPROM copy of programmed low voltage limit +_Eep_Pgm_Motor_Gain: DB 0FFh +_Eep_Pgm_Motor_Idle: DB 0FFh +Eep_Pgm_Startup_Pwr: DB DEFAULT_PGM_MAIN_STARTUP_PWR ; EEPROM copy of programmed startup power +Eep_Pgm_Pwm_Freq: DB DEFAULT_PGM_MAIN_PWM_FREQ ; EEPROM copy of programmed pwm frequency +Eep_Pgm_Direction_Rev: DB DEFAULT_PGM_MAIN_DIRECTION_REV ; EEPROM copy of programmed rotation direction +Eep_Pgm_Input_Pol: DB DEFAULT_PGM_MAIN_RCP_PWM_POL ; EEPROM copy of programmed input polarity +Eep_Initialized_L: DB 0A5h ; EEPROM initialized signature low byte +Eep_Initialized_H: DB 05Ah ; EEPROM initialized signature high byte +Eep_Enable_TX_Program: DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable +Eep_Main_Rearm_Start: DB DEFAULT_PGM_MAIN_REARM_START ; EEPROM re-arming main enable +Eep_Pgm_Gov_Setup_Target: DB DEFAULT_PGM_MAIN_GOV_SETUP_TARGET ; EEPROM main governor setup target +Eep_Pgm_Startup_Rpm: DB DEFAULT_PGM_MAIN_STARTUP_RPM ; EEPROM copy of programmed startup rpm +Eep_Pgm_Startup_Accel: DB DEFAULT_PGM_MAIN_STARTUP_ACCEL ; EEPROM copy of programmed startup acceleration +_Eep_Pgm_Volt_Comp: DB 0FFh +Eep_Pgm_Comm_Timing: DB DEFAULT_PGM_MAIN_COMM_TIMING ; EEPROM copy of programmed commutation timing +Eep_Pgm_Damping_Force: DB DEFAULT_PGM_MAIN_DAMPING_FORCE ; EEPROM copy of programmed damping force +Eep_Pgm_Gov_Range: DB DEFAULT_PGM_MAIN_GOVERNOR_RANGE ; EEPROM copy of programmed governor range +Eep_Pgm_Startup_Method: DB DEFAULT_PGM_MAIN_STARTUP_METHOD ; EEPROM copy of programmed startup method +Eep_Pgm_Ppm_Min_Throttle: DB DEFAULT_PGM_PPM_MIN_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1148) +Eep_Pgm_Ppm_Max_Throttle: DB DEFAULT_PGM_PPM_MAX_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1832) +Eep_Pgm_Beep_Strength: DB DEFAULT_PGM_MAIN_BEEP_STRENGTH ; EEPROM copy of programmed beep strength +Eep_Pgm_Beacon_Strength: DB DEFAULT_PGM_MAIN_BEACON_STRENGTH ; EEPROM copy of programmed beacon strength +Eep_Pgm_Beacon_Delay: DB DEFAULT_PGM_MAIN_BEACON_DELAY ; EEPROM copy of programmed beacon delay +Eep_Pgm_Throttle_Rate: DB DEFAULT_PGM_MAIN_THROTTLE_RATE ; EEPROM copy of programmed throttle rate +Eep_Pgm_Demag_Comp: DB DEFAULT_PGM_MAIN_DEMAG_COMP ; EEPROM copy of programmed demag compensation +Eep_Pgm_BEC_Voltage_High: DB DEFAULT_PGM_BEC_VOLTAGE_HIGH ; EEPROM copy of programmed BEC voltage +ENDIF + +IF MODE == 1 +_Eep_Pgm_Gov_P_Gain: DB 0FFh +_Eep_Pgm_Gov_I_Gain: DB 0FFh +_Eep_Pgm_Gov_Mode: DB 0FFh + +_Eep_Pgm_Low_Voltage_Lim: DB 0FFh +Eep_Pgm_Motor_Gain: DB DEFAULT_PGM_TAIL_GAIN ; EEPROM copy of programmed tail gain +Eep_Pgm_Motor_Idle: DB DEFAULT_PGM_TAIL_IDLE_SPEED ; EEPROM copy of programmed tail idle speed +Eep_Pgm_Startup_Pwr: DB DEFAULT_PGM_TAIL_STARTUP_PWR ; EEPROM copy of programmed startup power +Eep_Pgm_Pwm_Freq: DB DEFAULT_PGM_TAIL_PWM_FREQ ; EEPROM copy of programmed pwm frequency +Eep_Pgm_Direction_Rev: DB DEFAULT_PGM_TAIL_DIRECTION_REV ; EEPROM copy of programmed rotation direction +Eep_Pgm_Input_Pol: DB DEFAULT_PGM_TAIL_RCP_PWM_POL ; EEPROM copy of programmed input polarity +Eep_Initialized_L: DB 05Ah ; EEPROM initialized signature low byte +Eep_Initialized_H: DB 0A5h ; EEPROM initialized signature high byte +Eep_Enable_TX_Program: DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable +_Eep_Main_Rearm_Start: DB 0FFh +_Eep_Pgm_Gov_Setup_Target: DB 0FFh +Eep_Pgm_Startup_Rpm: DB DEFAULT_PGM_TAIL_STARTUP_RPM ; EEPROM copy of programmed startup rpm +Eep_Pgm_Startup_Accel: DB DEFAULT_PGM_TAIL_STARTUP_ACCEL ; EEPROM copy of programmed startup acceleration +_Eep_Pgm_Volt_Comp: DB 0FFh +Eep_Pgm_Comm_Timing: DB DEFAULT_PGM_TAIL_COMM_TIMING ; EEPROM copy of programmed commutation timing +Eep_Pgm_Damping_Force: DB DEFAULT_PGM_TAIL_DAMPING_FORCE ; EEPROM copy of programmed damping force +_Eep_Pgm_Gov_Range: DB 0FFh +Eep_Pgm_Startup_Method: DB DEFAULT_PGM_TAIL_STARTUP_METHOD ; EEPROM copy of programmed startup method +Eep_Pgm_Ppm_Min_Throttle: DB DEFAULT_PGM_PPM_MIN_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1148) +Eep_Pgm_Ppm_Max_Throttle: DB DEFAULT_PGM_PPM_MAX_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1832) +Eep_Pgm_Beep_Strength: DB DEFAULT_PGM_TAIL_BEEP_STRENGTH ; EEPROM copy of programmed beep strength +Eep_Pgm_Beacon_Strength: DB DEFAULT_PGM_TAIL_BEACON_STRENGTH ; EEPROM copy of programmed beacon strength +Eep_Pgm_Beacon_Delay: DB DEFAULT_PGM_TAIL_BEACON_DELAY ; EEPROM copy of programmed beacon delay +Eep_Pgm_Throttle_Rate: DB DEFAULT_PGM_TAIL_THROTTLE_RATE ; EEPROM copy of programmed throttle rate +Eep_Pgm_Demag_Comp: DB DEFAULT_PGM_TAIL_DEMAG_COMP ; EEPROM copy of programmed demag compensation +Eep_Pgm_BEC_Voltage_High: DB DEFAULT_PGM_BEC_VOLTAGE_HIGH ; EEPROM copy of programmed BEC voltage +ENDIF + +IF MODE == 2 +Eep_Pgm_Fir_Key: DB DEFAULT_PGM_MULTI_FIRST_KEYWORD ;增加首个关键字 2013.8.27 +Eep_Pgm_Gov_P_Gain: DB DEFAULT_PGM_MULTI_P_GAIN ; EEPROM copy of programmed closed loop P gain +Eep_Pgm_Gov_I_Gain: DB DEFAULT_PGM_MULTI_I_GAIN ; EEPROM copy of programmed closed loop I gain +Eep_Pgm_Gov_Mode: DB DEFAULT_PGM_MULTI_GOVERNOR_MODE ; EEPROM copy of programmed closed loop mode + +Eep_Pgm_Low_Voltage_Lim: DB DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM ; EEPROM copy of programmed low voltage limit +Eep_Pgm_Low_Voltage_Ctl: DB DEFAULT_PGM_MULTI_LOW_VOLTAGE_CTL ; 增加低压保护控制编程 +Eep_Pgm_Motor_Gain: DB DEFAULT_PGM_MULTI_GAIN ; EEPROM copy of programmed tail gain +_Eep_Pgm_Motor_Idle: DB 0FFh ; EEPROM copy of programmed tail idle speed +Eep_Pgm_Startup_Pwr: DB DEFAULT_PGM_MULTI_STARTUP_PWR ; EEPROM copy of programmed startup power +Eep_Pgm_Pwm_Freq: DB DEFAULT_PGM_MULTI_PWM_FREQ ; EEPROM copy of programmed pwm frequency +Eep_Pgm_Direction_Rev: DB DEFAULT_PGM_MULTI_DIRECTION_REV ; EEPROM copy of programmed rotation direction +Eep_Pgm_Input_Pol: DB DEFAULT_PGM_MULTI_RCP_PWM_POL ; EEPROM copy of programmed input polarity +Eep_Initialized_L: DB 055h ; EEPROM initialized signature low byte +Eep_Initialized_H: DB 0AAh ; EEPROM initialized signature high byte +Eep_Enable_TX_Program: DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable +_Eep_Main_Rearm_Start: DB 0FFh +_Eep_Pgm_Gov_Setup_Target: DB 0FFh +Eep_Pgm_Startup_Rpm: DB DEFAULT_PGM_MULTI_STARTUP_RPM ; EEPROM copy of programmed startup rpm +Eep_Pgm_Startup_Accel: DB DEFAULT_PGM_MULTI_STARTUP_ACCEL ; EEPROM copy of programmed startup acceleration +_Eep_Pgm_Volt_Comp: DB 0FFh +Eep_Pgm_Comm_Timing: DB DEFAULT_PGM_MULTI_COMM_TIMING ; EEPROM copy of programmed commutation timing +Eep_Pgm_Damping_Force: DB DEFAULT_PGM_MULTI_DAMPING_FORCE ; EEPROM copy of programmed damping force +_Eep_Pgm_Gov_Range: DB 0FFh +;Eep_Pgm_Startup_Method: DB DEFAULT_PGM_MULTI_STARTUP_METHOD ; EEPROM copy of programmed startup method +Eep_Pgm_Ppm_Min_Throttle: DB DEFAULT_PGM_PPM_MIN_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1148) +Eep_Pgm_Ppm_Max_Throttle: DB DEFAULT_PGM_PPM_MAX_THROTTLE ; EEPROM copy of programmed minimum throttle (final value is 4x+1000=1832) +Eep_Pgm_Beep_Strength: DB DEFAULT_PGM_MULTI_BEEP_STRENGTH ; EEPROM copy of programmed beep strength +Eep_Pgm_Beacon_Strength: DB DEFAULT_PGM_MULTI_BEACON_STRENGTH ; EEPROM copy of programmed beacon strength +Eep_Pgm_Beacon_Delay: DB DEFAULT_PGM_MULTI_BEACON_DELAY ; EEPROM copy of programmed beacon delay +Eep_Pgm_Throttle_Rate: DB DEFAULT_PGM_MULTI_THROTTLE_RATE ; EEPROM copy of programmed throttle rate +Eep_Pgm_Demag_Comp: DB DEFAULT_PGM_MULTI_DEMAG_COMP ; EEPROM copy of programmed demag compensation +Eep_Pgm_BEC_Voltage_High: DB DEFAULT_PGM_BEC_VOLTAGE_HIGH ; EEPROM copy of programmed BEC voltage +ENDIF + + +Eep_Dummy: DB 0FFh ; EEPROM address for safety reason + +CSEG AT 1A60h +Eep_Name: DB " " ; Name tag (16 Bytes) + +;**** **** **** **** **** + Interrupt_Table_Definition ; SiLabs interrupts +CSEG AT 80h ; Code segment after interrupt vectors + +;**** **** **** **** **** + +; Table definitions +GOV_GAIN_TABLE: DB 02h, 03h, 04h, 06h, 08h, 0Ch, 10h, 18h, 20h, 30h, 40h, 60h, 80h +THROTTLE_RATE_TABLE: DB 02h, 03h, 04h, 06h, 08h, 0Ch, 10h, 18h, 20h, 30h, 40h, 80h, 0FFh +STARTUP_POWER_TABLE: DB 04h, 06h, 08h, 0Ch, 10h, 18h, 20h, 30h, 40h, 60h, 80h, 0A0h, 0C0h +DEMAG_WAIT_TABLE: DB 0, 0, 0, 1, 1 +DEMAG_POWER_TABLE: DB 0, 3, 2, 2, 1 + +;FINISH_KEYWORD_TABLE: DB 066h, 08h, 08h, 03h, 01h, 00h, 02h, 00h +; DB 09h, 01h, 00h, 00h, 00h, 00h, 00h, 00h +; DB 0B4h, 00h, 04h, 00h, 02h, 00h, 00h, 025h +; DB 0D0h, 050h, 064h, 01h, 0Dh, 01h, 00h, 00h ;增加编程默认值表 2013.7.30 ;////////////////////////////////////////// +; DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h +; DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h + +IF MODE == 0 +TX_PGM_PARAMS_MAIN: DB 13, 13, 4, 2, 6, 2, 13, 5, 5, 5, 13, 6, 3, 5, 2, 2 +ENDIF +IF MODE == 1 + IF DAMPED_MODE_ENABLE == 1 +TX_PGM_PARAMS_TAIL: DB 5, 5, 2, 13, 5, 5, 5, 13, 6, 4, 5, 2, 2 + ENDIF + IF DAMPED_MODE_ENABLE == 0 +TX_PGM_PARAMS_TAIL: DB 5, 5, 2, 13, 5, 5, 5, 13, 6, 3, 5, 2, 2 + ENDIF +ENDIF +IF MODE == 2 + IF DAMPED_MODE_ENABLE == 1 +;///////TX_PGM_PARAMS_MULTI: DB 13, 13, 4, 5, 6, 2, 13, 5, 5, 5, 13, 6, 4, 5, 2, 2 + TX_PGM_PARAMS_MULTI: DB 6, 5, 13, 4, 2, 4, 2 + ENDIF + IF DAMPED_MODE_ENABLE == 0 +;///////TX_PGM_PARAMS_MULTI: DB 13, 13, 4, 5, 6, 2, 13, 5, 5, 5, 13, 6, 3, 5, 2, 2 + TX_PGM_PARAMS_MULTI: DB 6, 5, 13, 4, 2, 4, 2 + ENDIF +ENDIF + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Timer0 interrupt routine +; +; Assumptions: DPTR register must be set to desired pwm_nfet_on label +; Requirements: Temp variables can NOT be used since PWSW.3 is not set +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +t0_int: ; Used for pwm control + clr EA ; Disable all interrupts + push PSW ; Preserve registers through interrupt + push ACC + ; Check if pwm is on + jb Flags0.PWM_ON, t0_int_pwm_off ; Is pwm on? + + ; Pwm on cycle. + jnb Current_Pwm_Limited.7, t0_int_pwm_on_low_pwm ; Jump for low pwm (<50%) + +t0_int_pwm_on_execute: + clr A + jmp @A+DPTR ; No - jump to pwm on routines. DPTR should be set to one of the pwm_nfet_on labels + +t0_int_pwm_on_low_pwm: + ; Do not execute pwm when stopped + jnb Flags1.MOTOR_SPINNING, t0_int_pwm_on_stopped + +IF MODE == 0 OR MODE == 2 ; Main or multi + jmp t0_int_pwm_on_execute +ENDIF +IF MODE == 1 ; Tail + ; Skip pwm on cycles for very low pwm + inc Pwm_On_Cnt ; Increment event counter + clr C + mov A, #5 ; Only skip for very low pwm + subb A, Current_Pwm_Limited ; Check skipping shall be done (for low pwm only) + jc t0_int_pwm_on_execute + + subb A, Pwm_On_Cnt ; Check if on cycle is to be skipped + jc t0_int_pwm_on_execute + + mov TL0, #120 ; Write start point for timer + mov A, Current_Pwm_Limited + jnz ($+5) + mov TL0, #0 ; Write start point for timer (long time for zero pwm) + jmp t0_int_pwm_on_exit_no_timer_update +ENDIF + +t0_int_pwm_on_stopped: + jmp t0_int_pwm_on_exit + + +t0_int_pwm_off: + jnb Flags1.DIRECT_STARTUP_PHASE, t0_int_pwm_off_start_checked + All_nFETs_Off ; Switch off all nfets early during direct start, for a smooth start +t0_int_pwm_off_start_checked: + ; Pwm off cycle + mov TL0, Current_Pwm_Limited ; Load new timer setting + ; Clear pwm on flag + clr Flags0.PWM_ON + ; Set full PWM (on all the time) if current PWM near max. This will give full power, but at the cost of a small "jump" in power + mov A, Current_Pwm_Limited ; Load current pwm + cpl A ; Full pwm? + jnz ($+4) ; No - branch + ajmp t0_int_pwm_off_fullpower_exit ; Yes - exit + + inc Pwm_Off_Cnt ; Increment event counter + ; Do not execute pwm when stopped + jnb Flags1.MOTOR_SPINNING, t0_int_pwm_off_stopped + + ; If damped operation, set pFETs on in pwm_off + jb Flags2.PGM_PWMOFF_DAMPED, t0_int_pwm_off_damped ; Damped operation? + + ; Separate exit commands here for minimum delay + mov TL1, #0 ; Reset timer1 + pop ACC ; Restore preserved registers + pop PSW + All_nFETs_Off ; Switch off all nfets + setb EA ; Enable all interrupts + reti + +t0_int_pwm_off_stopped: + All_nFETs_Off ; Switch off all nfets + jmp t0_int_pwm_off_exit + +t0_int_pwm_off_damped: + setb Flags2.CURR_PWMOFF_DAMPED ; Set damped status + clr Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator unusable status + mov A, Damping_On + jz t0_int_pwm_off_do_damped ; Highest damping - apply damping always + + clr C + mov A, Pwm_Off_Cnt ; Is damped on number reached? + dec A + subb A, Damping_On + jc t0_int_pwm_off_do_damped ; No - apply damping + + clr Flags2.CURR_PWMOFF_DAMPED ; Set non damped status + setb Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator usable status + clr C + mov A, Pwm_Off_Cnt + subb A, Damping_Period ; Is damped period number reached? + jnc t0_int_pwm_off_clr_cnt ; Yes - Proceed + + jmp t0_int_pwm_off_exit ; No - Branch + +t0_int_pwm_off_clr_cnt: + mov Pwm_Off_Cnt, #0 ; Yes - clear counter + jmp t0_int_pwm_off_exit ; Not damped cycle - exit + +t0_int_pwm_off_do_damped: + ; Delay to allow nFETs to go off before pFETs are turned on (only in full damped mode) + jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, t0_int_pwm_off_damped_light ; If damped light operation - branch + +; All_pFETs_Off ; Switch off all nfets +; mov A, #PFETON_DELAY +; djnz ACC, $ +; All_nFETs_On ; Switch on all pfets + jmp t0_int_pwm_off_exit + +t0_int_pwm_off_damped_light: +IF DAMPED_MODE_ENABLE == 1 + setb Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator usable status always for damped light mode on fully damped capable escs +ENDIF + All_nFETs_Off ; Switch off all nfets + mov A, Comm_Phase ; Turn on pfets according to commutation phase + jb ACC.2, t0_int_pwm_off_comm_4_5_6 + jb ACC.1, t0_int_pwm_off_comm_2_3 + +IF DAMPED_MODE_ENABLE == 0 + AnFET_On ; Comm phase 1 - turn on A +ELSE + mov A, #PFETON_DELAY + djnz ACC, $ + CnFET_On ; Comm phase 1 - turn on C +ENDIF + jmp t0_int_pwm_off_exit + +t0_int_pwm_off_comm_2_3: + jb ACC.0, t0_int_pwm_off_comm_3 +IF DAMPED_MODE_ENABLE == 0 + BnFET_On ; Comm phase 2 - turn on B +ELSE + mov A, #PFETON_DELAY + djnz ACC, $ + CnFET_On ; Comm phase 2 - turn on C +ENDIF + jmp t0_int_pwm_off_exit + +t0_int_pwm_off_comm_3: +IF DAMPED_MODE_ENABLE == 0 + CnFET_On ; Comm phase 3 - turn on C +ELSE + mov A, #PFETON_DELAY + djnz ACC, $ + BnFET_On ; Comm phase 3 - turn on B +ENDIF + jmp t0_int_pwm_off_exit + +t0_int_pwm_off_comm_4_5_6: + jb ACC.1, t0_int_pwm_off_comm_6 + jb ACC.0, t0_int_pwm_off_comm_5 + +IF DAMPED_MODE_ENABLE == 0 + AnFET_On ; Comm phase 4 - turn on A +ELSE + mov A, #PFETON_DELAY + djnz ACC, $ + BnFET_On ; Comm phase 4 - turn on B +ENDIF + jmp t0_int_pwm_off_exit + +t0_int_pwm_off_comm_5: +IF DAMPED_MODE_ENABLE == 0 + BnFET_On ; Comm phase 5 - turn on B +ELSE + mov A, #PFETON_DELAY + djnz ACC, $ + AnFET_On ; Comm phase 5 - turn on A +ENDIF + jmp t0_int_pwm_off_exit + +t0_int_pwm_off_comm_6: +IF DAMPED_MODE_ENABLE == 0 + CnFET_On ; Comm phase 6 - turn on C +ELSE + mov A, #PFETON_DELAY + djnz ACC, $ + AnFET_On ; Comm phase 6 - turn on A +ENDIF + +t0_int_pwm_off_exit: ; Exit from pwm off cycle + mov TL1, #0 ; Reset timer1 + pop ACC ; Restore preserved registers + pop PSW + All_nFETs_Off ; Switch off all nfets + setb EA ; Enable all interrupts + reti + +t0_int_pwm_off_fullpower_exit: ; Exit from pwm off cycle, leaving power on + pop ACC ; Restore preserved registers + pop PSW + setb EA ; Enable all interrupts + reti + + + +pwm_nofet_on: ; Dummy pwm on cycle + ajmp t0_int_pwm_on_exit + +pwm_afet_on: ; Pwm on cycle afet on (bfet off) + AnFET_on + BnFET_off + ajmp t0_int_pwm_on_exit + +pwm_bfet_on: ; Pwm on cycle bfet on (cfet off) + BnFET_on + CnFET_off + ajmp t0_int_pwm_on_exit + +pwm_cfet_on: ; Pwm on cycle cfet on (afet off) + CnFET_on + AnFET_off + ajmp t0_int_pwm_on_exit + +pwm_anfet_bpfet_on_fast: ; Pwm on cycle anfet on (bnfet off) and bpfet on (used in damped state 6) + ApFET_off + AnFET_on ; Switch nFETs + CpFET_off + BnFET_off + ajmp t0_int_pwm_on_exit +pwm_anfet_bpfet_on_safe: ; Pwm on cycle anfet on (bnfet off) and bpfet on (used in damped state 6) + ; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow) + ApFET_off + CpFET_off + mov A, #NFETON_DELAY ; Set full delay + djnz ACC, $ + AnFET_on ; Switch nFETs + BnFET_off + ajmp t0_int_pwm_on_exit + +pwm_anfet_cpfet_on_fast: ; Pwm on cycle anfet on (bnfet off) and cpfet on (used in damped state 5) + ApFET_off + AnFET_on ; Switch nFETs + BpFET_off + BnFET_off + ajmp t0_int_pwm_on_exit +pwm_anfet_cpfet_on_safe: ; Pwm on cycle anfet on (bnfet off) and cpfet on (used in damped state 5) + ; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow) + ApFET_off + BpFET_off + mov A, #NFETON_DELAY ; Set full delay + djnz ACC, $ + AnFET_on ; Switch nFETs + BnFET_off + ajmp t0_int_pwm_on_exit + +pwm_bnfet_cpfet_on_fast: ; Pwm on cycle bnfet on (cnfet off) and cpfet on (used in damped state 4) + BpFET_off + BnFET_on ; Switch nFETs + ApFET_off + CnFET_off + ajmp t0_int_pwm_on_exit +pwm_bnfet_cpfet_on_safe: ; Pwm on cycle bnfet on (cnfet off) and cpfet on (used in damped state 4) + ; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow) + BpFET_off + ApFET_off + mov A, #NFETON_DELAY ; Set full delay + djnz ACC, $ + BnFET_on ; Switch nFETs + CnFET_off + ajmp t0_int_pwm_on_exit + +pwm_bnfet_apfet_on_fast: ; Pwm on cycle bnfet on (cnfet off) and apfet on (used in damped state 3) + BpFET_off + BnFET_on ; Switch nFETs + CpFET_off + CnFET_off + ajmp t0_int_pwm_on_exit +pwm_bnfet_apfet_on_safe: ; Pwm on cycle bnfet on (cnfet off) and apfet on (used in damped state 3) + ; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow) + BpFET_off + CpFET_off + mov A, #NFETON_DELAY ; Set full delay + djnz ACC, $ + BnFET_on ; Switch nFETs + CnFET_off + ajmp t0_int_pwm_on_exit + +pwm_cnfet_apfet_on_fast: ; Pwm on cycle cnfet on (anfet off) and apfet on (used in damped state 2) + CpFET_off + CnFET_on ; Switch nFETs + BpFET_off + AnFET_off + ajmp t0_int_pwm_on_exit +pwm_cnfet_apfet_on_safe: ; Pwm on cycle cnfet on (anfet off) and apfet on (used in damped state 2) + ; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow) + CpFET_off + BpFET_off + mov A, #NFETON_DELAY ; Set full delay + djnz ACC, $ + CnFET_on ; Switch nFETs + AnFET_off + ajmp t0_int_pwm_on_exit + +pwm_cnfet_bpfet_on_fast: ; Pwm on cycle cnfet on (anfet off) and bpfet on (used in damped state 1) + CpFET_off + CnFET_on ; Switch nFETs + ApFET_off + AnFET_off + ajmp t0_int_pwm_on_exit +pwm_cnfet_bpfet_on_safe: ; Pwm on cycle cnfet on (anfet off) and bpfet on (used in damped state 1) + ; Delay from pFETs are turned off (only in damped mode) until nFET is turned on (pFETs are slow) + CpFET_off + ApFET_off + mov A, #NFETON_DELAY ; Set full delay + djnz ACC, $ + CnFET_on ; Switch nFETs + AnFET_off + ajmp t0_int_pwm_on_exit + +t0_int_pwm_on_exit: + ; Set timer for coming on cycle length + mov A, Current_Pwm_Limited ; Load current pwm + cpl A ; cpl is 255-x + mov TL0, A ; Write start point for timer + ; Set other variables + mov TL1, #0 ; Reset timer1 + mov Pwm_On_Cnt, #0 ; Reset pwm on event counter + setb Flags0.PWM_ON ; Set pwm on flag +t0_int_pwm_on_exit_no_timer_update: + ; Exit interrupt + pop ACC ; Restore preserved registers + pop PSW + setb EA ; Enable all interrupts + reti + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Timer2 interrupt routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +t2_int: ; Happens every 128us for low byte and every 32ms for high byte + clr EA ; Disable all interrupts + push PSW ; Preserve registers through interrupt + push ACC + setb PSW.3 ; Select register bank 1 for interrupt routines + ; Clear low byte interrupt flag + clr TF2L ; Clear interrupt flag + ; Check RC pulse timeout counter + mov A, Rcp_Timeout_Cnt ; RC pulse timeout count zero? + jz t2_int_pulses_absent ; Yes - pulses are absent + + ; Decrement timeout counter (if PWM) +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jz t2_int_skip_start ; If no flag is set (PPM) - branch + +; dec Rcp_Timeout_Cnt ; No - decrement + ajmp t2_int_skip_start + +t2_int_pulses_absent: + ; Timeout counter has reached zero, pulses are absent + mov Temp1, #RCP_MIN ; RCP_MIN as default + mov Temp2, #RCP_MIN + Read_Rcp_Int ; Look at value of Rcp_In + jnb ACC.Rcp_In, ($+5) ; Is it high? + mov Temp1, #RCP_MAX ; Yes - set RCP_MAX + Rcp_Int_First ; Set interrupt trig to first again + Rcp_Clear_Int_Flag ; Clear interrupt flag + clr Flags2.RCP_EDGE_NO ; Set first edge flag + Read_Rcp_Int ; Look once more at value of Rcp_In + jnb ACC.Rcp_In, ($+5) ; Is it high? + mov Temp2, #RCP_MAX ; Yes - set RCP_MAX + clr C + mov A, Temp1 + subb A, Temp2 ; Compare the two readings of Rcp_In + jnz t2_int_pulses_absent ; Go back if they are not equal + + jnb Flags0.RCP_MEAS_PWM_FREQ, ($+6) ; Is measure RCP pwm frequency flag set? + + mov Rcp_Timeout_Cnt, #RCP_TIMEOUT ; Yes - set timeout count to start value +; mov Pgm_Pulse_Cnt, #0 ;清除PCA中断计数 +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jz t2_int_ppm_timeout_set ; If no flag is set (PPM) - branch + +; mov Rcp_Timeout_Cnt, #RCP_TIMEOUT ; For PWM, set timeout count to start value + +t2_int_ppm_timeout_set: + mov New_Rcp, Temp1 ; Store new pulse length + setb Flags2.RCP_UPDATED ; Set updated flag + + +t2_int_skip_start: + ; Check RC pulse skip counter + mov A, Rcp_Skip_Cnt + jz t2_int_skip_end ; If RC pulse skip count is zero - end skipping RC pulse detection + + ; Decrement skip counter (only if edge counter is zero) + dec Rcp_Skip_Cnt ; Decrement + ajmp t2_int_rcp_update_start + +t2_int_skip_end: +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jz t2_int_rcp_update_start ; If no flag is set (PPM) - branch + + ; Skip counter has reached zero, start looking for RC pulses again +; Rcp_Int_Enable ; Enable RC pulse interrupt +; Rcp_Clear_Int_Flag ; Clear interrupt flag + +t2_int_rcp_update_start: + ; Process updated RC pulse + jb Flags2.RCP_UPDATED, ($+5) ; Is there an updated RC pulse available? + ajmp t2_int_pwm_exit ; No - exit + + mov A, New_Rcp ; Load new pulse value + mov Temp1, A + clr Flags2.RCP_UPDATED ; Flag that pulse has been evaluated + ; Use a gain of 1.0625x for pwm input if not governor mode +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jz t2_int_pwm_min_run ; If no flag is set (PPM) - branch +;;***************************************************** +;; Closed loop mode 选择 +;;***************************************************** +;IF MODE <= 1 ; Main or tail +; mov Temp2, #Pgm_Gov_Mode ; Governor mode? +; cjne @Temp2, #4, t2_int_pwm_min_run; Yes - branch +;ENDIF +;IF MODE == 2 ; Multi +;;读取Closed loop mode +; mov Temp2, #Pgm_Gov_Mode ; Closed loop mode? +; cjne @Temp2, #4, t2_int_pwm_min_run; Yes - branch +;ENDIF + +; ; Limit the maximum value to avoid wrap when scaled to pwm range +;;Closed loop mode = 第1项 Off +; clr C +; mov A, Temp1 +; subb A, #240 ; 240 = (255/1.0625) Needs to be updated according to multiplication factor below +; jc t2_int_rcp_update_mult + +; mov A, #240 ; Set requested pwm to max +; mov Temp1, A + +;t2_int_rcp_update_mult: +; ; Multiply by 1.0625 (optional adjustment gyro gain) +; mov A, Temp1 +; swap A ; After this "0.0625" +; anl A, #0Fh +; add A, Temp1 +; mov Temp1, A +; ; Adjust tail gain +;;读取 Multi gain +; mov Temp2, #Pgm_Motor_Gain +; cjne @Temp2, #3, ($+5) ; Is gain 1? +; ajmp t2_int_pwm_min_run ; Yes - skip adjustment +;;Multi gain = 第2选项 +; clr C +; rrc A ; After this "0.5" +; clr C +; rrc A ; After this "0.25" +; mov Bit_Access_Int, @Temp2 ; (Temp2 has #Pgm_Motor_Gain) +; jb Bit_Access_Int.0, t2_int_rcp_gain_corr ; Branch if bit 0 in gain is set +;;Multi gain = 第4选项 +; clr C +; rrc A ; After this "0.125" + +;t2_int_rcp_gain_corr: +; jb Bit_Access_Int.2, t2_int_rcp_gain_pos ; Branch if bit 2 in gain is set +;;Multi gain = 第1选项 +; clr C +; xch A, Temp1 +; subb A, Temp1 ; Apply negative correction +; mov Temp1, A +; ajmp t2_int_pwm_min_run +;;Multi gain = 第5选项 +;t2_int_rcp_gain_pos: +; add A, Temp1 ; Apply positive correction +; mov Temp1, A +; jnc t2_int_pwm_min_run ; Above max? + +; mov A, #0FFh ; Yes - limit +; mov Temp1, A +;;Multi gain = 第3选项 +t2_int_pwm_min_run: + ; Limit minimum pwm + clr C + mov A, Temp1 + subb A, Pwm_Motor_Idle ; Is requested pwm lower than minimum? + jnc t2_int_pwm_update ; No - branch + + mov A, Pwm_Motor_Idle ; Yes - limit pwm to Pwm_Motor_Idle + mov Temp1, A + +t2_int_pwm_update: + ; Check if any startup phase flags are set + mov A, Flags1 + anl A, #((1 SHL SETTLE_PHASE)+(1 SHL STEPPER_PHASE)) + jnz t2_int_pwm_exit ; Exit if any startup phase set (pwm controlled by set_startup_pwm) + + ; Update requested_pwm + mov Requested_Pwm, Temp1 ; Set requested pwm + ; Limit pwm during direct start + jnb Flags1.DIRECT_STARTUP_PHASE, t2_int_current_pwm_update + + clr C + mov A, Requested_Pwm ; Limit pwm during direct start + subb A, Pwm_Limit + jc ($+7) + + mov Requested_Pwm, Pwm_Limit + ajmp t2_int_current_pwm_update + + mov A, Requested_Pwm + add A, #11 + mov Requested_Pwm, A + +t2_int_current_pwm_update: +IF MODE <= 1 ; Main or tail + mov Temp1, #Pgm_Gov_Mode ; Governor mode? + cjne @Temp1, #4, t2_int_pwm_exit ; Yes - branch +ENDIF +IF MODE == 2 ; Multi +;读取Closed loop mode + mov Temp1, #Pgm_Gov_Mode ; Closed loop mode? + cjne @Temp1, #1, t2_int_pwm_exit ; Yes - branch +ENDIF + + ; Update current pwm, with limited throttle change rate +;Closed loop mode = Off + clr C + mov A, Requested_Pwm + subb A, Current_Pwm ; Is requested pwm larger than current pwm? + jc t2_int_set_current_pwm ; No - proceed + + mov Temp1, #Pgm_Throttle_Rate_Decoded + subb A, @Temp1 ; Is difference larger than throttle change rate? + jc t2_int_set_current_pwm ; No - proceed + + mov A, Current_Pwm ; Increase current pwm by throttle change rate + add A, @Temp1 + mov Current_Pwm, A + jnc t2_int_current_pwm_done ; Is result above max? + + mov Current_Pwm, #0FFh ; Yes - limit + jmp t2_int_current_pwm_done + +t2_int_set_current_pwm: + mov Current_Pwm, Requested_Pwm ; Set equal as default +t2_int_current_pwm_done: +IF MODE == 1 ; Tail + ; If tail, then set current_pwm_limited + mov Current_Pwm_Limited, Current_Pwm ; Default not limited + clr C + mov A, Current_Pwm ; Check against limit + subb A, Pwm_Limit + jc ($+5) ; If current pwm below limit - branch + + mov Current_Pwm_Limited, Pwm_Limit ; Limit pwm +ENDIF +IF MODE == 2 ; Multi + ; If multi, then set current_pwm_limited + mov Current_Pwm_Limited, Current_Pwm ; Default not limited + clr C + mov A, Current_Pwm ; Check against limit + subb A, Pwm_Limit + jc ($+5) ; If current pwm below limit - branch + + mov Current_Pwm_Limited, Pwm_Limit ; Limit pwm +ENDIF + +t2_int_pwm_exit: + ; Check if high byte flag is set + jb TF2H, t2h_int + pop ACC ; Restore preserved registers + pop PSW + clr PSW.3 ; Select register bank 0 for main program routines + setb EA ; Enable all interrupts + reti + +t2h_int: + ; High byte interrupt (happens every 32ms) + clr TF2H ; Clear interrupt flag + mov Temp1, #GOV_SPOOLRATE ; Load governor spool rate + ; Check RC pulse timeout counter (used here for PPM only) + mov A, Rcp_Timeout_Cnt ; RC pulse timeout count zero? + jz t2h_int_rcp_stop_check ; Yes - do not decrement + + ; Decrement timeout counter (if PPM) +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jnz t2h_int_rcp_stop_check ; If a flag is set (PWM) - branch + + dec Rcp_Timeout_Cnt ; No flag set (PPM) - decrement + +t2h_int_rcp_stop_check: + ; Check RC pulse against stop value + clr C + mov A, New_Rcp ; Load new pulse value + subb A, #RCP_STOP +; subb A, #(RCP_STOP+2) ; Check if pulse is below stop value + jc t2h_int_rcp_stop + + ; RC pulse higher than stop value, reset stop counter + mov Rcp_Stop_Cnt, #0 ; Reset rcp stop counter + ajmp t2h_int_rcp_gov_pwm + +t2h_int_rcp_stop: + ; RC pulse less than stop value, increment stop counter + mov A, Rcp_Stop_Cnt ; Load rcp stop counter + inc A ; Check if counter is max + jz t2h_int_rcp_gov_pwm ; Branch if counter is equal to max + + inc Rcp_Stop_Cnt ; Increment stop counter + +t2h_int_rcp_gov_pwm: +IF MODE == 0 ; Main + mov Temp2, #Pgm_Gov_Mode ; Governor target by arm mode? + cjne @Temp2, #2, t2h_int_rcp_gov_by_setup ; No - branch + + mov A, Gov_Active ; Is governor active? + jz t2h_int_rcp_gov_by_tx ; No - branch (this ensures soft spoolup by tx) + + clr C + mov A, Requested_Pwm + subb A, #50 ; Is requested pwm below 20%? + jc t2h_int_rcp_gov_by_tx ; Yes - branch (this enables a soft spooldown) + + mov Requested_Pwm, Gov_Arm_Target ; Yes - load arm target + +t2h_int_rcp_gov_by_setup: + mov Temp2, #Pgm_Gov_Mode ; Governor target by setup mode? + cjne @Temp2, #3, t2h_int_rcp_gov_by_tx ; No - branch + + mov A, Gov_Active ; Is governor active? + jz t2h_int_rcp_gov_by_tx ; No - branch (this ensures soft spoolup by tx) + + clr C + mov A, Requested_Pwm + subb A, #50 ; Is requested pwm below 20%? + jc t2h_int_rcp_gov_by_tx ; Yes - branch (this enables a soft spooldown) +;读取Pgm_Gov_Setup_Target + mov Temp2, #Pgm_Gov_Setup_Target ; Gov by setup - load setup target + mov Requested_Pwm, @Temp2 + +t2h_int_rcp_gov_by_tx: + clr C + mov A, Governor_Req_Pwm + subb A, Requested_Pwm ; Is governor requested pwm equal to requested pwm? + jz t2h_int_rcp_gov_pwm_done ; Yes - branch + + jc t2h_int_rcp_gov_pwm_inc ; No - if lower, then increment + + dec Governor_Req_Pwm ; No - if higher, then decrement + ajmp t2h_int_rcp_gov_pwm_done + +t2h_int_rcp_gov_pwm_inc: + inc Governor_Req_Pwm ; Increment + +t2h_int_rcp_gov_pwm_done: + djnz Temp1, t2h_int_rcp_gov_pwm ; If not number of steps processed - go back + + inc Spoolup_Limit_Cnt ; Increment spoolup count + + jnz ($+4) ; Wrapped? + + dec Spoolup_Limit_Cnt ; Yes - decrement + + djnz Spoolup_Limit_Skip, t2h_int_rcp_exit ; Jump if skip count is not reached + + mov Spoolup_Limit_Skip, #1 ; Reset skip count. Default is fast spoolup + mov Temp1, #3 ; Default fast increase + + clr C + mov A, Spoolup_Limit_Cnt + subb A, #(3*MAIN_SPOOLUP_TIME) ; No spoolup until "30"*32ms + jc t2h_int_rcp_exit + + clr C + mov A, Spoolup_Limit_Cnt + subb A, #(10*MAIN_SPOOLUP_TIME) ; Slow spoolup until "100"*32ms + jnc t2h_int_rcp_limit_middle_ramp + + mov Temp1, #1 ; Slow initial spoolup + mov Spoolup_Limit_Skip, #3 + jmp t2h_int_rcp_set_limit + +t2h_int_rcp_limit_middle_ramp: + clr C + mov A, Spoolup_Limit_Cnt + subb A, #(15*MAIN_SPOOLUP_TIME) ; Faster spoolup until "150"*32ms + jnc t2h_int_rcp_set_limit + + mov Temp1, #1 ; Faster middle spoolup + mov Spoolup_Limit_Skip, #1 + +t2h_int_rcp_set_limit: + mov A, Pwm_Limit_Spoolup ; Increment spoolup pwm + clr C + add A, Temp1 + jnc t2h_int_rcp_no_limit ; If below 255 - branch + + mov Pwm_Limit_Spoolup, #0FFh + ajmp t2h_int_rcp_exit + +t2h_int_rcp_no_limit: + mov Pwm_Limit_Spoolup, A +ENDIF +IF MODE == 2 ; Multi + mov A, Pwm_Limit_Spoolup ; Increment spoolup pwm, for a 0.8 seconds spoolup + clr C + add A, #10 + jnc t2h_int_rcp_no_limit ; If below 255 - branch + + mov Pwm_Limit_Spoolup, #0FFh + ajmp t2h_int_rcp_exit + +t2h_int_rcp_no_limit: + mov Pwm_Limit_Spoolup, A +ENDIF + +t2h_int_rcp_exit: + pop ACC ; Restore preserved registers + pop PSW + clr PSW.3 ; Select register bank 0 for main program routines + setb EA ; Enable all interrupts + reti + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Timer3 interrupt routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +t3_int: ; Used for commutation timing + clr EA ; Disable all interrupts + anl TMR3CN, #07Fh ; Clear interrupt flag + clr Flags0.T3_PENDING ; Flag that timer has wrapped + setb EA ; Enable all interrupts + reti + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; PCA interrupt routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +pca_int: ; Used for RC pulse timing + clr EA ; Disable all interrupts + push PSW ; Preserve registers through interrupt + push ACC + push B + setb PSW.3 ; Select register bank 1 for interrupt routines + +; mov A, Pca_First_Int +; cjne A, #1, ($+5) +; inc Pgm_Pulse_Cnt + ; Get PCA0 capture values + mov Temp1, PCA0CPL0 + mov Temp2, PCA0CPH0 + ; Clear interrupt flag + Rcp_Clear_Int_Flag + ; Check which edge it is + jnb Flags2.RCP_EDGE_NO, ($+5) ; Is it a first edge trig? + ajmp pca_int_second_meas_pwm_freq ; No - branch to second + + Rcp_Int_Second ; Yes - set second edge trig + setb Flags2.RCP_EDGE_NO ; Set second edge flag + ; Read RC signal level + Read_Rcp_Int + ; Test RC signal level + jb ACC.Rcp_In, ($+5) ; Is it high? + ajmp pca_int_fail_minimum ; No - jump to fail minimum + + ; RC pulse was high, store RC pulse start timestamp + mov Rcp_Prev_Edge_L, Temp1 + mov Rcp_Prev_Edge_H, Temp2 + ajmp pca_int_exit ; Exit + +pca_int_fail_minimum: + ; Prepare for next interrupt + Rcp_Int_First ; Set interrupt trig to first again + Rcp_Clear_Int_Flag ; Clear interrupt flag + clr Flags2.RCP_EDGE_NO ; Set first edge flag +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + mov A, #(1 SHL RCP_PWM_FREQ_1KHZ) + anl A, Flags3 ; Check pwm frequency flags + jnz ($+4) ; If a flag is set (PWM) - proceed + + ajmp pca_int_set_timeout ; If PPM - ignore trig as noise + + mov Temp1, #RCP_MIN ; Set RC pulse value to minimum + Read_Rcp_Int ; Test RC signal level again + jnb ACC.Rcp_In, ($+5) ; Is it high? + ajmp pca_int_set_timeout ; Yes - set new timeout and exit + + mov New_Rcp, Temp1 ; Store new pulse length + ajmp pca_int_set_timeout ; Set new timeout and exit + +pca_int_second_meas_pwm_freq: + ; Prepare for next interrupt + Rcp_Int_First ; Set first edge trig + clr Flags2.RCP_EDGE_NO ; Set first edge flag + ; Check if pwm frequency shall be measured + jb Flags0.RCP_MEAS_PWM_FREQ, ($+5) ; Is measure RCP pwm frequency flag set? + ajmp pca_int_fall ; No - skip measurements + + ; Set second edge trig only during pwm frequency measurement + Rcp_Int_Second ; Set second edge trig + Rcp_Clear_Int_Flag ; Clear interrupt flag + setb Flags2.RCP_EDGE_NO ; Set second edge flag + ; Store edge data to RAM + mov Rcp_Edge_L, Temp1 + mov Rcp_Edge_H, Temp2 + ; Calculate pwm frequency + clr C + mov A, Temp1 + subb A, Rcp_PrePrev_Edge_L + mov Temp1, A ;存低字节差 + mov A, Temp2 + subb A, Rcp_PrePrev_Edge_H + mov Temp2, A ;存高字节差 +; clr A +; mov Temp4, A + ; Check if pwm frequency is 8kHz + mov Temp3, #250 ; Set default period tolerance requirement +; clr C +; mov A, Temp1 +; subb A, #low(360) ; If below 180us, 8kHz pwm is assumed +; mov A, Temp2 +; subb A, #high(360) +; jnc pca_int_check_4kHz + +; clr A +; setb ACC.RCP_PWM_FREQ_8KHZ +; mov Temp4, A +; mov Temp3, #15 ; Set period tolerance requirement +; ajmp pca_int_restore_edge + +;pca_int_check_4kHz: +; ; Check if pwm frequency is 4kHz +; clr C +; mov A, Temp1 +; subb A, #low(720) ; If below 360us, 4kHz pwm is assumed +; mov A, Temp2 +; subb A, #high(720) +; jnc pca_int_check_2kHz + +; clr A +; setb ACC.RCP_PWM_FREQ_4KHZ +; mov Temp4, A +; mov Temp3, #30 ; Set period tolerance requirement +; ajmp pca_int_restore_edge + +;pca_int_check_2kHz: +; ; Check if pwm frequency is 2kHz +; clr C +; mov A, Temp1 +; subb A, #low(1440) ; If below 720us, 2kHz pwm is assumed +; mov A, Temp2 +; subb A, #high(1440) +; jnc pca_int_check_1kHz + +; clr A +; setb ACC.RCP_PWM_FREQ_2KHZ +; mov Temp4, A +; mov Temp3, #60 ; Set period tolerance requirement +; ajmp pca_int_restore_edge + +;pca_int_check_1kHz: + ; Check if pwm frequency is 1kHz + clr C + mov A, Temp1 + subb A, #low(2200) ; If below 1100us, 1kHz pwm is assumed + mov A, Temp2 + subb A, #high(2200) + jnc pca_int_restore_edge + + ajmp pca_int_set_timeout +; clr A +; setb ACC.RCP_PWM_FREQ_1KHZ +; mov Temp4, A +; mov Temp3, #120 ; Set period tolerance requirement + +pca_int_restore_edge: + ; Calculate difference between this period and previous period + clr C + mov A, Temp1 + subb A, Rcp_Prev_Period_L + mov Temp5, A + mov A, Temp2 + subb A, Rcp_Prev_Period_H + mov Temp6, A + ; Make positive + jnb ACC.7, pca_int_check_diff + mov A, Temp5 + cpl A + add A, #1 + mov Temp5, A + mov A, Temp6 + cpl A + mov Temp6, A + +pca_int_check_diff: + ; Check difference + mov Rcp_Period_Diff_Accepted, #0 ; Set not accepted as default + jnz pca_int_store_data ; Check if high byte is zero + + clr C + mov A, Temp5 + subb A, Temp3 ; Check difference + jnc pca_int_store_data + + mov Rcp_Period_Diff_Accepted, #1 ; Set accepted + +pca_int_store_data: + ; Store previous period + mov Rcp_Prev_Period_L, Temp1 + mov Rcp_Prev_Period_H, Temp2 + ; Restore edge data from RAM + mov Temp1, Rcp_Edge_L + mov Temp2, Rcp_Edge_H + ; Store pre previous edge + mov Rcp_PrePrev_Edge_L, Temp1 + mov Rcp_PrePrev_Edge_H, Temp2 + +pca_int_fall: + clr A + mov Temp4, A + ; RC pulse edge was second, calculate new pulse length + clr C + mov A, Temp1 + subb A, Rcp_Prev_Edge_L + mov Temp1, A + mov A, Temp2 + subb A, Rcp_Prev_Edge_H + mov Temp2, A + +; jnb Flags3.RCP_PWM_FREQ_8KHZ, ($+5) ; Is RC input pwm frequency 8kHz? +; ajmp pca_int_pwm_divide_done ; Yes - branch forward + +; jnb Flags3.RCP_PWM_FREQ_4KHZ, ($+5) ; Is RC input pwm frequency 4kHz? +; ajmp pca_int_pwm_divide ; Yes - branch forward + + mov A, Temp2 ; No - 2kHz. Divide by 2 again + clr C + rrc A + mov Temp2, A + mov A, Temp1 + rrc A + mov Temp1, A + +; jnb Flags3.RCP_PWM_FREQ_2KHZ, ($+5) ; Is RC input pwm frequency 2kHz? +; ajmp pca_int_pwm_divide ; Yes - branch forward + + mov A, Temp2 ; No - 1kHz. Divide by 2 again + clr C + rrc A + mov Temp2, A + mov A, Temp1 + rrc A + mov Temp1, A + + clr C + mov A, Temp1 + subb A, #250 ; If below 500us, + mov A, Temp2 + subb A, #0 + jnc ($+9) + + mov A, Initial_Arm + cjne A, #1, ($+5) + + ajmp pca_int_pwm_divide + +; jnb Flags3.RCP_PWM_FREQ_1KHZ, ($+5) ; Is RC input pwm frequency 1kHz? +; ajmp pca_int_pwm_divide ; Yes - branch forward + + mov A, Temp2 ; No - PPM. Divide by 2 (to bring range to 256) and move to Temp5/6 + clr C + rrc A + mov Temp6, A + mov A, Temp1 + rrc A + mov Temp5, A + ; Skip range limitation if pwm frequency measurement + jb Flags0.RCP_MEAS_PWM_FREQ, pca_int_ppm_check_full_range + + ; Check if 2160us or above (in order to ignore false pulses) + clr C + mov A, Temp5 ; Is pulse 2160us or higher? + subb A, #28 + mov A, Temp6 + subb A, #2 + jc ($+5) ; No - proceed + + ljmp pca_int_set_timeout ; Yes - ignore pulse + + ; Check if below 800us (in order to ignore false pulses) + mov A, Temp6 + jnz pca_int_ppm_check_full_range + + clr C + mov A, Temp5 ; Is pulse below 800us? + subb A, #200 + jnc pca_int_ppm_check_full_range ; No - proceed + + jmp pca_int_exit ; Yes - ignore pulse + +pca_int_ppm_check_full_range: + ; Calculate "1000us" plus throttle minimum + mov A, #0 ; Set 1000us as default minimum + jb Flags3.FULL_THROTTLE_RANGE, pca_int_ppm_calculate ; Check if full range is chosen + + mov Temp1, #Pgm_Ppm_Min_Throttle ; Min throttle value is in 4us units + mov A, @Temp1 + +pca_int_ppm_calculate: + add A, #250 + mov Temp7, A + clr A + addc A, #0 + mov Temp8, A + + clr C + mov A, Temp5 ; Subtract minimum + subb A, Temp7 + mov Temp5, A + mov A, Temp6 + subb A, Temp8 + mov Temp6, A + jnc pca_int_ppm_neg_checked ; Is result negative? + + mov Temp1, #RCP_MIN ; Yes - set to minimum + mov Temp2, #0 + ajmp pca_int_pwm_divide_done + +pca_int_ppm_neg_checked: + clr C ; Check that RC pulse is within legal range (1000+4*255=2020) + mov A, Temp5 + subb A, #RCP_MAX + mov A, Temp6 + subb A, #0 + jc pca_int_ppm_max_checked + + mov Temp1, #RCP_MAX + mov Temp2, #0 + ajmp pca_int_pwm_divide_done + +pca_int_ppm_max_checked: + mov A, Temp5 ; Multiply throttle value by gain + mov B, Ppm_Throttle_Gain + mul AB + xch A, B + mov C, B.7 ; Multiply result by 2 (unity gain is 128) + rlc A + mov Temp1, A ; Transfer to Temp1/2 + mov Temp2, #0 + jc pca_int_ppm_limit_after_mult + + jmp pca_int_limited + +pca_int_ppm_limit_after_mult: + mov Temp1, #RCP_MAX + mov Temp2, #0 + jmp pca_int_limited + +pca_int_pwm_divide: +;480us + clr C + mov A, Temp1 + subb A, #240 + mov A, Temp2 + subb A, #0 + jnc pca_int_set_timeout +;40us + clr C + mov A, Temp1 + subb A, #20 + mov A, Temp2 + subb A, #0 + jc pca_int_set_timeout + + clr A + setb ACC.RCP_PWM_FREQ_1KHZ + mov Temp4, A +; mov Rcp_Period_Diff_Accepted, #1 + ajmp pca_int_limited + +pca_int_pwm_divide_done: + ; Check that RC pulse is within legal range + clr C + mov A, Temp1 + subb A, #RCP_MAX + mov A, Temp2 + subb A, #0 + jc pca_int_limited + + mov Temp1, #RCP_MAX + +pca_int_limited: + ; RC pulse value accepted + mov New_Rcp, Temp1 ; Store new pulse length + setb Flags2.RCP_UPDATED ; Set updated flag +; jb Flags0.RCP_MEAS_PWM_FREQ, ($+5) ; Is measure RCP pwm frequency flag set? +; ajmp pca_int_set_timeout ; No - skip measurements + +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + mov A, #(1 SHL RCP_PWM_FREQ_1KHZ) + cpl A + anl A, Flags3 ; Clear all pwm frequency flags + orl A, Temp4 ; Store pwm frequency value in flags + mov Flags3, A + +pca_int_set_timeout: + mov Rcp_Timeout_Cnt, #RCP_TIMEOUT ; Set timeout count to start value +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + mov A, #(1 SHL RCP_PWM_FREQ_1KHZ) + anl A, Flags3 ; Check pwm frequency flags + jnz pca_int_ppm_timeout_set ; If a flag is set - branch + + mov Rcp_Timeout_Cnt, #RCP_TIMEOUT_PPM ; No flag set means PPM. Set timeout count + +pca_int_ppm_timeout_set: +; jnb Flags0.RCP_MEAS_PWM_FREQ, ($+5) ; Is measure RCP pwm frequency flag set? +; ajmp pca_int_exit ; Yes - exit + +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jz pca_int_exit ; If no flag is set (PPM) - branch + +; Rcp_Int_Disable ; Disable RC pulse interrupt + +pca_int_exit: ; Exit interrupt routine + mov Rcp_Skip_Cnt, #RCP_SKIP_RATE ; Load number of skips +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + mov A, #(1 SHL RCP_PWM_FREQ_1KHZ) + anl A, Flags3 ; Check pwm frequency flags + jnz ($+5) ; If a flag is set (PWM) - branch + + mov Rcp_Skip_Cnt, #10 ; Load number of skips + + pop B ; Restore preserved registers + pop ACC + pop PSW + clr PSW.3 ; Select register bank 0 for main program routines + setb EA ; Enable all interrupts + reti + + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Wait xms ~(x*4*250) (Different entry points) +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +wait1ms: + mov Temp2, #1 + ajmp waitxms_o + +wait3ms: + mov Temp2, #3 + ajmp waitxms_o + +wait10ms: + mov Temp2, #10 + ajmp waitxms_o + +wait30ms: + mov Temp2, #30 + ajmp waitxms_o + +wait100ms: + mov Temp2, #100 + ajmp waitxms_o + +wait200ms: + mov Temp2, #200 + ajmp waitxms_o + +waitxms_o: ; Outer loop + mov Temp1, #23 +waitxms_m: ; Middle loop + clr A + djnz ACC, $ ; Inner loop (42.7us - 1024 cycles) + djnz Temp1, waitxms_m + djnz Temp2, waitxms_o + ret +;**;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Wait 1 second routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +wait1s: + mov Temp5, #5 +wait1s_loop: + call wait200ms + djnz Temp5, wait1s_loop + ret + + +;**;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Success beep routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +success_beep: + clr EA ; Disable all interrupts + call beep_f1 + call beep_f2 + call beep_f3 +; call beep_f4 + call wait10ms + call beep_f1 + call beep_f2 + call beep_f3 +; call beep_f4 +; call wait10ms +; call beep_f1 +; call beep_f2 +; call beep_f3 +; call beep_f4 + setb EA ; Enable all interrupts + ret + + +;**;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Success beep inverted routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +success_beep_inverted: + clr EA ; Disable all interrupts +; call beep_f4 + call beep_f3 + call beep_f2 + call beep_f1 + call wait10ms +; call beep_f4 + call beep_f3 + call beep_f2 + call beep_f1 + call wait10ms +; call beep_f4 +; call beep_f3 +; call beep_f2 +; call beep_f1 + setb EA ; Enable all interrupts + ret + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Function and parameter value beep routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +function_paraval_beep: + mov Temp7, Tx_Pgm_Func_No ; Function no + mov Temp8, Tx_Pgm_Paraval_No ; Parameter value no + clr EA ; Disable all interrupts +;//////function_beep: +;////// call beep_f1 +;////// call beep_f1 +;////// call beep_f1 +;////// call wait10ms +;////// djnz Temp7, function_beep +;//////paraval_beep: +;////// call beep_f4 +;////// call wait10ms +;////// djnz Temp8, paraval_beep +;function_beep: + jnb Flags0.PROGRAM_FUNC_FLAG,paraval_beep ;跳到参数选项叫 +function_no_6: + clr C + mov A,Temp7 + subb A,#5 + jc function_below_beep + jz function_beep + mov Temp7, A +function_beep: + call beep_f3 + call beep_f3 + call beep_f3 + call beep_f3 + call beep_f3 + call wait30ms + + cjne Temp7,#5,($+5) + ajmp fun_par_end + + +function_below_beep: + call beep_f1 + call beep_f1 + call beep_f1 + call wait100ms + djnz Temp7, function_below_beep + ajmp fun_par_end + +paraval_beep: + clr A + mov Temp7,A + + clr C + mov A,Temp8 + subb A,#10 ;参数数 - 10 + jc paraval_no_7 ;<10 + inc Temp7 ;>=10 + inc Temp7 + jz paraval_below_beep + mov Temp8,A ;>=存差 + ajmp paraval_below_beep + +paraval_no_7: + clr C + mov A,Temp8 + subb A,#5 + jc paraval_no_below + inc Temp7 + jz paraval_below_beep + mov Temp8,A ;>=存差 + +paraval_below_beep: + call beep_f2 + call beep_f2 + call beep_f2 + call wait30ms + djnz Temp7,paraval_below_beep + cjne Temp8,#10,($+5) + ajmp fun_par_end + cjne Temp8,#5,($+5) + ajmp fun_par_end + +paraval_no_below: + call wait100ms + call beep_f4 + call wait100ms + djnz Temp8, paraval_no_below +fun_par_end: + setb EA ; Enable all interrupts + + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 接收一个数据(一个字节) +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +receive_a_byte: + mov Temp8,#0 + mov Commu_Data_Buffer, #0 + mov Temp4, #8 +wait_high: + + Read_Rcp_Int + ; Test RC signal level + jb ACC.Rcp_In,start_t2 + + jnb TF1, wait_high + +; setb Flags3.ERRO_DATA +; ajmp receive_exit + +start_t2: + mov TL0, #00h + mov TH0, #00h + setb TR0 ;启动T0 +wait_low: + Read_Rcp_Int + ; Test RC signal level + jnb ACC.Rcp_In, measure_wide + + jnb TF1, wait_low + +; setb Flags3.ERRO_DATA +; ajmp receive_exit + +measure_wide: + clr TR0 ;停止T0 +; mov Temp1, TL0 +; mov Temp2, TH0 + +; mov New_Rcp, Temp1 + mov New_Rcp, TL0 + clr C + mov A, New_Rcp + subb A, #20 ;40us + jc receive_a_erro_byte ;<80us 错误字节 + + clr C + mov A, New_Rcp + subb A, #78 ;156us + jnc receive_bit_one ;>160us 进行位1判断 + + mov A, Temp8 ;取0 + rl A + mov Temp8, A + ajmp receive_a_byte_exit + +receive_bit_one: + clr C + mov A, New_Rcp + subb A, #102 ;240us + jc receive_a_erro_byte ;160< New_Rcp <240us 错误字节 + + clr C + mov A, New_Rcp + subb A, #204 ;400us + jnc receive_a_erro_byte ;>400us 错误字节 + + mov A, Temp8 ;取1 + rl A + inc A + mov Temp8, A + ajmp receive_a_byte_exit + +receive_a_erro_byte: + setb Flags3.ERRO_DATA + +receive_a_byte_exit: + jnb TF1, ($+7) + + setb Flags3.ERRO_DATA + ajmp ($+6) + + djnz Temp4, wait_high + mov Commu_Data_Buffer, Temp8 +receive_exit: + ret + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 接收一组数据 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +receive_bytes: + mov Temp5, #48 + mov Temp2, #Tag_Temporary_Storage ; Set RAM address + mov Commu_Data_Buffer, #0 +wait_receive_bytes: + call receive_a_byte + mov @Temp2, Commu_Data_Buffer + inc Temp2 + djnz Temp5, wait_receive_bytes + + ret + +store_tags: +; call store_tags + mov Temp2, #Tag_Temporary_Storage ; Set RAM address + mov Temp5, #48 +store_tag: + cjne Temp5, #45, store_two + mov Temp1, #Pgm_Gov_Mode + jmp store_eep +store_two: + cjne Temp5, #44, store_three + mov Temp1, #Pgm_Low_Voltage_Lim + jmp store_eep +store_three: + cjne Temp5, #43, store_four + mov Temp1, #Pgm_Low_Voltage_Ctl + jmp store_eep +store_four: + cjne Temp5, #40, store_five + mov Temp1, #Pgm_Startup_Pwr + jmp store_eep +store_five: + cjne Temp5, #39, store_six + mov Temp1, #Pgm_Pwm_Freq + jmp store_eep +store_six: + cjne Temp5, #28, store_seven + mov Temp1, #Pgm_Comm_Timing + jmp store_eep +store_seven: + cjne Temp5, #27, store_next + mov Temp1, #Pgm_Damping_Force + +store_eep: + mov Commu_Data_Buffer, @Temp2 +;setb P1.7 + mov @Temp1, Commu_Data_Buffer + + call erase_and_store_all_in_eeprom + clr EA + +store_next: + inc Temp2 + djnz Temp5, store_tag + + ret + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 发送一个数据(一个字节) +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +send_a_byte: + clr EA + setb TR0 ;启动T0 + mov Temp4, #8 + mov A, Commu_Data_Buffer ;读取要发送的数据 +wait_send_a_byte: + setb P0.7 ;发送高电平 + +; mov A, Commu_Data_Buffer ;读取要发送的数据 + jnb ACC.7, low_value ;($+8) + + mov TL0, #067h ;发送1脉宽长 + ajmp high_value ;($+5) + +low_value: + mov TL0, #0CDh ;发送0脉宽长 + +high_value: + mov TH0, #0FFh + + clr TF0 ;清T0溢出标志 + jnb TF0, $ ;等待T0溢出 高电平发送完成 + + clr P0.7 ;发送低电平 + mov TL0, #0CDh ; + mov TH0, #0FFh + + clr TF0 ;清T0溢出标志 + jnb TF0, $ ;等待T0溢出 低电平发送完成 + + rl A ;发送下一位 +; mov Commu_Data_Buffer, A + djnz Temp4, wait_send_a_byte + + ret + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 发送一组数据 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +send_bytes: + clr P0.7 +; mov A, P0MDOUT +; orl A, #080h + mov P0MDOUT, #80h ;设置成推挽输出 + mov Temp5, #48 +; mov Temp2, #Tag_Temporary_Storage ; Set RAM address + mov Temp1, #Pgm_Fir_Key +wait_send_bytes: + mov Commu_Data_Buffer, @Temp1 + inc Temp1 + + call send_a_byte ;逐个字节发送 + + djnz Temp5, wait_send_bytes + +; mov A, P0MDOUT +; anl A, #07Fh + mov P0MDOUT, #7Fh ;设置成漏极输出 + setb P0.7 + + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 编程卡校验和 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +get_commu_buffers_sum: + mov Commu_Sum, #0 + mov Temp5, #48 + mov Temp2, #Tag_Temporary_Storage ; Set RAM address +wait_get_commu_buffers_sum: + mov A, @Temp2 + clr C + addc A, Commu_Sum + mov Commu_Sum, A + inc Temp2 + djnz Temp5, wait_get_commu_buffers_sum + + ret + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 清零校验和 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +set_commu_sum_to_zero: + mov Temp8, #0 + mov Temp5, #47 + mov Temp2, #Tag_Temporary_Storage ; Set RAM address +wait_set_commu_sum_to_zero: + mov A, @Temp2 + clr C + addc A, Temp8 + mov Temp8, A + inc Temp2 + + djnz Temp5, wait_set_commu_sum_to_zero + + cpl A + inc A + mov @Temp2, A ;写最后一个字节 + + ret + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 读取EEPROM参数 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;check_parameters: +; mov Temp5, #48 ; Number of tags +; mov Temp2, #Tag_Temporary_Storage ; Set RAM address +; mov Temp1, #Bit_Access +; mov DPTR, #Eep_ESC_Layout ; Set flash address +;read_eep: +; call read_eeprom_byte +; mov A, Bit_Access +; mov @Temp2, A ; Write to RAM +; inc Temp2 +; inc DPTR +; djnz Temp5, read_eep + +; call get_commu_buffers_sum + +; mov A, Commu_Sum +; jnz set_parameters_default +;;读取首字节 +; mov Temp2, #Tag_Temporary_Storage ; Set RAM address +; mov Temp1, #Bit_Access +; mov DPTR, #Eep_ESC_Layout ; Set flash address +; call read_eeprom_byte +; mov A, Bit_Access +; cjne A, #66h, set_parameters_default +;;设置默认参数 +;set_parameters_default: +; mov Temp5, #48 +; mov Temp2, #Tag_Temporary_Storage ; Set RAM address +; mov DPTR, #FINISH_KEYWORD_TABLE +;wait_set_parameters_default: +; clr A +; movc A, @A+DPTR +; mov @Temp2, A +; inc Temp2 +; inc DPTR +; djnz Temp5, wait_set_parameters_default + +; call set_commu_sum_to_zero + +; ret + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 编程卡编程函数 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +program_by_card: +; clr EA + mov Commu_Data_Buffer, #0 + call wait10ms + clr Flags3.ERRO_DATA ;清错误字节标志 + + mov TL1, #00h + mov TH1, #00h + setb TR1 ; 启动T1 + clr TF1 ;清T1溢出标志 + + call receive_a_byte ;读取一个字节(关键字) + + jb Flags3.ERRO_DATA, program_by_card ;接收到错误字节,则重新接收 + + mov A, Commu_Data_Buffer ;读接收到的字节 + cjne A, #05h, receive_next_keyword ;判断是否关键字 0x05 + call wait3ms + + call send_bytes + + ljmp program_by_card + +receive_next_keyword: + + cjne A, #09h, program_by_card ;判断是否关键字 0x09 + mov Commu_Data_Buffer, #0 + mov TL1, #00h + mov TH1, #00h + setb TR1 ;启动T1 + clr TF1 ;清T1溢出标志 + + call receive_bytes ;读取一组数据 + + call get_commu_buffers_sum + mov A, Commu_Sum ;读取校验和 + jnz program_by_card ;判断校验和 + + mov Temp2, #Tag_Temporary_Storage ; Set RAM address + mov A, @Temp2 ;读取首字节 + cjne A, #66h, program_by_card ;判断首字节 + + call wait1ms + clr P0.7 +; mov A, P0MDOUT +; orl A, #080h ;设置成推挽输出 + mov P0MDOUT, #080h + mov Commu_Data_Buffer, #088h + + call send_a_byte ;逐个字节发送 +; mov A, P0MDOUT +; anl A, #07Fh ;设置成漏极输出 + mov P0MDOUT, #07Fh + setb P0.7 + call store_tags ;存一组数据 +; call erase_and_store_all_in_eeprom +; clr EA +;clr P1.7 + ljmp program_by_card + + ret + + + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Beeper routines (4 different entry points) +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +beep_f1: ; Entry point 1, load beeper frequency 1 settings + mov Temp3, #18 ; Off wait loop length + mov Temp4, #100 ; Number of beep pulses Mos开关次数 + ajmp beep + +beep_f2: ; Entry point 2, load beeper frequency 2 settings + mov Temp3, #14 + mov Temp4, #120 ;Mos开关次数 + ajmp beep + +beep_f3: ; Entry point 3, load beeper frequency 3 settings + mov Temp3, #12 + mov Temp4, #160 ;Mos开关次数 + ajmp beep + +beep_f4: ; Entry point 4, load beeper frequency 4 settings + mov Temp3, #9 + mov Temp4, #180 ;Mos开关次数 + ajmp beep + +beep: ; Beep loop start + mov Temp5, Current_Pwm_Limited ; Store value + mov Current_Pwm_Limited, #1 ; Set to a nonzero value + mov Temp2, #2 ; Must be an even number (or direction will change) +beep_onoff: + cpl Flags3.PGM_DIR_REV ; Toggle between using A fet and C fet 切换A、C up导通 + clr A + BpFET_off ; BpFET off + djnz ACC, $ ; Allow some time after pfet is turned off + BnFET_on ; BnFET on (in order to charge the driver of the BpFET) + djnz ACC, $ ; Let the nfet be turned on a while + BnFET_off ; BnFET off again + djnz ACC, $ ; Allow some time after nfet is turned off + BpFET_on ; BpFET on + djnz ACC, $ ; Allow some time after pfet is turned on + ; Turn on nfet + AnFET_on ; AnFET on + mov A, Beep_Strength + djnz ACC, $ + ; Turn off nfet + AnFET_off ; AnFET off + mov A, #100 ; 25祍 off + djnz ACC, $ + djnz Temp2, beep_onoff + ; Copy variable + mov A, Temp3 + mov Temp1, A +beep_off: ; Fets off loop + djnz ACC, $ + djnz Temp1, beep_off + +beep_recharge_done: + djnz Temp4, beep + BpFET_off ; BpFET off + mov Current_Pwm_Limited, Temp5 ; Restore value + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Division 16bit unsigned by 16bit unsigned +; +; Dividend shall be in Temp2/Temp1, divisor in Temp4/Temp3 +; Result will be in Temp2/Temp1 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +div_u16_by_u16: + clr C + mov Temp5, #0 + mov Temp6, #0 + mov B, #0 +div_u16_by_u16_div1: + inc B ; Increment counter for each left shift + mov A, Temp3 ; Shift left the divisor + rlc A + mov Temp3, A + mov A, Temp4 + rlc A + mov Temp4, A + jnc div_u16_by_u16_div1 ; Repeat until carry flag is set from high-byte +div_u16_by_u16_div2: + mov A, Temp4 ; Shift right the divisor + rrc A + mov Temp4, A + mov A, Temp3 + rrc A + mov Temp3, A + clr C + mov A, Temp2 ; Make a safe copy of the dividend + mov Temp8, A + mov A, Temp1 + mov Temp7, A + mov A, Temp1 ; Move low-byte of dividend into accumulator + subb A, Temp3 ; Dividend - shifted divisor = result bit (no factor, only 0 or 1) + mov Temp1, A ; Save updated dividend + mov A, Temp2 ; Move high-byte of dividend into accumulator + subb A, Temp4 ; Subtract high-byte of divisor (all together 16-bit substraction) + mov Temp2, A ; Save updated high-byte back in high-byte of divisor + jnc div_u16_by_u16_div3 ; If carry flag is NOT set, result is 1 + mov A, Temp8 ; Otherwise result is 0, save copy of divisor to undo subtraction + mov Temp2, A + mov A, Temp7 + mov Temp1, A +div_u16_by_u16_div3: + cpl C ; Invert carry, so it can be directly copied into result + mov A, Temp5 + rlc A ; Shift carry flag into temporary result + mov Temp5, A + mov A, Temp6 + rlc A + mov Temp6,A + djnz B, div_u16_by_u16_div2 ;Now count backwards and repeat until "B" is zero + mov A, Temp6 ; Move result to Temp2/Temp1 + mov Temp2, A + mov A, Temp5 + mov Temp1, A + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Multiplication 16bit signed by 8bit unsigned +; +; Multiplicand shall be in Temp2/Temp1, multiplicator in Temp3 +; Result will be in Temp2/Temp1. Result will divided by 16 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +mult_s16_by_u8_div_16: + mov A, Temp1 ; Read input to math registers + mov B, Temp2 + mov Bit_Access, Temp3 + setb PSW.4 ; Select register bank 2 for math routines + mov Temp1, A ; Store in math registers + mov Temp2, B + mov Temp4, #0 ; Set sign in Temp4 and test sign + jnb B.7, mult_s16_by_u8_positive + + mov Temp4, #0FFh + cpl A + add A, #1 + mov Temp1, A + mov A, Temp2 + cpl A + addc A, #0 + mov Temp2, A +mult_s16_by_u8_positive: + mov A, Temp1 ; Multiply LSB with multiplicator + mov B, Bit_Access + mul AB + mov Temp6, B ; Place MSB in Temp6 + mov Temp1, A ; Place LSB in Temp1 (result) + mov A, Temp2 ; Multiply MSB with multiplicator + mov B, Bit_Access + mul AB + mov Temp8, B ; Place in Temp8/7 + mov Temp7, A + mov A, Temp6 ; Add up + add A, Temp7 + mov Temp2, A + mov A, #0 + addc A, Temp8 + mov Temp3, A + mov Temp5, #4 ; Set number of divisions +mult_s16_by_u8_div_loop: + clr C ; Rotate right + mov A, Temp3 + rrc A + mov Temp3, A + mov A, Temp2 + rrc A + mov Temp2, A + mov A, Temp1 + rrc A + mov Temp1, A + djnz Temp5, mult_s16_by_u8_div_loop + + mov B, Temp4 ; Test sign + jnb B.7, mult_s16_by_u8_exit + + mov A, Temp1 + cpl A + add A, #1 + mov Temp1, A + mov A, Temp2 + cpl A + addc A, #0 + mov Temp2, A + +mult_s16_by_u8_exit: + mov A, Temp1 ; Store output + mov B, Temp2 + clr PSW.4 ; Select normal register bank + mov Temp1, A + mov Temp2, B + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Calculate governor routines +; +; No assumptions +; +; Governs headspeed based upon the Comm_Period4x variable and pwm +; The governor task is split into several routines in order to distribute processing time +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; First governor routine - calculate governor target +IF MODE <= 1 ; Main or tail +calc_governor_target: + mov Temp1, #Pgm_Gov_Mode ; Governor mode? + cjne @Temp1, #4, governor_speed_check ; Yes + jmp calc_governor_target_exit ; No + +governor_speed_check: + ; Stop governor for stop RC pulse + clr C + mov A, New_Rcp ; Check RC pulse against stop value + subb A, #RCP_STOP ; Is pulse below stop value? + jc governor_deactivate ; Yes - deactivate + + ; Skip speed check if governor is alrady active + mov A, Gov_Active + jnz governor_target_calc + + ; Check speed (do not run governor for low speeds) + mov Temp1, #05h ; Default high range activation limit value (~62500 eRPM) + clr C + mov Temp2, #Pgm_Gov_Range + cjne @Temp2, #2, ($+5) + + mov Temp1, #12h ; Low range activation limit value (~17400 eRPM) + + clr C + mov A, Comm_Period4x_L + subb A, #00h + mov A, Comm_Period4x_H + subb A, Temp1 + jc governor_activate ; If speed above min limit - run governor + +governor_deactivate: + mov Current_Pwm, Requested_Pwm ; Set current pwm to requested + clr A + mov Gov_Target_L, A ; Set target to zero + mov Gov_Target_H, A + mov Gov_Integral_L, A ; Set integral to zero + mov Gov_Integral_H, A + mov Gov_Integral_X, A + mov Gov_Active, A + jmp calc_governor_target_exit + +governor_activate: + mov Gov_Active, #1 +governor_target_calc: + ; Governor calculations + clr C + mov Temp2, #Pgm_Gov_Range + mov A, @Temp2 ; Check high or low range (Temp2 has #Pgm_Gov_Range) + subb A, #2 + jz calc_governor_target_low + + mov A, Governor_Req_Pwm ; Load governor requested pwm + cpl A ; Calculate 255-pwm (invert pwm) + ; Calculate comm period target (1 + 2*((255-Requested_Pwm)/256) - 0.25) + rlc A ; Msb to carry + rlc A ; To bit0 + mov Temp2, A ; Now 1 lsb is valid for H + rrc A + mov Temp1, A ; Now 7 msbs are valid for L + mov A, Temp2 + anl A, #01h ; Calculate H byte + inc A ; Add 1 + mov Temp2, A + mov A, Temp1 + anl A, #0FEh ; Calculate L byte + clr C + subb A, #40h ; Subtract 0.25 + mov Temp1, A + mov A, Temp2 + subb A, #0 + mov Temp2, A + jmp calc_governor_store_target + +calc_governor_target_low: + mov A, Governor_Req_Pwm ; Load governor requested pwm + cpl A ; Calculate 255-pwm (invert pwm) + ; Calculate comm period target (2 + 8*((255-Requested_Pwm)/256) - 0.25) + rlc A ; Msb to carry + rlc A ; To bit0 + rlc A ; To bit1 + rlc A ; To bit2 + mov Temp2, A ; Now 3 lsbs are valid for H + rrc A + mov Temp1, A ; Now 4 msbs are valid for L + mov A, Temp2 + anl A, #07h ; Calculate H byte + inc A ; Add 1 + inc A ; Add 1 more + mov Temp2, A + mov A, Temp1 + anl A, #0F8h ; Calculate L byte + clr C + subb A, #40h ; Subtract 0.25 + mov Temp1, A + mov A, Temp2 + subb A, #0 + mov Temp2, A + +calc_governor_store_target: + ; Store governor target + mov Gov_Target_L, Temp1 + mov Gov_Target_H, Temp2 +calc_governor_target_exit: + ret +ENDIF +IF MODE == 2 ; Multi +calc_governor_target: +;读取 Closed loop mode + mov Temp1, #Pgm_Gov_Mode ; Closed loop mode? + cjne @Temp1, #1, governor_target_calc ; Yes - branch +;Closed loop mode = 第4项 Off + jmp calc_governor_target_exit ; No + +governor_target_calc: + ; Stop governor for stop RC pulse + clr C + mov A, New_Rcp ; Check RC pulse against stop value + subb A, #RCP_STOP ; Is pulse below stop value? + jc governor_deactivate ; Yes - deactivate + + jmp governor_activate ; No - activate + +governor_deactivate: + mov Current_Pwm, Requested_Pwm ; Set current pwm to requested + clr A + mov Gov_Target_L, A ; Set target to zero + mov Gov_Target_H, A + mov Gov_Integral_L, A ; Set integral to zero + mov Gov_Integral_H, A + mov Gov_Integral_X, A + mov Gov_Active, A + jmp calc_governor_target_exit + +governor_activate: + mov Temp1, #Pgm_Gov_Mode ; Store gov mode + mov A, @Temp1 + mov Temp5, A + mov Gov_Active, #1 + mov A, Requested_Pwm ; Load requested pwm + mov Governor_Req_Pwm, A ; Set governor requested pwm + ; Calculate comm period target 2*(51000/Requested_Pwm) + mov Temp1, #38h ; Load 51000 + mov Temp2, #0C7h + mov Temp3, Comm_Period4x_L ; Load comm period + mov Temp4, Comm_Period4x_H + ; Set speed range. Bare Comm_Period4x corresponds to 400k rpm, because it is 500n units +;Closed loop mode = 第1项 HiRange + clr C + mov A, Temp4 + rrc A + mov Temp4, A + mov A, Temp3 + rrc A + mov Temp3, A ; 200k eRPM range here + ; Check range + mov A, Temp5 + dec A + dec A + dec A + dec A + jz governor_activate_range_set ; 200k eRPM? - branch +;Closed loop mode = 第2项 MidRange +governor_activate_100k: + clr C + mov A, Temp4 + rrc A + mov Temp4, A + mov A, Temp3 + rrc A + mov Temp3, A ; 100k eRPM range here + mov A, Temp5 ; Check range again + dec A + dec A + dec A + jz governor_activate_range_set ; 100k eRPM? - branch +;Closed loop mode = 第3项 LoRange +governor_activate_50k: + clr C + mov A, Temp4 + rrc A + mov Temp4, A + mov A, Temp3 + rrc A + mov Temp3, A ; 50k eRPM range here +governor_activate_range_set: + call div_u16_by_u16 + ; Store governor target + mov Gov_Target_L, Temp1 + mov Gov_Target_H, Temp2 +calc_governor_target_exit: + ret +ENDIF + +; Second governor routine - calculate governor proportional error +calc_governor_prop_error: + ; Exit if governor is inactive + mov A, Gov_Active + jz calc_governor_prop_error_exit + +IF MODE <= 1 ; Main or tail + ; Load comm period and divide by 2 + clr C + mov A, Comm_Period4x_H + rrc A + mov Temp2, A + mov A, Comm_Period4x_L + rrc A + mov Temp1, A + ; Calculate error + clr C + mov A, Gov_Target_L + subb A, Temp1 + mov Temp1, A + mov A, Gov_Target_H + subb A, Temp2 + mov Temp2, A +ENDIF +IF MODE == 2 ; Multi + ; Calculate error + clr C + mov A, Gov_Target_L + subb A, Governor_Req_Pwm + mov Temp1, A + mov A, Gov_Target_H + subb A, #0 + mov Temp2, A +ENDIF + ; Check error and limit + jnc governor_check_prop_limit_pos ; Check carry + + clr C + mov A, Temp1 + subb A, #80h ; Is error too negative? + mov A, Temp2 + subb A, #0FFh + jc governor_limit_prop_error_neg ; Yes - limit + jmp governor_store_prop_error + +governor_check_prop_limit_pos: + clr C + mov A, Temp1 + subb A, #7Fh ; Is error too positive? + mov A, Temp2 + subb A, #00h + jnc governor_limit_prop_error_pos ; Yes - limit + jmp governor_store_prop_error + +governor_limit_prop_error_pos: + mov Temp1, #7Fh ; Limit to max positive (2's complement) + mov Temp2, #00h + jmp governor_store_prop_error + +governor_limit_prop_error_neg: + mov Temp1, #80h ; Limit to max negative (2's complement) + mov Temp2, #0FFh + +governor_store_prop_error: + ; Store proportional + mov Gov_Proportional_L, Temp1 + mov Gov_Proportional_H, Temp2 +calc_governor_prop_error_exit: + ret + + +; Third governor routine - calculate governor integral error +calc_governor_int_error: + ; Exit if governor is inactive + mov A, Gov_Active + jz calc_governor_int_error_exit + + ; Add proportional to integral + mov A, Gov_Proportional_L + add A, Gov_Integral_L + mov Temp1, A + mov A, Gov_Proportional_H + addc A, Gov_Integral_H + mov Temp2, A + mov Bit_Access, Gov_Proportional_H ; Sign extend high byte + clr A + jnb Bit_Access.7, ($+4) + cpl A + addc A, Gov_Integral_X + mov Temp3, A + ; Check integral and limit + jnb ACC.7, governor_check_int_limit_pos ; Check sign bit + + clr C + mov A, Temp3 + subb A, #0F0h ; Is error too negative? + jc governor_limit_int_error_neg ; Yes - limit + jmp governor_check_pwm + +governor_check_int_limit_pos: + clr C + mov A, Temp3 + subb A, #0Fh ; Is error too positive? + jnc governor_limit_int_error_pos ; Yes - limit + jmp governor_check_pwm + +governor_limit_int_error_pos: + mov Temp1, #0FFh ; Limit to max positive (2's complement) + mov Temp2, #0FFh + mov Temp3, #0Fh + jmp governor_check_pwm + +governor_limit_int_error_neg: + mov Temp1, #00h ; Limit to max negative (2's complement) + mov Temp2, #00h + mov Temp3, #0F0h + +governor_check_pwm: + ; Check current pwm + clr C + mov A, Current_Pwm + subb A, Pwm_Limit ; Is current pwm at or above pwm limit? + jnc governor_int_max_pwm ; Yes - branch + + mov A, Current_Pwm ; Is current pwm at zero? + jz governor_int_min_pwm ; Yes - branch + + ajmp governor_store_int_error ; No - store integral error + +governor_int_max_pwm: + mov A, Gov_Proportional_H + jb ACC.7, calc_governor_int_error_exit ; Is proportional error negative - branch (high byte is always zero) + ajmp governor_store_int_error ; Positive - store integral error + +governor_int_min_pwm: + mov A, Gov_Proportional_H + jnb ACC.7, calc_governor_int_error_exit ; Is proportional error positive - branch (high byte is always zero) + +governor_store_int_error: + ; Store integral + mov Gov_Integral_L, Temp1 + mov Gov_Integral_H, Temp2 + mov Gov_Integral_X, Temp3 +calc_governor_int_error_exit: + ret + + +; Fourth governor routine - calculate governor proportional correction +calc_governor_prop_correction: + ; Exit if governor is inactive + mov A, Gov_Active + jnz calc_governor_prop_corr + jmp calc_governor_prop_corr_exit + +calc_governor_prop_corr: + ; Load proportional gain + mov Temp1, #Pgm_Gov_P_Gain_Decoded; Load proportional gain + mov A, @Temp1 + mov Temp3, A ; Store in Temp3 + ; Load proportional + clr C + mov A, Gov_Proportional_L ; Nominal multiply by 2 + rlc A + mov Temp1, A + mov A, Gov_Proportional_H + rlc A + mov Temp2, A + ; Apply gain + call mult_s16_by_u8_div_16 + ; Check error and limit (to low byte) + mov A, Temp2 + jnb ACC.7, governor_check_prop_corr_limit_pos ; Check sign bit + + clr C + mov A, Temp1 + subb A, #80h ; Is error too negative? + mov A, Temp2 + subb A, #0FFh + jc governor_limit_prop_corr_neg ; Yes - limit + ajmp governor_apply_prop_corr + +governor_check_prop_corr_limit_pos: + clr C + mov A, Temp1 + subb A, #7Fh ; Is error too positive? + mov A, Temp2 + subb A, #00h + jnc governor_limit_prop_corr_pos ; Yes - limit + ajmp governor_apply_prop_corr + +governor_limit_prop_corr_pos: + mov Temp1, #7Fh ; Limit to max positive (2's complement) + mov Temp2, #00h + ajmp governor_apply_prop_corr + +governor_limit_prop_corr_neg: + mov Temp1, #80h ; Limit to max negative (2's complement) + mov Temp2, #0FFh + +governor_apply_prop_corr: + ; Test proportional sign + mov A, Temp1 + jb ACC.7, governor_corr_neg_prop ; If proportional negative - go to correct negative + + ; Subtract positive proportional + clr C + mov A, Governor_Req_Pwm + subb A, Temp1 + mov Temp1, A + ; Check result + jc governor_corr_prop_min_pwm ; Is result negative? + + clr C + mov A, Temp1 ; Is result below pwm min? + subb A, #1 + jc governor_corr_prop_min_pwm ; Yes + jmp governor_store_prop_corr ; No - store proportional correction + +governor_corr_prop_min_pwm: + mov Temp1, #1 ; Load minimum pwm + jmp governor_store_prop_corr + +governor_corr_neg_prop: + ; Add negative proportional + mov A, Temp1 + cpl A + add A, #1 + add A, Governor_Req_Pwm + mov Temp1, A + ; Check result + jc governor_corr_prop_max_pwm ; Is result above max? + jmp governor_store_prop_corr ; No - store proportional correction + +governor_corr_prop_max_pwm: + mov Temp1, #255 ; Load maximum pwm +governor_store_prop_corr: + ; Store proportional pwm + mov Gov_Prop_Pwm, Temp1 +calc_governor_prop_corr_exit: + ret + + +; Fifth governor routine - calculate governor integral correction +calc_governor_int_correction: + ; Exit if governor is inactive + mov A, Gov_Active + jnz calc_governor_int_corr + jmp calc_governor_int_corr_exit + +calc_governor_int_corr: + ; Load integral gain + mov Temp1, #Pgm_Gov_I_Gain_Decoded; Load integral gain + mov A, @Temp1 + mov Temp3, A ; Store in Temp3 + ; Load integral + mov Temp1, Gov_Integral_H + mov Temp2, Gov_Integral_X + ; Apply gain + call mult_s16_by_u8_div_16 + ; Check integral and limit + mov A, Temp2 + jnb ACC.7, governor_check_int_corr_limit_pos ; Check sign bit + + clr C + mov A, Temp1 + subb A, #01h ; Is integral too negative? + mov A, Temp2 + subb A, #0FFh + jc governor_limit_int_corr_neg ; Yes - limit + jmp governor_apply_int_corr + +governor_check_int_corr_limit_pos: + clr C + mov A, Temp1 + subb A, #0FFh ; Is integral too positive? + mov A, Temp2 + subb A, #00h + jnc governor_limit_int_corr_pos ; Yes - limit + jmp governor_apply_int_corr + +governor_limit_int_corr_pos: + mov Temp1, #0FFh ; Limit to max positive (2's complement) + mov Temp2, #00h + jmp governor_apply_int_corr + +governor_limit_int_corr_neg: + mov Temp1, #01h ; Limit to max negative (2's complement) + mov Temp2, #0FFh + +governor_apply_int_corr: + ; Test integral sign + mov A, Temp2 + jb ACC.7, governor_corr_neg_int ; If integral negative - go to correct negative + + ; Subtract positive integral + clr C + mov A, Gov_Prop_Pwm + subb A, Temp1 + mov Temp1, A + ; Check result + jc governor_corr_int_min_pwm ; Is result negative? + + clr C + mov A, Temp1 ; Is result below pwm min? + subb A, #1 + jc governor_corr_int_min_pwm ; Yes + jmp governor_store_int_corr ; No - store correction + +governor_corr_int_min_pwm: + mov Temp1, #0 ; Load minimum pwm + jmp governor_store_int_corr + +governor_corr_neg_int: + ; Add negative integral + mov A, Temp1 + cpl A + add A, #1 + add A, Gov_Prop_Pwm + mov Temp1, A + ; Check result + jc governor_corr_int_max_pwm ; Is result above max? + jmp governor_store_int_corr ; No - store correction + +governor_corr_int_max_pwm: + mov Temp1, #255 ; Load maximum pwm +governor_store_int_corr: + ; Store current pwm + mov Current_Pwm, Temp1 +calc_governor_int_corr_exit: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Measure lipo cells +; +; No assumptions +; +; Measure voltage and calculate lipo cells +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +measure_lipo_cells: +IF MODE == 1 ; Tail + ; If tail, then exit + jmp measure_lipo_exit +ENDIF +measure_lipo_start: + ; Load programmed low voltage limit +;读取Low voltage limit + mov Lipo_Cell_Count, #0 ;2013.8.23 防止接收机拿掉后再接上时,电池检测出错 + mov Temp1, #Pgm_Low_Voltage_Lim ; Load limit + mov A, @Temp1 + mov Bit_Access, A ; Store in Bit_Access + ; Set commutation to BpFET on +; call comm5comm6 + CnFET_off ; Cn off + BnFET_on ; Bn on + Set_Comp_Phase_C ; Set comparator to phase C + mov Comm_Phase, #6 + ; Start adc + Start_Adc + ; Wait for ADC conversion to complete + Get_Adc_Status + jb AD0BUSY, measure_lipo_cells + ; Read ADC result + Read_Adc_Result + ; Stop ADC + Stop_Adc + ; Switch power off + call switch_power_off + ; Set limit step + mov Lipo_Adc_Limit_L, #ADC_LIMIT_L + mov Lipo_Adc_Limit_H, #ADC_LIMIT_H + clr C + mov A, #ADC_LIMIT_H ; Divide 2.8V value by 2 + rrc A + mov Temp6, A + mov A, #ADC_LIMIT_L + rrc A + mov Temp5, A + mov A, #ADC_LIMIT_L ; Calculate 1.4+2.8V=4.2V value + add A, Temp5 + add A, #3 ;加宽一节电池电压范围 4.3V 2013.8.16 + mov Temp5, A + mov A, #ADC_LIMIT_H + addc A, Temp6 + mov Temp6, A + mov A, Temp5 ; Copy step + mov Temp3, A + mov A, Temp6 + mov Temp4, A +;*************************************************** +; Lipo节数检测 +;*************************************************** +measure_lipo_cell_loop: + ; Check voltage against xS lower limit + inc Lipo_Cell_Count ;增加电池节数累加 2013.5.29 + clr C + mov A, Temp1 + subb A, Temp3 ; Voltage above limit? + mov A, Temp2 + subb A, Temp4 + jc measure_lipo_adjust ; No - branch 读取到电压范围 + + ; Set xS voltage limit + mov A, Lipo_Adc_Limit_L + add A, #ADC_LIMIT_L + mov Lipo_Adc_Limit_L, A + mov A, Lipo_Adc_Limit_H + addc A, #ADC_LIMIT_H + mov Lipo_Adc_Limit_H, A + ; Set (x+1)S lower limit + mov A, Temp3 + add A, Temp5 ; Add step + mov Temp3, A + mov A, Temp4 + addc A, Temp6 + mov Temp4, A + jmp measure_lipo_cell_loop ; Check for one more battery cell + +measure_lipo_adjust: + mov Temp7, Lipo_Adc_Limit_L + mov Temp8, Lipo_Adc_Limit_H + ; Calculate 3.125% + clr C + mov A, Lipo_Adc_Limit_H + rrc A + mov Temp2, A + mov A, Lipo_Adc_Limit_L + rrc A + mov Temp1, A ; After this 50% + clr C + mov A, Temp2 + rrc A + mov Temp2, A + mov A, Temp1 + rrc A + mov Temp1, A ; After this 25% +; mov A, Lipo_Adc_Limit_L ; Set adc reference for voltage compensation +; add A, Temp1 ;低压低字节+低压低字节偏移量 +; mov Lipo_Adc_Reference_L, A ;存低压低字节 +; mov A, Lipo_Adc_Limit_H +; addc A, Temp2 ;低压高字节+低压高字节偏移量 +; mov Lipo_Adc_Reference_H, A ;存低压高字节 +; ; Divide three times to get to 3.125% 6.25% 2013.5.30 + mov Temp3, #2 ;3 +measure_lipo_divide_loop: + clr C + mov A, Temp2 + rrc A + mov Temp2, A + mov A, Temp1 + rrc A + mov Temp1, A + djnz Temp3, measure_lipo_divide_loop + + ; Add the programmed number of 0.1V (or 3.125% increments) + mov Temp3, Bit_Access ; Load programmed limit (Bit_Access has Pgm_Low_Voltage_Lim) +; dec Temp3 +; mov A,Temp3 ;增加判断指令,如果没有这条指令能判断???? +; jnz measure_lipo_limit_on ; Is low voltage limiting on? + + cjne Temp3, #4, measure_lipo_limit_on + + mov Lipo_Adc_Limit_L, #0 ; No - set limit to zero + mov Lipo_Adc_Limit_H, #0 + jmp measure_lipo_exit + +measure_lipo_limit_on: + dec Temp3 + mov A, Temp3 + jz measure_lipo_update +;Bit_Access>2时,低压保护值=基值+偏移量 +;Low voltage limit > 第2项时 +measure_lipo_add_loop: + clr C + mov A, Temp7 ; Add 3.125% + add A, Temp1 + mov Temp7, A + mov A, Temp8 + addc A, Temp2 + mov Temp8, A +; clr C +; mov A, Temp7 ; Add 3.125% +; add A, Temp1 +; mov Temp7, A +; mov A, Temp8 +; addc A, Temp2 +; mov Temp8, A + djnz Temp3, measure_lipo_add_loop +;存低压保护值 +;Low voltage limit = 第2项 3.0V +measure_lipo_update: + ; Set ADC limit + mov Lipo_Adc_Limit_L, Temp7 + mov Lipo_Adc_Limit_H, Temp8 +measure_lipo_exit: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Start ADC conversion +; +; No assumptions +; +; Start conversion used for measuring power supply voltage +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +start_adc_conversion: + ; Start adc + Start_Adc + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Check temperature, power supply voltage and limit power +; +; No assumptions +; +; Used to limit main motor power in order to maintain the required voltage +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +check_temp_voltage_and_limit_power: + ; Load programmed low voltage limit + mov Temp1, #Pgm_Low_Voltage_Lim ;读低压保护选项 + mov A, @Temp1 + mov Temp8, A ; Store in Temp8 + ; Wait for ADC conversion to complete + Get_Adc_Status + jb AD0BUSY, check_temp_voltage_and_limit_power + ; Read ADC result + Read_Adc_Result ;读AD值 + ; Stop ADC + Stop_Adc ;禁止AD转换 + + inc Adc_Conversion_Cnt ; Increment conversion counter + clr C + mov A, Adc_Conversion_Cnt ; Is conversion count equal to temp rate? + subb A, #TEMP_CHECK_RATE + jc check_voltage_start ; No - check voltage AD转换次数 < 8次 ? + + mov Adc_Conversion_Cnt, #0 ; Yes - temperature check. Reset counter + mov A, Temp2 ; Is temperature reading below 256? + jnz temp_average_inc_dec ; No - proceed + + mov A, Current_Average_Temp ; Yes - decrement average + jz temp_average_updated ; Already zero - no change + jmp temp_average_dec ; Decrement + +temp_average_inc_dec: + clr C + mov A, Temp1 ; Check if current temperature is above or below average + subb A, Current_Average_Temp + jz temp_average_updated_load_acc ; Equal - no change + + mov A, Current_Average_Temp ; Above - increment average + jnc temp_average_inc + + jz temp_average_updated ; Below - decrement average if average is not already zero +temp_average_dec: + dec A ; Decrement average + jmp temp_average_updated + +temp_average_inc: + inc A ; Increment average + jz temp_average_dec + jmp temp_average_updated + +temp_average_updated_load_acc: + mov A, Current_Average_Temp +temp_average_updated: + mov Current_Average_Temp, A + clr C + subb A, #TEMP_LIMIT ; Is temperature below first limit? + mov Temp1, A + jc temp_check_exit ; Yes - exit + + mov Pwm_Limit, #192 ; No - limit pwm + + clr C + mov A, Temp1 ; Is temperature below second limit + subb A, #TEMP_LIMIT_STEP + mov Temp1, A + jc temp_check_exit ; Yes - exit + + mov Pwm_Limit, #128 ; No - limit pwm + + clr C + mov A, Temp1 ; Is temperature below third limit + subb A, #TEMP_LIMIT_STEP + mov Temp1, A + jc temp_check_exit ; Yes - exit + + mov Pwm_Limit, #64 ; No - limit pwm + + clr C + mov A, Temp1 ; Is temperature below final limit + subb A, #TEMP_LIMIT_STEP + mov Temp1, A + jc temp_check_exit ; Yes - exit + + mov Pwm_Limit, #16 ; No - limit pwm 2013.8.5最高温度时速度由0改成16 + +temp_check_exit: + Set_Adc_Ip_Volt ; Select adc input for next conversion + ret + +check_voltage_start: +IF MODE == 0 OR MODE == 2 ; Main or multi + ; Check if low voltage limiting is enabled + mov A, Temp8 + clr C + subb A, #4 ; Is low voltage limit disabled? + jz check_voltage_good ; Yes - voltage declared good + + ; Check if ADC is saturated + clr C + mov A, Temp1 ;读取AD值低字节 + subb A, #0FFh + mov A, Temp2 ;读取AD值高字节 + subb A, #03h ;判断AD是否超出10位AD范围 + jnc check_voltage_good ; ADC saturated, can not make judgement + + ; Check voltage against limit + clr C + mov A, Temp1 + subb A, Lipo_Adc_Limit_L + mov A, Temp2 + subb A, Lipo_Adc_Limit_H + jnc check_voltage_good ; If voltage above limit - branch 电压值 > 低压设置值 + + mov Temp1, #Pgm_Low_Voltage_Ctl ;读低压保护控制方式选项 + mov A, @Temp1 + clr C + subb A, #1 ; + jz check_voltage_next_way + + mov A, Pwm_Limit + subb A, #5 + jnc check_limit_count + setb LOW_LIMIT_STOP ;设置低压保护控制方式2 低压停止标志 + ljmp run_to_wait_for_power_on + +check_voltage_next_way: + ; Decrease pwm limit + mov A, Pwm_Limit + subb A, #80 ;更改低压保护方式 2013.05.31 +;////// jz check_voltage_lim ; If limit zero - branch + jc check_voltage_lim ; If limit <100 - branch +check_limit_count: + mov A, Limit_Count + jz ($+6) + dec Limit_Count ;递减低压保护变量 2013.7.5 + ajmp check_voltage_lim + + mov Limit_Count, #5 ; 2013.7.5 + dec Pwm_Limit ; Decrement limit + jmp check_voltage_lim +;Low voltage limit = 第1项 +check_voltage_good: + ; Increase pwm limit + mov Limit_Count, #5 ; 2013.7.5 + mov A, Pwm_Limit + cpl A + jz check_voltage_lim ; If limit max - branch + + inc Pwm_Limit ; Increment limit + +check_voltage_lim: + mov Temp1, Pwm_Limit ; Set limit + clr C + mov A, Current_Pwm + subb A, Temp1 + jnc check_voltage_spoolup_lim ; If current pwm above limit - branch and limit + + mov Temp1, Current_Pwm ; Set current pwm (no limiting) + +check_voltage_spoolup_lim: + mov Current_Pwm_Limited, Temp1 ;取小值 + ; Slow spoolup + clr C + mov A, Current_Pwm_Limited + subb A, Pwm_Limit_Spoolup + jc check_voltage_exit ; If current pwm below limit - branch + + mov Current_Pwm_Limited, Pwm_Limit_Spoolup ;取小值 + mov A, Pwm_Limit_Spoolup ; Check if spoolup limit is max + cpl A + jz check_voltage_exit ; If max - branch + + mov Pwm_Limit, Pwm_Limit_Spoolup ; Set pwm limit to spoolup limit during ramp (to avoid governor integral buildup) + +check_voltage_exit: +ENDIF + ; Set adc mux for next conversion + clr C + mov A, Adc_Conversion_Cnt ; Is next conversion for temperature? + cjne A, #(TEMP_CHECK_RATE-1), ($+6) + + Set_Adc_Ip_Temp ; Select temp sensor for next conversion + + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Set startup PWM routine +; +; No assumptions +; +; Used for pwm control during startup +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +set_startup_pwm: + ; Set pwm values according to startup phase flags + jnb Flags1.SETTLE_PHASE, ($+5) ; Is it motor start settle phase? 是否启动定位? + mov Temp1, #PWM_SETTLE ; Yes - set settle power + jnb Flags1.STEPPER_PHASE, ($+5) ; Is it motor start stepper phase? 是否步进启动? + mov Temp1, #PWM_STEPPER ; Yes - set stepper power + + ; Update pwm variables if any startup phase flag is set + mov A, Flags1 + anl A, #((1 SHL SETTLE_PHASE)+(1 SHL STEPPER_PHASE)) + jz startup_pwm_exit ; If no startup phase set - exit + + ; Adjust startup power + mov A, Temp1 ; Multiply startup power by programmed value + mov Temp2, #Pgm_Startup_Pwr_Decoded + mov B, @Temp2 + mul AB + xch A, B + mov C, B.7 ; Multiply result by 2 (unity gain is 128) + rlc A + mov Temp1, A ; Transfer to Temp1 + clr C + mov A, Temp1 ; Check against limit + subb A, Pwm_Limit + jc startup_pwm_set_pwm ; If pwm below limit - branch + + mov Temp1, Pwm_Limit ; Limit pwm + +startup_pwm_set_pwm: + ; Set pwm variables + mov Requested_Pwm, Temp1 ; Update requested pwm + mov Current_Pwm, Temp1 ; Update current pwm + mov Current_Pwm_Limited, Temp1 ; Update limited version of current pwm + jnb Flags1.SETTLE_PHASE, startup_pwm_exit ; Is it motor start settle phase? + + clr C ; Yes - update spoolup beginning pwm (will use PWM_SETTLE or PWM_SETTLE/2) + mov A, Temp1 + mov Pwm_Spoolup_Beg, A + +startup_pwm_exit: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Initialize all timings routine +; +; No assumptions +; +; Part of initialization before motor start +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +initialize_all_timings: + ; Load programmed startup rpm +;读取Startup rpm +; mov Temp1, #Pgm_Startup_Rpm ; Load startup rpm +; mov A, @Temp1 +; mov Temp8, A ; Store in Temp8 + ; Check startup rpm setting and set step accordingly +; clr C +; mov A, Temp8 +; subb A, #5 +; jnc stepper_step_high +; clr C +; mov A, Temp8 +; subb A, #4 +; jnc stepper_step_med_high +; clr C +; mov A, Temp8 +; subb A, #3 +; jnc stepper_step_med +; clr C +; mov A, Temp8 +; subb A, #2 +; jnc stepper_step_med_low +; clr C +; mov A, Temp8 +; subb A, #1 +; jnc stepper_step_low +;Startup_Rpm = 第5项 +;stepper_step_high: +; mov Stepper_Step_Beg_L, #low(2000 SHL 1) +; mov Stepper_Step_Beg_H, #high(2000 SHL 1) +; mov Stepper_Step_End_L, #low(670 SHL 1) +; mov Stepper_Step_End_H, #high(670 SHL 1) +; ajmp stepper_step_set +;Startup_Rpm = 第4项 +;stepper_step_med_high: +; mov Stepper_Step_Beg_L, #low(2400 SHL 1) +; mov Stepper_Step_Beg_H, #high(2400 SHL 1) +; mov Stepper_Step_End_L, #low(800 SHL 1) +; mov Stepper_Step_End_H, #high(800 SHL 1) +; ajmp stepper_step_set +;Startup_Rpm = 第3项 +;stepper_step_med: +; mov Stepper_Step_Beg_L, #low(3000 SHL 1) ; ~3300 eRPM +; mov Stepper_Step_Beg_H, #high(3000 SHL 1) +; mov Stepper_Step_End_L, #low(1000 SHL 1) ; ~10000 eRPM +; mov Stepper_Step_End_H, #high(1000 SHL 1) +; ajmp stepper_step_set +;Startup_Rpm = 第2项 +;stepper_step_med_low: +; mov Stepper_Step_Beg_L, #low(3750 SHL 1) +; mov Stepper_Step_Beg_H, #high(3750 SHL 1) +; mov Stepper_Step_End_L, #low(1250 SHL 1) +; mov Stepper_Step_End_H, #high(1250 SHL 1) +; ajmp stepper_step_set +;Startup_Rpm = 第1项 +;stepper_step_low: +; mov Stepper_Step_Beg_L, #low(4500 SHL 1) +; mov Stepper_Step_Beg_H, #high(4500 SHL 1) +; mov Stepper_Step_End_L, #low(1500 SHL 1) +; mov Stepper_Step_End_H, #high(1500 SHL 1) +; ajmp stepper_step_set + +;stepper_step_set: +; mov Wt_Stepper_Step_L, Stepper_Step_Beg_L ; Initialize stepper step time +; mov Wt_Stepper_Step_H, Stepper_Step_Beg_H + mov Comm_Period4x_L, #00h ; Set commutation period registers + mov Comm_Period4x_H, #08h + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Calculate next commutation timing routine +; +; No assumptions +; +; Called immediately after each commutation +; Also sets up timer 1 to wait advance timing +; Two entry points are used +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;calc_next_comm_timing_start: ; Entry point for startup +; mov Temp1, Wt_Stepper_Step_L ; Set up stepper step wait +; mov Temp2, Wt_Stepper_Step_H +; jmp read_timer + +calc_next_comm_timing: ; Entry point for run phase + mov Temp1, Wt_Advance_L ; Set up advance timing wait + mov Temp2, Wt_Advance_H +read_timer: + ; Set up next wait + mov TMR3CN, #00h ; Timer3 disabled + clr C + clr A + subb A, Temp1 ; Set wait to zero cross scan value + mov TMR3L, A + clr A + subb A, Temp2 + mov TMR3H, A + mov TMR3CN, #04h ; Timer3 enabled + setb Flags0.T3_PENDING + ; Read commutation time + mov TMR2CN, #20h ; Timer2 disabled + mov Temp1, TMR2L ; Load timer value + mov Temp2, TMR2H + mov TMR2CN, #24h ; Timer2 enabled + ; Calculate this commutation time + mov Temp3, Prev_Comm_L + mov Temp4, Prev_Comm_H + mov Prev_Comm_L, Temp1 ; Store timestamp as previous commutation + mov Prev_Comm_H, Temp2 + clr C + mov A, Temp1 + subb A, Temp3 ; Calculate the new commutation time + mov Temp1, A + mov A, Temp2 + subb A, Temp4 + mov Temp2, A + ; Calculate next zero cross scan timeout + mov Temp3, Comm_Period4x_L ; Comm_Period4x(-l-h-x) holds the time of 4 commutations + mov Temp4, Comm_Period4x_H + clr C + mov A, Temp4 + rrc A ; Divide by 2 + mov Temp6, A + mov A, Temp3 + rrc A + mov Temp5, A + clr C + mov A, Temp6 + rrc A ; Divide by 2 again + mov Temp6, A + mov A, Temp5 + rrc A + mov Temp5, A + clr C + mov A, Temp3 + subb A, Temp5 ; Subtract a quarter + mov Temp3, A + mov A, Temp4 + subb A, Temp6 + mov Temp4, A + + mov A, Temp3 + add A, Temp1 ; Add the new time + mov Temp3, A + mov A, Temp4 + addc A, Temp2 + mov Temp4, A + mov Comm_Period4x_L, Temp3 ; Store Comm_Period4x_X + mov Comm_Period4x_H, Temp4 + jc calc_next_comm_slow ; If period larger than 0xffff - go to slow case + + ret + +calc_next_comm_slow: + mov Comm_Period4x_L, #0FFh ; Set commutation period registers to very slow timing (0xffff) + mov Comm_Period4x_H, #0FFh + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Wait advance timing routine +; +; No assumptions +; +; Waits for the advance timing to elapse +; Also sets up timer 1 to wait the zero cross scan wait time +; And has a separate entry point for just setting up zero cross scan wait +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +wait_advance_timing: + jnb Flags0.T3_PENDING, ($+5) + ajmp wait_advance_timing + +setup_zc_scan_wait: + mov TMR3CN, #00h ; Timer3 disabled + clr C + clr A + subb A, Wt_Zc_Scan_L ; Set wait to zero cross scan value + mov TMR3L, A + clr A + subb A, Wt_Zc_Scan_H + mov TMR3H, A + mov TMR3CN, #04h ; Timer3 enabled + setb Flags0.T3_PENDING + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Calculate new wait times routine +; +; No assumptions +; +; Calculates new wait times +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +calc_new_wait_times: + ; Load programmed commutation timing +;读取Commutation timing + mov Temp1, #Pgm_Comm_Timing ; Load timing setting + mov A, @Temp1 + mov Temp8, A ; Store in Temp8 + mov Temp7, #(COMM_TIME_RED SHL 1) + jnb Flags0.DEMAG_DETECTED, calc_new_wait_check_startup ; Demag detected? + + mov Temp8, #5 ; Yes - set high timing + +calc_new_wait_check_startup: + jnb Flags1.DIRECT_STARTUP_PHASE, calc_new_wait_dir_start_set ; Set timing for direct start + + mov Temp8, #3 ; Set medium timing + mov Temp7, #0 ; Set no comm time reduction + +calc_new_wait_dir_start_set: + ; Load current commutation timing + mov Temp2, Comm_Period4x_H ; Load Comm_Period4x + mov Temp1, Comm_Period4x_L + mov Temp3, #4 ; Divide 4 times +divide_wait_times: + clr C + mov A, Temp2 + rrc A ; Divide by 2 + mov Temp2, A + mov A, Temp1 + rrc A + mov Temp1, A + djnz Temp3, divide_wait_times + + clr C + mov A, Temp1 + subb A, Temp7 + mov Temp1, A + mov A, Temp2 + subb A, #0 + mov Temp2, A + jc load_min_time ; Check that result is still positive + + clr C + mov A, Temp1 + subb A, #(COMM_TIME_MIN SHL 1) + mov A, Temp2 + subb A, #0 + jnc adjust_timing ; Check that result is still above minumum + +load_min_time: + mov Temp1, #(COMM_TIME_MIN SHL 1) + clr A + mov Temp2, A + +adjust_timing: + mov A, Temp2 ; Copy values + mov Temp4, A + mov A, Temp1 + mov Temp3, A + clr C + mov A, Temp2 + rrc A ; Divide by 2 + mov Temp6, A + mov A, Temp1 + rrc A + mov Temp5, A + clr C + mov A, Temp8 ; (Temp8 has Pgm_Comm_Timing) + subb A, #3 ; Is timing normal? + jz store_times_decrease ; Yes - branch + + mov A, Temp8 + jb ACC.0, adjust_timing_two_steps ; If an odd number - branch +;Commutation timing = 第2、4项 + mov A, Temp1 ; Add 7.5?and store in Temp1/2 + add A, Temp5 + mov Temp1, A + mov A, Temp2 + addc A, Temp6 + mov Temp2, A + mov A, Temp5 ; Store 7.5?in Temp3/4 + mov Temp3, A + mov A, Temp6 + mov Temp4, A + jmp store_times_up_or_down +;Commutation timing = 第1、5项 +adjust_timing_two_steps: + mov A, Temp1 ; Add 15?and store in Temp1/2 + add A, Temp1 + mov Temp1, A + mov A, Temp2 + addc A, Temp2 + mov Temp2, A + mov Temp3, #(COMM_TIME_MIN SHL 1) ; Store minimum time in Temp3/4 + clr A + mov Temp4, A + +store_times_up_or_down: + clr C + mov A, Temp8 + subb A, #3 ; Is timing higher than normal? + jc store_times_decrease ; No - branch +;Commutation timing = 第4、5项 +store_times_increase: + mov Wt_Comm_L, Temp3 ; Now commutation time (~60? divided by 4 (~15?nominal) + mov Wt_Comm_H, Temp4 + mov Wt_Advance_L, Temp1 ; New commutation advance time (~15?nominal) + mov Wt_Advance_H, Temp2 + mov Wt_Zc_Scan_L, Temp5 ; Use this value for zero cross scan delay (7.5? + mov Wt_Zc_Scan_H, Temp6 + ret +;Commutation timing = 第1、2、3项 +store_times_decrease: + mov Wt_Comm_L, Temp1 ; Now commutation time (~60? divided by 4 (~15?nominal) + mov Wt_Comm_H, Temp2 + mov Wt_Advance_L, Temp3 ; New commutation advance time (~15?nominal) + mov Wt_Advance_H, Temp4 + mov Wt_Zc_Scan_L, Temp5 ; Use this value for zero cross scan delay (7.5? + mov Wt_Zc_Scan_H, Temp6 + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Wait before zero cross scan routine +; +; No assumptions +; +; Waits for the zero cross scan wait time to elapse +; Also sets up timer 1 to wait the zero cross scan timeout time +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +wait_before_zc_scan: + jnb Flags0.T3_PENDING, ($+5) + ajmp wait_before_zc_scan + + mov TMR3CN, #00h ; Timer3 disabled + clr C + clr A + subb A, Comm_Period4x_L ; Set wait to zero comm period 4x value + mov TMR3L, A + clr A + subb A, Comm_Period4x_H + mov TMR3H, A + mov TMR3CN, #04h ; Timer3 enabled + setb Flags0.T3_PENDING + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Wait for comparator to go low/high routines +; +; No assumptions +; +; Waits for the zero cross scan wait time to elapse +; Then scans for comparator going low/high +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +wait_for_comp_out_low: + mov Comp_Wait_Reads, #0 + mov Bit_Access, #00h ; Desired comparator output + jmp wait_for_comp_out_start + +wait_for_comp_out_high: + mov Comp_Wait_Reads, #0 + mov Bit_Access, #40h ; Desired comparator output + +wait_for_comp_out_start: + setb EA ; Enable interrupts + inc Comp_Wait_Reads + jb Flags0.T3_PENDING, ($+4) ; Has zero cross scan timeout elapsed? + ret ; Yes - return + + ; Set default comparator response times + mov CPT0MD, #0 ; Set fast response (100ns) as default +IF COMP1_USED==1 + mov CPT1MD, #0 ; Set fast response (100ns) as default +ENDIF + ; Select number of comparator readings based upon current rotation speed + mov A, Comm_Period4x_H ; Load rotation period + clr C + rrc A ; Divide by 4 + clr C + rrc A + mov Temp1, A + inc Temp1 ; Add one to be sure it is always larger than zero + jz comp_wait_on_comp_able ; If minimum number of readings - jump directly to reading + ; For damped mode, do fewer comparator readings (since comparator info is primarily only available in the pwm on period) + jnb Flags2.PGM_PWMOFF_DAMPED, comp_wait_set_max_readings + + clr C + rrc A ; Divide by 4 again + clr C + rrc A + mov Temp1, A + inc Temp1 ; Add one to be sure it is always larger than zero + +comp_wait_set_max_readings: + clr C + mov A, Temp1 ; Limit to a max of 10 + subb A, #10 + jc ($+4) + + mov Temp1, #10 + + jnb Flags2.PGM_PWM_HIGH_FREQ, comp_wait_set_response_time ; Jump if pwm frequency is low + + clr C + mov A, Temp1 ; Limit to a max of 4 + subb A, #4 + jc ($+4) + + mov Temp1, #4 + +comp_wait_set_response_time: + clr C + mov A, Comm_Period4x_H ; Is Comm_Period4x_H less than 1ms? + subb A, #8 + jc comp_wait_on_comp_able ; Yes - jump + + mov CPT0MD, #2 ; Set medium response (300ns) +IF COMP1_USED==1 + mov CPT1MD, #2 ; Set medium response (300ns) +ENDIF + clr C + mov A, Comm_Period4x_H ; Is Comm_Period4x_H less than 2ms? + subb A, #16 + jc comp_wait_on_comp_able ; Yes - jump + + mov CPT0MD, #3 ; Set slow response (1000ns) +IF COMP1_USED==1 + mov CPT1MD, #3 ; Set slow response (1000ns) +ENDIF + +comp_wait_on_comp_able: + jb Flags0.T3_PENDING, ($+6) ; Has zero cross scan timeout elapsed? + setb EA ; Enable interrupts + ret ; Yes - return + + mov Temp2, #COMP_PWM_HIGH_ON_DELAY ; Wait time after pwm has been switched on (motor wire electrical settling) + jb Flags2.PGM_PWM_HIGH_FREQ, ($+5) + mov Temp2, #COMP_PWM_LOW_ON_DELAY + setb EA ; Enable interrupts + nop ; Allocate only just enough time to capture interrupt + nop + clr EA ; Disable interrupts + jb Flags0.PWM_ON, pwm_wait_startup ; If pwm on - proceed + + mov Temp2, #COMP_PWM_HIGH_OFF_DELAY ; Wait time after pwm has been switched off (motor wire electrical settling) + jb Flags2.PGM_PWM_HIGH_FREQ, ($+5) + mov Temp2, #COMP_PWM_LOW_OFF_DELAY + jnb Flags2.CURR_PWMOFF_COMP_ABLE, comp_wait_on_comp_able ; If comparator is not usable in pwm off - go back + +pwm_wait_startup: + jnb Flags1.DIRECT_STARTUP_PHASE, pwm_wait ; Set a long delay from pwm on/off events during direct startup + + mov Temp2, #120 +pwm_wait: + clr C + mov A, TL1 + subb A, Temp2 +IF DAMPED_MODE_ENABLE==0 + jc comp_wait_on_comp_able ; Re-evaluate pwm cycle for slower escs +ENDIF +IF DAMPED_MODE_ENABLE==1 ; Assume same pwm cycle for fast escs + jb Flags1.DIRECT_STARTUP_PHASE, ($+5) + jc pwm_wait + jc comp_wait_on_comp_able ; Re-evaluate pwm cycle during direct start +ENDIF + +comp_read: + Read_Comp_Out ; Read comparator output + cpl A + anl A, #40h + cjne A, Bit_Access, ($+5) ; If comparator output is correct - proceed + + ajmp wait_for_comp_out_start ; If comparator output is not correct - go back and restart + + djnz Temp1, comp_wait_on_comp_able ; Decrement readings counter - repeat comparator reading if not zero + + setb EA ; Enable interrupts + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Evaluate comparator integrity +; +; No assumptions +; +; Checks comparator signal behaviour versus expected behaviour +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +evaluate_comparator_integrity: + clr Flags0.DEMAG_DETECTED ; Clear demag detected flag + ; Check if demag compensation is enabled +;读取Demag compensation + mov Temp1, #Pgm_Demag_Comp ; Load programmed demag compensation + mov A, @Temp1 + dec A + jz eval_comp_no_demag + + ; Check if a demag situation has occurred + mov A, Comp_Wait_Reads ; Check if there were no waits (there shall be some). If none a demag situation has occurred + dec A + jnz eval_comp_no_demag +;Demag compensation = 第2项 + setb Flags0.DEMAG_DETECTED ; Set demag detected flag +;Demag compensation = 第1项 +eval_comp_no_demag: + jnb Flags1.DIRECT_STARTUP_PHASE, eval_comp_check_timeout + + inc Direct_Startup_Ok_Cnt ; Increment ok counter + jb Flags0.T3_PENDING, eval_comp_exit + + mov Direct_Startup_Ok_Cnt, #0 ; Reset ok counter + jmp eval_comp_exit + +eval_comp_check_timeout: + jb Flags0.T3_PENDING, eval_comp_exit ; Has timeout elapsed? + dec SP ; Routine exit without "ret" command + dec SP + ljmp run_to_wait_for_power_on ; Yes - exit run mode + +eval_comp_exit: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Setup commutation timing routine +; +; No assumptions +; +; Sets up and starts wait from commutation to zero cross +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +setup_comm_wait: + mov TMR3CN, #00h ; Timer3 disabled + clr C + clr A + subb A, Wt_Comm_L ; Set wait commutation value + mov TMR3L, A + clr A + subb A, Wt_Comm_H + mov TMR3H, A + mov TMR3CN, #04h ; Timer3 enabled + setb Flags0.T3_PENDING + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Wait for commutation routine +; +; No assumptions +; +; Waits from zero cross to commutation +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +wait_for_comm: + ; Store motor power + mov Temp7, Current_Pwm_Limited + ; Check if a demag situation has occurred + jnb Flags0.DEMAG_DETECTED, wait_for_comm_wait; Demag detected? + + ; Load programmed demag compensation + mov Temp1, #Pgm_Demag_Comp_Power_Decoded ; Yes - load programmed demag compensation power decoded + mov A, @Temp1 + mov Temp8, A ; Store in Temp8 + + ; Check for first power off + cjne Temp8, #1, wait_for_comm_blind + + setb Flags0.DEMAG_CUT_POWER ; Turn off motor power + mov Current_Pwm_Limited, #0 + All_nFETs_off + + ; Wait a blind wait +wait_for_comm_blind: + call setup_zc_scan_wait ; Setup a zero cross scan wait (7.5 deg) +wait_demag_default_zc1: + jnb Flags0.DEMAG_CUT_POWER, ($+6) ; Cut motor power if set + mov Current_Pwm_Limited, #0 + jnb Flags0.T3_PENDING, ($+5) + ajmp wait_demag_default_zc1 + + ; Check for second power off + cjne Temp8, #2, wait_for_comm_second_blind_wait + + setb Flags0.DEMAG_CUT_POWER ; Turn off motor power + mov Current_Pwm_Limited, #0 + All_nFETs_off + + ; Check for another blind wait +wait_for_comm_second_blind_wait: + mov Temp1, #Pgm_Demag_Comp_Wait_Decoded ; Yes - load programmed demag compensation wait decoded + cjne @Temp1, #1, wait_for_comm_power3 + + call setup_zc_scan_wait ; Setup a zero cross scan wait (7.5 deg) +wait_demag_default_zc2: + jnb Flags0.DEMAG_CUT_POWER, ($+6) ; Cut motor power if set + mov Current_Pwm_Limited, #0 + jnb Flags0.T3_PENDING, ($+5) + ajmp wait_demag_default_zc2 + +wait_for_comm_power3: + ; Check for third power off + cjne Temp8, #3, wait_for_comm_setup + + setb Flags0.DEMAG_CUT_POWER ; Turn off motor power + mov Current_Pwm_Limited, #0 + All_nFETs_off + +wait_for_comm_setup: + call setup_comm_wait ; Setup commutation wait +wait_for_comm_wait: + jnb Flags0.DEMAG_CUT_POWER, ($+6) ; Cut motor power if set + mov Current_Pwm_Limited, #0 + jnb Flags0.T3_PENDING, ($+5) + ajmp wait_for_comm_wait + + jnb Flags0.DEMAG_DETECTED, wait_for_comm_exit ; Was there a demag situation? + + clr Flags0.DEMAG_CUT_POWER ; Restore motor power again + mov Current_Pwm_Limited, Temp7 + +wait_for_comm_exit: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Commutation routines +; +; No assumptions +; +; Performs commutation switching +; Damped routines uses all pfets on when in pwm off to dampen the motor +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;****************************************************** +; 关B down 并 开A down或Cdown +;****************************************************** +comm1comm2: + clr EA ; Disable all interrupts + BpFET_off ; Bp off + jb Flags2.PGM_PWMOFF_DAMPED, comm12_damp + jmp comm12_nondamp +comm12_damp: +IF DAMPED_MODE_ENABLE == 0 + mov DPTR, #pwm_cnfet_apfet_on_fast + jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, comm12_nondamp +ENDIF +IF DAMPED_MODE_ENABLE == 1 + mov DPTR, #pwm_cnfet_apfet_on_safe +ENDIF + jnb Flags2.CURR_PWMOFF_DAMPED, comm12_nondamp ; If pwm off not damped - branch + CpFET_off + mov A, #NFETON_DELAY ; Delay + djnz ACC, $ +comm12_nondamp: + ApFET_on ; Ap on + Set_Comp_Phase_B ; Set comparator to phase B + mov Comm_Phase, #2 + setb EA ; Enable all interrupts + ret + +comm2comm3: + clr EA ; Disable all interrupts + jb Flags2.PGM_PWMOFF_DAMPED, comm23_damp + jmp comm23_nondamp +comm23_damp: +IF DAMPED_MODE_ENABLE == 0 + mov DPTR, #pwm_bnfet_apfet_on_fast +ENDIF +IF DAMPED_MODE_ENABLE == 1 + mov DPTR, #pwm_bnfet_apfet_on_safe +ENDIF + jnb Flags2.CURR_PWMOFF_DAMPED, comm23_nfet ; If pwm off not damped - branch + BpFET_off + CpFET_off + mov A, #NFETON_DELAY ; Delay + djnz ACC, $ + jmp comm23_nfet +comm23_nondamp: + mov DPTR, #pwm_bfet_on +comm23_nfet: + CnFET_off ; Cn off + jnb Flags0.PWM_ON, comm23_cp ; Is pwm on? + BnFET_on ; Yes - Bn on +comm23_cp: + Set_Comp_Phase_C ; Set comparator to phase C + mov Comm_Phase, #3 + setb EA ; Enable all interrupts + ret + +comm3comm4: + clr EA ; Disable all interrupts + ApFET_off ; Ap off + jb Flags2.PGM_PWMOFF_DAMPED, comm34_damp + jmp comm34_nondamp +comm34_damp: +IF DAMPED_MODE_ENABLE == 0 + mov DPTR, #pwm_bnfet_cpfet_on_fast + jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, comm34_nondamp +ENDIF +IF DAMPED_MODE_ENABLE == 1 + mov DPTR, #pwm_bnfet_cpfet_on_safe +ENDIF + jnb Flags2.CURR_PWMOFF_DAMPED, comm34_nondamp ; If pwm off not damped - branch + BpFET_off + mov A, #NFETON_DELAY ; Delay + djnz ACC, $ +comm34_nondamp: + CpFET_on ; Cp on + Set_Comp_Phase_A ; Set comparator to phase A + mov Comm_Phase, #4 + setb EA ; Enable all interrupts + ret + +comm4comm5: + clr EA ; Disable all interrupts + jb Flags2.PGM_PWMOFF_DAMPED, comm45_damp + jmp comm45_nondamp +comm45_damp: +IF DAMPED_MODE_ENABLE == 0 + mov DPTR, #pwm_anfet_cpfet_on_fast +ENDIF +IF DAMPED_MODE_ENABLE == 1 + mov DPTR, #pwm_anfet_cpfet_on_safe +ENDIF + jnb Flags2.CURR_PWMOFF_DAMPED, comm45_nfet ; If pwm off not damped - branch + ApFET_off + BpFET_off + mov A, #NFETON_DELAY ; Delay + djnz ACC, $ + jmp comm45_nfet +comm45_nondamp: + mov DPTR, #pwm_afet_on +comm45_nfet: + BnFET_off ; Bn off + jnb Flags0.PWM_ON, comm45_cp ; Is pwm on? + AnFET_on ; Yes - An on +comm45_cp: + Set_Comp_Phase_B ; Set comparator to phase B + mov Comm_Phase, #5 + setb EA ; Enable all interrupts + ret + +comm5comm6: + clr EA ; Disable all interrupts + CpFET_off ; Cp off + jb Flags2.PGM_PWMOFF_DAMPED, comm56_damp + jmp comm56_nondamp +comm56_damp: +IF DAMPED_MODE_ENABLE == 0 + mov DPTR, #pwm_anfet_bpfet_on_fast + jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, comm56_nondamp +ENDIF +IF DAMPED_MODE_ENABLE == 1 + mov DPTR, #pwm_anfet_bpfet_on_safe +ENDIF + jnb Flags2.CURR_PWMOFF_DAMPED, comm56_nondamp ; If pwm off not damped - branch + ApFET_off + mov A, #NFETON_DELAY ; Delay + djnz ACC, $ +comm56_nondamp: + BpFET_on ; Bp on + Set_Comp_Phase_C ; Set comparator to phase C + mov Comm_Phase, #6 + setb EA ; Enable all interrupts + ret + +comm6comm1: + clr EA ; Disable all interrupts + jb Flags2.PGM_PWMOFF_DAMPED, comm61_damp + jmp comm61_nondamp +comm61_damp: +IF DAMPED_MODE_ENABLE == 0 + mov DPTR, #pwm_cnfet_bpfet_on_fast +ENDIF +IF DAMPED_MODE_ENABLE == 1 + mov DPTR, #pwm_cnfet_bpfet_on_safe +ENDIF + jnb Flags2.CURR_PWMOFF_DAMPED, comm61_nfet ; If pwm off not damped - branch + ApFET_off + CpFET_off + mov A, #NFETON_DELAY ; Delay + djnz ACC, $ + jmp comm61_nfet +comm61_nondamp: + mov DPTR, #pwm_cfet_on +comm61_nfet: + AnFET_off ; An off + jnb Flags0.PWM_ON, comm61_cp ; Is pwm on? + CnFET_on ; Yes - Cn on +comm61_cp: + Set_Comp_Phase_A ; Set comparator to phase A + mov Comm_Phase, #1 + setb EA ; Enable all interrupts + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Switch power off routine +; +; No assumptions +; +; Switches all fets off +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +switch_power_off: + mov DPTR, #pwm_nofet_on ; Set DPTR register to pwm_nofet_on label + All_pFETs_Off ; Turn off all pfets + All_nFETs_Off ; Turn off all nfets + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decrement stepper step routine +; +; No assumptions +; +; Decrements the stepper step +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;decrement_stepper_step: +; clr C +; mov A, Wt_Stepper_Step_L +; subb A, Stepper_Step_End_L ; Minimum Stepper_Step_End +; mov A, Wt_Stepper_Step_H +; subb A, Stepper_Step_End_H +; jnc decrement_step ; Branch if same or higher than minimum +; ret + +;decrement_step: + ; Load programmed startup acceleration +;读取Startup acceleration +; mov Temp1, #Pgm_Startup_Accel ; Load startup accel +; mov A, @Temp1 +; mov Temp8, A ; Store in Temp8 + ; Check acceleration setting and set step size accordingly +; clr C +; mov A, Temp8 +; subb A, #5 +; jnc dec_step_high +; clr C +; mov A, Temp8 +; subb A, #4 +; jnc dec_step_med_high +; clr C +; mov A, Temp8 +; subb A, #3 +; jnc dec_step_med +; clr C +; mov A, Temp8 +; subb A, #2 +; jnc dec_step_med_low +; clr C +; mov A, Temp8 +; subb A, #1 +; jnc dec_step_low +;Start acceleration = 第5项 +;dec_step_high: +; clr C +; mov A, Wt_Stepper_Step_L +; subb A, #low(30 SHL 1) +; mov Temp1, A +; jmp decrement_step_exit +;Start acceleration = 第4项 +;dec_step_med_high: +; clr C +; mov A, Wt_Stepper_Step_L +; subb A, #low(20 SHL 1) +; mov Temp1, A +; jmp decrement_step_exit +;Start acceleration = 第3项 +;dec_step_med: +; clr C +; mov A, Wt_Stepper_Step_L +; subb A, #low(13 SHL 1) +; mov Temp1, A +; jmp decrement_step_exit +;Start acceleration = 第2项 +;dec_step_med_low: +; clr C +; mov A, Wt_Stepper_Step_L +; subb A, #low(9 SHL 1) +; mov Temp1, A +; jmp decrement_step_exit +;Start acceleration = 第1项 +;dec_step_low: +; clr C +; mov A, Wt_Stepper_Step_L +; subb A, #low(5 SHL 1) +; mov Temp1, A +; jmp decrement_step_exit + +;decrement_step_exit: +; mov A, Wt_Stepper_Step_H +; subb A, #0 +; mov Temp2, A +; mov Wt_Stepper_Step_L, Temp1 +; mov Wt_Stepper_Step_H, Temp2 +; ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Stepper timer wait +; +; No assumptions +; +; Waits for the stepper step timer to elapse +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;stepper_timer_wait: +; jnb Flags0.T3_PENDING, ($+6) ; Timer pending? +; ljmp stepper_timer_wait ; Yes, go back +; ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Set default parameters +; +; No assumptions +; +; Sets default programming parameters +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +set_default_parameters: +IF MODE == 0 ; Main + mov Temp1, #Pgm_Gov_P_Gain + mov @Temp1, #DEFAULT_PGM_MAIN_P_GAIN + mov Temp1, #Pgm_Gov_I_Gain + mov @Temp1, #DEFAULT_PGM_MAIN_I_GAIN + mov Temp1, #Pgm_Gov_Mode + mov @Temp1, #DEFAULT_PGM_MAIN_GOVERNOR_MODE + mov Temp1, #Pgm_Gov_Range + mov @Temp1, #DEFAULT_PGM_MAIN_GOVERNOR_RANGE + mov Temp1, #Pgm_Low_Voltage_Lim + mov @Temp1, #DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM + mov Temp1, #Pgm_Startup_Pwr + mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_PWR + mov Temp1, #Pgm_Startup_Rpm + mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_RPM + mov Temp1, #Pgm_Startup_Accel + mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_ACCEL + mov Temp1, #Pgm_Startup_Method + mov @Temp1, #DEFAULT_PGM_MAIN_STARTUP_METHOD + mov Temp1, #Pgm_Comm_Timing + mov @Temp1, #DEFAULT_PGM_MAIN_COMM_TIMING + mov Temp1, #Pgm_Throttle_Rate + mov @Temp1, #DEFAULT_PGM_MAIN_THROTTLE_RATE + mov Temp1, #Pgm_Damping_Force + mov @Temp1, #DEFAULT_PGM_MAIN_DAMPING_FORCE + mov Temp1, #Pgm_Pwm_Freq + mov @Temp1, #DEFAULT_PGM_MAIN_PWM_FREQ + mov Temp1, #Pgm_Demag_Comp + mov @Temp1, #DEFAULT_PGM_MAIN_DEMAG_COMP + mov Temp1, #Pgm_Direction_Rev + mov @Temp1, #DEFAULT_PGM_MAIN_DIRECTION_REV + mov Temp1, #Pgm_Input_Pol + mov @Temp1, #DEFAULT_PGM_MAIN_RCP_PWM_POL + mov Temp1, #Pgm_Motor_Idle + mov @Temp1, #0 +ENDIF +IF MODE == 1 ; Tail + mov Temp1, #Pgm_Motor_Gain + mov @Temp1, #DEFAULT_PGM_TAIL_GAIN + mov Temp1, #Pgm_Motor_Idle + mov @Temp1, #DEFAULT_PGM_TAIL_IDLE_SPEED + mov Temp1, #Pgm_Startup_Pwr + mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_PWR + mov Temp1, #Pgm_Startup_Rpm + mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_RPM + mov Temp1, #Pgm_Startup_Accel + mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_ACCEL + mov Temp1, #Pgm_Startup_Method + mov @Temp1, #DEFAULT_PGM_TAIL_STARTUP_METHOD + mov Temp1, #Pgm_Comm_Timing + mov @Temp1, #DEFAULT_PGM_TAIL_COMM_TIMING + mov Temp1, #Pgm_Throttle_Rate + mov @Temp1, #DEFAULT_PGM_TAIL_THROTTLE_RATE + mov Temp1, #Pgm_Damping_Force + mov @Temp1, #DEFAULT_PGM_TAIL_DAMPING_FORCE + mov Temp1, #Pgm_Pwm_Freq + mov @Temp1, #DEFAULT_PGM_TAIL_PWM_FREQ + mov Temp1, #Pgm_Demag_Comp + mov @Temp1, #DEFAULT_PGM_TAIL_DEMAG_COMP + mov Temp1, #Pgm_Direction_Rev + mov @Temp1, #DEFAULT_PGM_TAIL_DIRECTION_REV + mov Temp1, #Pgm_Input_Pol + mov @Temp1, #DEFAULT_PGM_TAIL_RCP_PWM_POL + mov Temp1, #Pgm_Gov_Mode + mov @Temp1, #4 +ENDIF +IF MODE == 2 ; Multi + mov Temp1, #Pgm_Fir_Key ;2013.8.27 增加关键字默认值 + mov @Temp1, #DEFAULT_PGM_MULTI_FIRST_KEYWORD + mov Temp1, #Pgm_Gov_P_Gain + mov @Temp1, #DEFAULT_PGM_MAIN_P_GAIN ;Pgm_Gov_P_Gain=9 P增益 + mov Temp1, #Pgm_Gov_I_Gain + mov @Temp1, #DEFAULT_PGM_MAIN_I_GAIN ;Pgm_Gov_I_Gain=9 I增益 + mov Temp1, #Pgm_Gov_Mode + mov @Temp1, #DEFAULT_PGM_MAIN_GOVERNOR_MODE ;Pgm_Gov_Mode=4 + mov Temp1, #Pgm_Motor_Gain + mov @Temp1, #DEFAULT_PGM_MULTI_GAIN ;gm_Motor_Gain=3 + mov Temp1, #Pgm_Low_Voltage_Lim + mov @Temp1, #DEFAULT_PGM_MULTI_LOW_VOLTAGE_LIM ;Pgm_Low_Voltage_Lim=1 低压保护:1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c + mov Temp1, #Pgm_Low_Voltage_Ctl + mov @Temp1, #DEFAULT_PGM_MULTI_LOW_VOLTAGE_CTL ;Pgm_Low_Voltage_Ctl=1 低压保护: 1=功率逐渐降低到31% 2=关闭输出 + mov Temp1, #Pgm_Startup_Pwr + mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_PWR ;Pgm_Startup_Pwr=10 + mov Temp1, #Pgm_Startup_Rpm + mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_RPM ;Pgm_Startup_Rpm=1 启动转速:1=0.67 2=0.8 3=1.00 4=1.25 5=1.5 + mov Temp1, #Pgm_Startup_Accel + mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_ACCEL ;Pgm_Startup_Accel=5 +; mov Temp1, #Pgm_Startup_Method +; mov @Temp1, #DEFAULT_PGM_MULTI_STARTUP_METHOD ;Pgm_Startup_Method=2 启动方式:1=步进启动 2=直接启动 + mov Temp1, #Pgm_Comm_Timing + mov @Temp1, #DEFAULT_PGM_MULTI_COMM_TIMING ;Pgm_Comm_Timing=3 进角时间:1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High + mov Temp1, #Pgm_Throttle_Rate + mov @Temp1, #DEFAULT_PGM_MULTI_THROTTLE_RATE ;Pgm_Throttle_Rate=13 油门范围:1=2 2=3 3=4 4=6 5=8 6=12 7=16 8=24 9=32 10=48 11=64 12=128 13=255 + mov Temp1, #Pgm_Damping_Force + mov @Temp1, #DEFAULT_PGM_MULTI_DAMPING_FORCE ;Pgm_Damping_Force=6 刹车力度:1=VeryLow 2=Low 3=MediumLow 4=MediumHigh 5=High 6=Highest + mov Temp1, #Pgm_Pwm_Freq + mov @Temp1, #DEFAULT_PGM_MULTI_PWM_FREQ ;Pgm_Pwm_Freq=1 1=Low 2=High 3=DampedLight 4=Damped + mov Temp1, #Pgm_Demag_Comp + mov @Temp1, #DEFAULT_PGM_MULTI_DEMAG_COMP ;Pgm_Demag_Comp=2 1=Disabled 2=15/0 3=15/7.5 4=7.5/7.5 5=7.5/15 (degrees blind advance / power off) + mov Temp1, #Pgm_Direction_Rev + mov @Temp1, #DEFAULT_PGM_MULTI_DIRECTION_REV ;Pgm_Direction_Rev=1 方向设置:1=正转 2=反转 + mov Temp1, #Pgm_Input_Pol + mov @Temp1, #DEFAULT_PGM_MULTI_RCP_PWM_POL ;Pgm_Input_Pol=1 接收信号极性设置:1=Positive(正) 2=Negative(负) + mov Temp1, #Pgm_Motor_Idle + mov @Temp1, #0 ;Pgm_Motor_Idle=0 +ENDIF + mov Temp1, #Pgm_Enable_TX_Program + mov @Temp1, #DEFAULT_PGM_ENABLE_TX_PROGRAM ;Pgm_Enable_TX_Program=1 1=Enabled 0=Disabled + mov Temp1, #Pgm_Main_Rearm_Start + mov @Temp1, #DEFAULT_PGM_MAIN_REARM_START ;Pgm_Main_Rearm_Start=0 1=Enabled 0=Disabled + mov Temp1, #Pgm_Gov_Setup_Target + mov @Temp1, #DEFAULT_PGM_MAIN_GOV_SETUP_TARGET ;Pgm_Gov_Setup_Target=180 Target for governor in setup mode. Corresponds to 70% throttle + mov Temp1, #Pgm_Ppm_Min_Throttle + mov @Temp1, #DEFAULT_PGM_PPM_MIN_THROTTLE ;Pgm_Ppm_Min_Throttle=37 最小油门:4*37+1000=1148 + mov Temp1, #Pgm_Ppm_Max_Throttle + mov @Temp1, #DEFAULT_PGM_PPM_MAX_THROTTLE ;Pgm_Ppm_Max_Throttle=208 最大油门:4*208+1000=1832 + mov Temp1, #Pgm_Beep_Strength + mov @Temp1, #DEFAULT_PGM_MAIN_BEEP_STRENGTH ;Pgm_Beep_Strength=120 声强设置 + mov Temp1, #Pgm_Beacon_Strength + mov @Temp1, #DEFAULT_PGM_MAIN_BEACON_STRENGTH ;Pgm_Beacon_Strength=200 灯亮长Beacon strength???? + mov Temp1, #Pgm_Beacon_Delay + mov @Temp1, #DEFAULT_PGM_MAIN_BEACON_DELAY ;Pgm_Beacon_Delay=4 灯亮时间????1=30s 2=1m 3=2m 4=3m 5=Infinite + mov Temp1, #Pgm_BEC_Voltage_High + mov @Temp1, #DEFAULT_PGM_BEC_VOLTAGE_HIGH ;Pgm_BEC_Voltage_High=0 0=Low 1= High + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decode parameters +; +; No assumptions +; +; Decodes programming parameters +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +decode_parameters: + ; Load programmed damping force +;读取Damping force + mov Temp1, #Pgm_Damping_Force; Load damping force + mov A, @Temp1 + mov Temp8, A ; Store in Temp8 + ; Decode damping +;Damping force = 第1项 + clr Flags2.PGM_PWMOFF_DAMPED + clr Flags2.PGM_PWMOFF_DAMPED_LIGHT + clr Flags2.PGM_PWMOFF_DAMPED_FULL + clr Flags2.CURR_PWMOFF_DAMPED + setb Flags2.CURR_PWMOFF_COMP_ABLE + mov Damping_Period, #9 ; Set default + mov Damping_On, #1 + mov Rcp_Stop_Limit,#250 + clr C + cjne Temp8, #1, decode_damping_2 ; Look for 2 + jmp decode_damping_done + +;Damping force = 第2项 +decode_damping_2: + setb Flags2.PGM_PWMOFF_DAMPED +; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT +; clr Flags2.PGM_PWMOFF_DAMPED_FULL + setb Flags2.CURR_PWMOFF_DAMPED + clr Flags2.CURR_PWMOFF_COMP_ABLE + mov Damping_Period, #5 + mov Damping_On, #1 + mov Rcp_Stop_Limit,#60 + clr C + cjne Temp8, #2, decode_damping_3 ; Look for 3 + jmp decode_damping_done + +;Damping force = 第3项 +decode_damping_3: +; setb Flags2.PGM_PWMOFF_DAMPED + setb Flags2.PGM_PWMOFF_DAMPED_LIGHT +; clr Flags2.PGM_PWMOFF_DAMPED_FULL +; setb Flags2.CURR_PWMOFF_DAMPED +; clr Flags2.CURR_PWMOFF_COMP_ABLE + mov Damping_Period, #5 + mov Damping_On, #2 + mov Rcp_Stop_Limit,#30 + clr C + cjne Temp8, #3, decode_damping_4 ; Look for 4 + jmp decode_damping_done + +;Damping force = 第4项 +decode_damping_4: +; setb Flags2.PGM_PWMOFF_DAMPED +; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT +; clr Flags2.PGM_PWMOFF_DAMPED_FULL +; setb Flags2.CURR_PWMOFF_DAMPED +; clr Flags2.CURR_PWMOFF_COMP_ABLE + mov Damping_Period, #5 + mov Damping_On, #3 + mov Rcp_Stop_Limit,#25 + clr C + cjne Temp8, #4, decode_damping_5 ; Look for 5 + jmp decode_damping_done + +;Damping force = 第5项 +decode_damping_5: +; setb Flags2.PGM_PWMOFF_DAMPED +; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT + setb Flags2.PGM_PWMOFF_DAMPED_FULL +; setb Flags2.CURR_PWMOFF_DAMPED +; clr Flags2.CURR_PWMOFF_COMP_ABLE + mov Damping_Period, #5 + mov Damping_On, #4 + mov Rcp_Stop_Limit,#20 + clr C + cjne Temp8, #5, decode_damping_6; Look for 6 + jmp decode_damping_done + +;Damping force = 第6项 +decode_damping_6: +; setb Flags2.PGM_PWMOFF_DAMPED +; setb Flags2.PGM_PWMOFF_DAMPED_LIGHT +; setb Flags2.PGM_PWMOFF_DAMPED_FULL +; setb Flags2.CURR_PWMOFF_DAMPED +; clr Flags2.CURR_PWMOFF_COMP_ABLE + mov Damping_Period, #5 + mov Damping_On, #5 + mov Rcp_Stop_Limit,#10 + +;*********************************************** +; 读取编程PWM频率(1) +;带硬刹/软刹 +;*********************************************** +decode_damping_done: + ; Load programmed pwm frequency +;读取Pwm frequency + mov Temp1, #Pgm_Pwm_Freq ; Load pwm freq + mov A, @Temp1 + mov Temp8, A ; Store in Temp8 +IF MODE == 0 ; Main + clr Flags2.PGM_PWMOFF_DAMPED_LIGHT + clr C + cjne Temp8, #3, ($+5) + setb Flags2.PGM_PWMOFF_DAMPED_LIGHT + clr Flags2.PGM_PWMOFF_DAMPED_FULL +ENDIF +IF MODE >= 1 ; Tail or multi +;////// clr Flags2.PGM_PWMOFF_DAMPED_LIGHT +;////// clr C +;////// cjne Temp8, #3, ($+5) +;Pwm frequency = 第3项 +;////// setb Flags2.PGM_PWMOFF_DAMPED_LIGHT +;////// clr Flags2.PGM_PWMOFF_DAMPED_FULL +;////// clr C +;////// cjne Temp8, #4, ($+5) +;Pwm frequency = 第4项 +;////// setb Flags2.PGM_PWMOFF_DAMPED_FULL +ENDIF +;Pwm frequency = 第1项 +;////// clr Flags2.PGM_PWMOFF_DAMPED ; Set damped flag if fully damped or damped light is set +;////// mov A, #((1 SHL PGM_PWMOFF_DAMPED_FULL)+(1 SHL PGM_PWMOFF_DAMPED_LIGHT)) +;////// anl A, Flags2 ; Check if any damped mode is set +;////// jz ($+4) +;Pwm frequency = 第2项 +;////// setb Flags2.PGM_PWMOFF_DAMPED +;Pwm frequency = 第1项 +;////// clr Flags2.CURR_PWMOFF_DAMPED ; Set non damped status as start +;////// jz ($+4) +;Pwm frequency = 第2项 +;////// setb Flags2.CURR_PWMOFF_DAMPED ; Set non damped status as start if damped +;Pwm frequency = 第1项 +;////// setb Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator usable status +;////// jz ($+4) +;Pwm frequency = 第2项 +;////// clr Flags2.CURR_PWMOFF_COMP_ABLE ; Set comparator not usable status if damped +;*********************************************** +; 读取编程电机旋转方向 +;*********************************************** +;读取Rotation direction +;Rotation direction = 第1项 + clr Flags3.PGM_DIR_REV + mov Temp1, #Pgm_Direction_Rev + mov A, @Temp1 + jnb ACC.1, ($+5) +;Rotation direction = 第2项 + setb Flags3.PGM_DIR_REV +;*********************************************** +; 读取编程输入信号RC PWM脉冲有效极性 +;*********************************************** +;读取Input pwm polarity +;Input pwm polarity = 第1项 + clr Flags3.PGM_RCP_PWM_POL + mov Temp1, #Pgm_Input_Pol + mov A, @Temp1 + jnb ACC.1, ($+5) +;Input pwm polarity = 第2项 + setb Flags3.PGM_RCP_PWM_POL +;*********************************************** +; 读取编程PWM频率(2) +;不带硬刹/软刹 +;*********************************************** + clr C + mov A, Temp8 + subb A, #1 + jz decode_pwm_freq_low +;Pwm frequency = 第1项 + mov CKCON, #01h ; Timer0 set for clk/4 (22kHz pwm) + setb Flags2.PGM_PWM_HIGH_FREQ + jmp decode_pwm_freq_end +;Pwm frequency = 第2项 +decode_pwm_freq_low: + mov CKCON, #00h ; Timer0 set for clk/12 (8kHz pwm) + clr Flags2.PGM_PWM_HIGH_FREQ + +decode_pwm_freq_end: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decode governor gain +; +; No assumptions +; +; Decodes governor gains +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +decode_governor_gains: + ; Decode governor gains +;读取 Closed loop P gain + mov Temp1, #Pgm_Gov_P_Gain ; Decode governor P gain + mov A, @Temp1 + dec A + mov DPTR, #GOV_GAIN_TABLE + movc A, @A+DPTR + mov Temp1, #Pgm_Gov_P_Gain_Decoded + mov @Temp1, A +;读取 Closed loop I gain + mov Temp1, #Pgm_Gov_I_Gain ; Decode governor P gain + mov A, @Temp1 + dec A + mov DPTR, #GOV_GAIN_TABLE + movc A, @A+DPTR + mov Temp1, #Pgm_Gov_I_Gain_Decoded + mov @Temp1, A + call switch_power_off ; Reset DPTR + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decode throttle rate +; +; No assumptions +; +; Decodes throttle rate +; +;读取中点油门范围 +;**** **** **** **** **** **** **** **** **** **** **** **** **** +decode_throttle_rate: + ; Decode throttle rate +;读取 Throttle change rate + mov Temp1, #Pgm_Throttle_Rate + mov A, @Temp1 + dec A + mov DPTR, #THROTTLE_RATE_TABLE + movc A, @A+DPTR + mov Temp1, #Pgm_Throttle_Rate_Decoded + mov @Temp1, A + call switch_power_off ; Reset DPTR + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decode startup power +; +; No assumptions +; +; Decodes startup power +; +;编程启动力度 +;**** **** **** **** **** **** **** **** **** **** **** **** **** +decode_startup_power: + ; Decode startup power +;读取 Startup power + mov Temp1, #Pgm_Startup_Pwr + mov A, @Temp1 + dec A + mov DPTR, #STARTUP_POWER_TABLE + movc A, @A+DPTR + mov Temp1, #Pgm_Startup_Pwr_Decoded + mov @Temp1, A + call switch_power_off ; Reset DPTR + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decode demag compensation +; +; No assumptions +; +; Decodes throttle rate +; +;编程demag compensation参数 +;**** **** **** **** **** **** **** **** **** **** **** **** **** +decode_demag_comp: + ; Decode demag compensation +;读取Demag compensation + mov Temp1, #Pgm_Demag_Comp + mov A, @Temp1 + dec A + mov DPTR, #DEMAG_WAIT_TABLE + movc A, @A+DPTR + mov Temp1, #Pgm_Demag_Comp_Wait_Decoded + mov @Temp1, A + mov Temp1, #Pgm_Demag_Comp + mov A, @Temp1 + dec A + mov DPTR, #DEMAG_POWER_TABLE + movc A, @A+DPTR + mov Temp1, #Pgm_Demag_Comp_Power_Decoded + mov @Temp1, A + call switch_power_off ; Reset DPTR + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Set BEC voltage +; +; No assumptions +; +; Sets the BEC output voltage low or high +; +;读取 BEC +;**** **** **** **** **** **** **** **** **** **** **** **** **** +set_bec_voltage: + ; Set bec voltage +IF DUAL_BEC_VOLTAGE == 1 + Set_BEC_Lo ; Set default to low +;读取 Pgm_BEC_Voltage_High + mov Temp1, #Pgm_BEC_Voltage_High + mov A, @Temp1 + jz set_bec_voltage_exit + + Set_BEC_Hi ; Set to high + +set_bec_voltage_exit: +ENDIF + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Find throttle gain +; +; The difference between max and min throttle must be more than 520us (a Pgm_Ppm_xxx_Throttle difference of 130) +; +; Finds throttle gain from throttle calibration values +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +find_throttle_gain: + ; Load programmed minimum and maximum throttle +;读取Pgm_Ppm_Min_Throttle和Pgm_Ppm_Max_Throttle增量 + mov Temp1, #Pgm_Ppm_Min_Throttle + mov A, @Temp1 + mov Temp3, A + mov Temp1, #Pgm_Ppm_Max_Throttle + mov A, @Temp1 + mov Temp4, A + ; Check if full range is chosen + jnb Flags3.FULL_THROTTLE_RANGE, find_throttle_gain_calculate + + mov Temp3, #0 + mov Temp4, #255 + +find_throttle_gain_calculate: + ; Calculate difference + clr C + mov A, Temp4 + subb A, Temp3 + mov Temp5, A + ; Check that difference is minimum 130 + clr C + subb A, #130 + jnc ($+4) + + mov Temp5, #130 + + ; Find gain + mov Ppm_Throttle_Gain, #0 +test_gain: + inc Ppm_Throttle_Gain + mov A, Temp5 + mov B, Ppm_Throttle_Gain ; A has difference, B has gain + mul AB + clr C + mov A, B + subb A, #128 + jc test_gain + ret + + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Main program start +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** + +reset: + ; Select register bank 0 for main program routines + clr PSW.3 ; Select register bank 0 for main program routines + ; Disable the WDT. + anl PCA0MD, #NOT(40h) ; Clear watchdog enable bit + ; Initialize stack + mov SP, #0c0h ; Stack = 64 upper bytes of RAM + ; Initialize VDD monitor + orl VDM0CN, #080h ; Enable the VDD monitor + + mov Temp2, #3 +wait_100us: + djnz ACC, $ + djnz Temp2,wait_100us + +; call wait1ms ; Wait at least 100us + mov RSTSRC, #02h ; Set VDD monitor as a reset source (PORSF) + ; Set clock frequency + orl OSCICN, #03h ; Set clock divider to 1 + mov A, OSCICL + add A, #04h ; 24.5MHz to 24MHz (~0.5% per step) + jc reset_cal_done ; Is carry set? - skip next instruction + + mov OSCICL, A + +reset_cal_done: + ; Ports initialization + mov P0, #P0_INIT + mov P0MDOUT, #P0_PUSHPULL + mov P0MDIN, #P0_DIGITAL + mov P0SKIP, #P0_SKIP + mov P1, #P1_INIT + mov P1MDOUT, #P1_PUSHPULL + mov P1MDIN, #P1_DIGITAL + mov P1SKIP, #P1_SKIP +IF PORT3_EXIST == 1 + mov P2, #P2_INIT +ENDIF + mov P2MDOUT, #P2_PUSHPULL +IF PORT3_EXIST == 1 + mov P2MDIN, #P2_DIGITAL + mov P2SKIP, #P2_SKIP + mov P3, #P3_INIT + mov P3MDOUT, #P3_PUSHPULL + mov P3MDIN, #P3_DIGITAL +ENDIF + mov XBR1, #41h ; Xbar enabled, CEX0 routed to pin Rcp_In + ; Switch power off + call switch_power_off + ; Clear RAM + clr A ; Clear accumulator + mov Temp1, A ; Clear Temp1 +clear_ram: + mov @Temp1, A ; Clear RAM + djnz Temp1, clear_ram ; Is A not zero? - jump + ; Set default programmed parameters + call set_default_parameters + ; Read all programmed parameters + call read_all_eeprom_parameters + ; Decode parameters + call decode_parameters + ; Decode governor gains + call decode_governor_gains + ; Decode throttle rate + call decode_throttle_rate + ; Decode startup power + call decode_startup_power + ; Decode demag compensation + call decode_demag_comp + ; Set BEC voltage + call set_bec_voltage + ; Find throttle gain from stored min and max settings + call find_throttle_gain + ; Set beep strength +;读取超强设置 + mov Temp1, #Pgm_Beep_Strength + mov Beep_Strength, @Temp1 + ; Switch power off + call switch_power_off + ; Timer control + mov TCON, #50h ; Timer0 and timer1 enabled + ; Timer mode + mov TMOD, #02h ; Timer0 as 8bit + ; Timer2: clk/12 for 128us and 32ms interrupts + mov TMR2CN, #24h ; Timer2 enabled, low counter interrups enabled + ; Timer3: clk/12 for commutation timing + mov TMR3CN, #04h ; Timer3 enabled + ; PCA + mov PCA0CN, #40h ; PCA enabled + ; Initializing beep 上电叫3声 + call wait1s + call wait1s + + ; Enable interrupts + mov IE, #22h ; Enable timer0 and timer2 interrupts + mov IP, #02h ; High priority to timer0 interrupts + mov EIE1, #90h ; Enable timer3 and PCA0 interrupts + mov EIP1, #10h ; High priority to PCA interrupts + ; Initialize comparator + mov CPT0CN, #80h ; Comparator enabled, no hysteresis + mov CPT0MD, #03h ; Comparator response time 1us +IF COMP1_USED==1 + mov CPT1CN, #80h ; Comparator enabled, no hysteresis + mov CPT1MD, #03h ; Comparator response time 1us +ENDIF + ; Initialize ADC + Initialize_Adc ; Initialize ADC operation + call wait1ms + setb EA ; Enable all interrupts + ; Measure number of lipo cells + call Measure_Lipo_Cells ; Measure number of lipo cells + ; Initialize rc pulse + Rcp_Int_Enable ; Enable interrupt + Rcp_Int_First ; Enable interrupt and set to first edge + Rcp_Clear_Int_Flag ; Clear interrupt flag + clr Flags2.RCP_EDGE_NO ; Set first edge flag + call wait200ms + ; Set initial arm variable + mov Initial_Arm, #1 +; mov Pca_First_Int, #1 + + ; Measure PWM frequency +measure_pwm_freq_init: + setb Flags0.RCP_MEAS_PWM_FREQ ; Set measure pwm frequency flag +; clr C ;2014.08.08 信号滤波 +; mov A, Pgm_Pulse_Cnt ;2014.08.08 信号滤波 +; subb A, #5 ;2014.08.08 信号滤波 +; jc measure_pwm_freq_init ;2014.08.08 信号滤波 +; mov Pca_First_Int, #0 ;2014.08.08 信号滤波 +; call wait200ms +measure_pwm_freq_start: + mov Temp3, #5 ; Number of pulses to measure +; mov Temp3, #1 +measure_pwm_freq_loop: + ; Check if period diff was accepted + mov A, Rcp_Period_Diff_Accepted +; jnz ($+4) + + jnz measure_pwm + call wait3ms + mov A, New_RCP + clr C + subb A,#230 + jc ($+7) + mov Pgm_Pulse_Cnt, #0 +; mov Temp3, #5 + ajmp measure_pwm_freq_start + + mov A, New_RCP + clr C + subb A,#30 + jnc ($+7) + mov Pgm_Pulse_Cnt, #0 +; mov Temp3, #5 + ajmp measure_pwm_freq_start + + inc Pgm_Pulse_Cnt + mov A, Pgm_Pulse_Cnt + clr C + subb A, #5 + jnc ($+6) + mov Temp3, #5 ; Reset number of pulses to measure + ajmp measure_pwm_freq_loop +; mov Temp3, #1 +measure_pwm: + call wait3ms ; Wait for next pulse (NB: Uses Temp1/2!) + mov A, New_Rcp ; Load value + clr C + subb A, #RCP_VALIDATE ; Higher than validate level? + jc measure_pwm_freq_start ; No - start over + + mov A, Flags3 ; Check pwm frequency flags +; anl A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + anl A, #(1 SHL RCP_PWM_FREQ_1KHZ) + mov Prev_Rcp_Pwm_Freq, Curr_Rcp_Pwm_Freq ; Store as previous flags for next pulse + mov Curr_Rcp_Pwm_Freq, A ; Store current flags for next pulse + cjne A, Prev_Rcp_Pwm_Freq, measure_pwm_freq_start ; Go back if new flags not same as previous + + djnz Temp3, measure_pwm_freq_loop ; Go back if not required number of pulses seen + + ; Clear measure pwm frequency flag + clr Flags0.RCP_MEAS_PWM_FREQ + ; Set up RC pulse interrupts after pwm frequency measurement + Rcp_Int_First ; Enable interrupt and set to first edge + Rcp_Clear_Int_Flag ; Clear interrupt flag + clr Flags2.RCP_EDGE_NO ; Set first edge flag + call wait100ms ; Wait for new RC pulse + + ; Validate RC pulse +;Pgm_Main_Rearm_Start = 第1项 enabled +validate_rcp_start: + call wait3ms ; Wait for next pulse (NB: Uses Temp1/2!) + mov Temp1, #RCP_VALIDATE ; Set validate level as default +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + mov A, #(1 SHL RCP_PWM_FREQ_1KHZ) + anl A, Flags3 ; Check pwm frequency flags + jnz ($+4) ; If a flag is set (PWM) - branch + + mov Temp1, #0 ; Set level to zero for PPM (any level will be accepted) + + clr C + mov A, New_Rcp ; Load value + subb A, Temp1 ; Higher than validate level? + jc validate_rcp_start ; No - start over + + ; Beep arm sequence start signal +;上电检测到信号后叫第1声(信号准备就绪) +;////// clr EA ; Disable all interrupts +;////// call beep_f1 ; Signal that RC pulse is ready +;////// call beep_f1 +;////// call beep_f1 +;////// setb EA ; Enable all interrupts + call wait200ms + + ; Arming sequence start + mov Gov_Arm_Target, #0 ; Clear governor arm target +arming_start: + call wait3ms +;读取Pgm_Enable_TX_Program + mov Temp1, #Pgm_Enable_TX_Program; Yes - start programming mode entry if enabled + mov A, @Temp1 + clr C + subb A, #1 ; Is TX programming enabled? + jnc arming_initial_arm_check ; Yes - proceed + + jmp program_by_tx_checked ; No - branch +;Pgm_Enable_TX_Program = 1 enabled +arming_initial_arm_check: + mov A, Initial_Arm ; Yes - check if it is initial arm sequence + clr C + subb A, #1 ; Is it the initial arm sequence? + jnc arming_ppm_check ; Yes - proceed + + jmp wait_for_power_on ; No - branch + +arming_ppm_check: + mov Temp1, #Pgm_Ppm_Min_Throttle ; Store + mov A, @Temp1 + mov Min_Throttle, A +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + mov A, #(1 SHL RCP_PWM_FREQ_1KHZ) + anl A, Flags3 ; Check pwm frequency flags + jz throttle_high_cal_start ; If no flag is set (PPM) - branch + + ; PWM tx program entry +; clr C +; mov A, New_Rcp ; Load new RC pulse value +; subb A, #200 ; Is RC pulse max? +; jc program_by_tx_entry_wait_pwm ; Yes - proceed +; subb A, #RCP_MAX ; Is RC pulse max? +; jnc program_by_tx_entry_pwm ; Yes - proceed + +; jmp program_by_tx_checked ; No - branch + +;program_by_tx_entry_pwm: +; clr EA ; Disable all interrupts +; call beep_f4 +; setb EA ; Enable all interrupts +; call wait100ms +; clr C +; mov A, New_Rcp ; Load new RC pulse value +; subb A, #RCP_STOP ; Below stop? +; subb A, #200 +; jnc program_by_tx_entry_pwm ; No - start over + +;program_by_tx_entry_wait_pwm: + + clr EA + call beep_f2 + call beep_f3 + call beep_f1 + + mov TMOD, #11h ;T0/T1 工作方式1 + mov CKCON, #02h ;T0/T1 48分频 + mov P0MDIN, #80h + mov P0SKIP, #0FFh + call program_by_card ; Yes - enter programming mode +; ajmp program_by_card_entry + +;program_by_tx_entry_wait_pwm: +; clr EA ; Disable all interrupts +; call beep_f1 +; call wait10ms +; call beep_f1 +; setb EA ; Enable all interrupts +; call wait100ms +; clr C +; mov A, New_Rcp ; Load new RC pulse value +; subb A, #RCP_MAX ; At or above max? +; jc program_by_tx_entry_wait_pwm ; No - start over + +; call program_by_tx ; Yes - enter programming mode +; jmp program_by_tx_checked + + ; PPM throttle calibration and tx program entry +;计算PPM最大,最小油门并存储 +throttle_high_cal_start: + mov Temp8, #5 ; Set 3 seconds wait time +throttle_high_cal: + setb Flags3.FULL_THROTTLE_RANGE ; Set range to 1000-2020us + call Find_Throttle_Gain ; Set throttle gain + call wait100ms ; Wait for new throttle value + clr EA ; Disable interrupts (freeze New_Rcp value) + clr Flags3.FULL_THROTTLE_RANGE ; Set programmed range + call Find_Throttle_Gain ; Set throttle gain + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #220 ; Is RC pulse above midstick? 1840 + setb EA ; Enable interrupts + jc ($+6) + djnz Temp8, throttle_high_cal + ajmp throttle_high_cal_save + + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, Min_Throttle ; Is RC pulse above midstick? 1148 + jnc ($+4) + ajmp arm_target_updated ; No - branch 检测低油门 + + clr EA + call beep_f1; + call wait100ms + setb EA + ajmp throttle_high_cal_start + +throttle_high_cal_save: +; call wait1s + clr C + mov A, New_Rcp ; Limit to max 250 + subb A, #5 ; Subtract about 2% and ensure that it is 250 or lower + mov Temp1, #Pgm_Ppm_Max_Throttle ; Store + mov @Temp1, A + call set_commu_sum_to_zero ;////////////////////////////////////************************** + call erase_and_store_all_in_eeprom + clr EA + call beep_f1;/////////////////////////////////////////成功存储最大油门叫声 + call beep_f1;/////////////////////////////////////////成功存储最大油门叫声 + call wait30ms;/////////////////////////////////////////成功存储最大油门叫声 + call beep_f4;/////////////////////////////////////////成功存储最大油门叫声 + call beep_f4;/////////////////////////////////////////成功存储最大油门叫声 + setb EA + + call wait1s + call wait1s +wait_loop_1: + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #215 ;Is RC pulse above midstick? + jnc program_by_tx_entry_wait_ppm + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #60 ;Is RC pulse above midstick? + jnc wait_loop_1 + ajmp throttle_low_cal_start + + ;PPM编程模式 +program_by_tx_entry_wait_ppm: + call program_by_tx ; Yes - enter programming mode 成功进入编程模式 + +;最小油门设置及退出 +throttle_low_cal_start: + mov Temp8, #5 ; Set 3 seconds wait time +throttle_low_cal: +; call wait1s + setb Flags3.FULL_THROTTLE_RANGE ; Set range to 1000-2020us + call Find_Throttle_Gain ; Set throttle gain + call wait100ms + clr EA ; Disable interrupts (freeze New_Rcp value) + clr Flags3.FULL_THROTTLE_RANGE ; Set programmed range + call Find_Throttle_Gain ; Set throttle gain + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #60 ; Below midstick? + setb EA ; Enable interrupts + jnc throttle_low_cal_start ; No - start over 在中点油门以上,则继续等待,直到检测到在中点油门以下 + djnz Temp8, throttle_low_cal ; Yes - continue to wait +; call wait3ms + mov A, New_Rcp + add A, #5 ; Add about 2% + mov Temp1, #Pgm_Ppm_Min_Throttle ; Store + mov @Temp1, A + call set_commu_sum_to_zero ;////////////////////////////////////************************** + call erase_and_store_all_in_eeprom + +; clr EA ; Disable all interrupts +; mov RSTSRC, #12h ; Generate hardware reset 强制复位系统 + + ; Set default programmed parameters +; call set_default_parameters + ; Read all programmed parameters + call read_all_eeprom_parameters + ; Decode parameters + call decode_parameters + ; Decode governor gains + call decode_governor_gains + ; Decode throttle rate + call decode_throttle_rate + ; Decode startup power + call decode_startup_power + ; Decode demag compensation + call decode_demag_comp + ; Set BEC voltage + call set_bec_voltage + ; Find throttle gain from stored min and max settings + call find_throttle_gain + +program_by_tx_checked: + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, Gov_Arm_Target ; Is RC pulse larger than arm target? + jc arm_target_updated ; No - do not update + + mov Gov_Arm_Target, New_Rcp ; Yes - update arm target + +arm_target_updated: + call wait100ms ; Wait for new throttle value + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_STOP ; Below stop? + jc arm_end_beep ; Yes - proceed ;最小油门计算好 及 编程结束叫声 + jmp arm_target_updated ; No - start over + +;上电检测到信号后叫第2声(信号检测结束) +arm_end_beep: +;改变上电叫方式 + clr EA ; Disable all interrupts + call beep_f1 + call beep_f1 + call beep_f1 + call wait1s + ; Beep arm sequence end signal + +;************************************************* +; 增加Lipo节数叫声 2013.5.29 +;************************************************* + mov Temp8,Lipo_Cell_Count ; +lipo_cell_beep: + call beep_f1 + call beep_f1 + call wait30ms + djnz Temp8,lipo_cell_beep + call wait200ms + call wait200ms +;///// call beep_f4 ; Signal that rcpulse is ready +;///// call beep_f4 +;///// call beep_f4 +;改变信号检测OK叫声方式 2013.5.29 + call beep_f1 + call wait30ms + call wait30ms + call beep_f2 + call wait30ms + call wait30ms + call beep_f3 + call wait30ms + call wait30ms + setb EA ; Enable all interrupts + call wait100ms + + ; Measure number of lipo cells + call Measure_Lipo_Cells ; Measure number of lipo cells + + ; Clear initial arm variable + mov Initial_Arm, #0 + + ; Armed and waiting for power on +wait_for_power_on: + mov Temp8, #50 + clr LOW_LIMIT_STOP ; 清低压保护控制方式2 停止标志 +;////// clr A +;////// mov Power_On_Wait_Cnt_L, A ; Clear wait counter +;////// mov Power_On_Wait_Cnt_H, A +wait_for_power_on_loop: +;////// inc Power_On_Wait_Cnt_L ; Increment low wait counter +;////// mov A, Power_On_Wait_Cnt_L +;////// cpl A +;////// jnz wait_for_power_on_no_beep; Counter wrapping (about 1 sec)? + +;////// inc Power_On_Wait_Cnt_H ; Increment high wait counter +;******************************************************** +; 读取油门最低未操作等待叫声时间 +;******************************************************** +;读取Pgm_Beacon_Delay +;////// mov Temp1, #Pgm_Beacon_Delay +;////// mov A, @Temp1 +;////// mov Temp1, #40 ; Approximately 30 sec +;////// dec A +;////// jz beep_delay_set + +;////// mov Temp1, #80 ; Approximately 1 min +;////// dec A +;////// jz beep_delay_set + +;////// mov Temp1, #160 ; Approximately 2 min +;////// dec A +;////// jz beep_delay_set + +;////// mov Temp1, #240 ; Approximately 3 min +;////// dec A +;////// jz beep_delay_set + +;////// mov Power_On_Wait_Cnt_H, #0 ; Reset counter for infinite delay + +;//////beep_delay_set: +;////// clr C +;////// mov A, Power_On_Wait_Cnt_H +;////// subb A, Temp1 ; Check against chosen delay +;////// jc wait_for_power_on_no_beep; Has delay elapsed? +;******************************************************** +; 读取油门最低未操作等待叫声声强设置 +;******************************************************** +;////// dec Power_On_Wait_Cnt_H ; Decrement high wait counter +;读取Pgm_Beacon_Strength +;////// mov Temp1, #Pgm_Beacon_Strength +;////// mov Beep_Strength, @Temp1 +;////// clr EA ; Disable all interrupts +;////// All_pFETs_Off;///////////////////////////////////////***************************** +;////// call beep_f4 ; Signal that there is no signal +;////// setb EA ; Enable all interrupts +;读取Pgm_Beep_Strength +;////// mov Temp1, #Pgm_Beep_Strength +;////// mov Beep_Strength, @Temp1 +;////// call wait100ms ; Wait for new RC pulse to be measured + +wait_for_power_on_no_beep: + call wait3ms + mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value + jnz wait_for_power_on_ppm_not_missing ; If it is not zero - proceed + +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jnz wait_for_power_on_ppm_not_missing ; If a flag is set (PWM) - branch + + jmp measure_pwm_freq_init ; If ppm and pulses missing - go back to measure pwm frequency + +wait_for_power_on_ppm_not_missing: + clr C + mov A, New_Rcp ; Load new RC pulse value +; subb A, #RCP_STOP ; Higher than stop (plus some hysteresis)? + subb A, #(RCP_STOP+7) ; Higher than stop (plus some hysteresis)? + jc wait_for_power_on ; No - start over + djnz Temp8, wait_for_power_on_no_beep + jb LOW_LIMIT_STOP, wait_for_power_on_loop + call wait100ms ; Wait to see if start pulse was only a glitch + mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value + jnz ($+5) ; If it is not zero - proceed + + ljmp measure_pwm_freq_init ; If it is zero (pulses missing) - go back to measure pwm frequency + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Start entry point +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +init_start: + setb ET0 + call switch_power_off + clr A + mov Requested_Pwm, A ; Set requested pwm to zero + mov Governor_Req_Pwm, A ; Set governor requested pwm to zero + mov Current_Pwm, A ; Set current pwm to zero + mov Current_Pwm_Limited, A ; Set limited current pwm to zero + mov Pwm_Limit, #0FFh ; Set pwm limit to max + mov Temp1, #Pgm_Motor_Idle + mov Pwm_Motor_Idle, @Temp1 ; Set idle pwm to programmed value + mov Gov_Target_L, A ; Set target to zero + mov Gov_Target_H, A + mov Gov_Integral_L, A ; Set integral to zero + mov Gov_Integral_H, A + mov Gov_Integral_X, A + mov Adc_Conversion_Cnt, A + mov Gov_Active, A + mov Flags0, A ; Clear flags0 + mov Flags1, A ; Clear flags1 + mov Rcp_Stop_Cnt, A ; Set RC pulse stop count to zero + mov Rcp_Stop_Limit, A + mov Lipo_Cell_Count, A + mov Limit_Count, A + mov New_Rcp, #Rcp_MIN + call initialize_all_timings ; Initialize timing + ;**** **** **** **** **** + ; Settle phase beginning + ;**** **** **** **** **** + mov Adc_Conversion_Cnt, #TEMP_CHECK_RATE ; Make sure a temp reading is done + Set_Adc_Ip_Temp + call wait1ms + call start_adc_conversion +read_initial_temp: + Get_Adc_Status + jb AD0BUSY, read_initial_temp + Read_Adc_Result ; Read initial temperature + mov A, Temp2 + jnz ($+3) ; Is reading below 256? + + mov Temp1, A ; Yes - set average temperature value to zero + + mov Current_Average_Temp, Temp1 ; Set initial average temperature + call check_temp_voltage_and_limit_power + mov Adc_Conversion_Cnt, #TEMP_CHECK_RATE ; Make sure a temp reading is done next time + Set_Adc_Ip_Temp + + ; Go to the desired startup mode +; mov Temp1, #Pgm_Startup_Method +; mov A, @Temp1 +; jnb ACC.0, direct_method_start + +; jmp stepper_method_start + +direct_method_start: + ; Set up start operating conditions + mov Temp1, #Pgm_Pwm_Freq + mov A, @Temp1 + mov Temp7, A ; Store setting in Temp7 + mov @Temp1, #1 ; Set nondamped low frequency pwm mode + call decode_parameters ; (Decode_parameters uses Temp1 and Temp8) + mov Temp1, #Pgm_Pwm_Freq + mov A, Temp7 + mov @Temp1, A ; Restore settings + ; Set max allowed power + setb Flags1.SETTLE_PHASE ; Set settle phase power as max + clr EA ; Disable interrupts to avoid that Requested_Pwm is overwritten + call set_startup_pwm + mov Pwm_Limit, Requested_Pwm + mov Pwm_Limit_Spoolup, Requested_Pwm + setb EA + clr Flags1.SETTLE_PHASE + mov Current_Pwm_Limited, #0 ; Set low pwm again after calling set_startup_pwm + mov Spoolup_Limit_Cnt, #0 + mov Spoolup_Limit_Skip, #1 + ; Begin startup sequence + setb Flags1.MOTOR_SPINNING ; Set motor spinning flag + setb Flags1.DIRECT_STARTUP_PHASE ; Set direct startup phase flag + mov Direct_Startup_Ok_Cnt, #0 ; Reset ok counter + call comm5comm6 ; Initialize commutation + call comm6comm1 + call calc_next_comm_timing ; Set virtual commutation point + call initialize_all_timings ; Initialize timing + jmp run1 + + +;stepper_method_start: +; ; Set up start operating conditions +; mov Temp1, #Pgm_Pwm_Freq +; mov A, @Temp1 +; mov Temp7, A ; Store setting in Temp7 +; mov @Temp1, #3 ; Set damped light mode +; mov Temp1, #Pgm_Damping_Force +; mov A, @Temp1 +; mov Temp6, A ; Store setting in Temp6 +; mov @Temp1, #5 ; Set high damping force +; call decode_parameters ; (Decode_parameters uses Temp1 and Temp8) +; mov Temp1, #Pgm_Pwm_Freq +; mov A, Temp7 +; mov @Temp1, A ; Restore settings +; mov Temp1, #Pgm_Damping_Force +; mov A, Temp6 +; mov @Temp1, A + ; Begin startup sequence +; setb Flags1.MOTOR_SPINNING ; Set motor spinning flag +; setb Flags1.SETTLE_PHASE ; Set motor start settling phase flag +; setb Flags2.CURR_PWMOFF_DAMPED; Set damped status, in order to ensure that pfets will be turned off in an initial pwm on +; call comm5comm6 ; Initialize commutation +; call comm6comm1 +; call set_startup_pwm +; call wait1ms +; call comm1comm2 +; call wait1ms +; call wait1ms +; call comm2comm3 +; call wait3ms +; call comm3comm4 +; call wait3ms +; call wait3ms +; call comm4comm5 +; call wait10ms ; Settle rotor +; call comm5comm6 +; call wait3ms +; call wait1ms +; clr Flags1.SETTLE_PHASE ; Clear settling phase flag +; setb Flags1.STEPPER_PHASE ; Set motor start stepper phase flag + +; ;**** **** **** **** **** +; ; Stepper phase beginning +; ;**** **** **** **** **** +;stepper_rot_beg: +; call start_adc_conversion +; call check_temp_voltage_and_limit_power +; call set_startup_pwm +; mov Adc_Conversion_Cnt, #TEMP_CHECK_RATE ; Make sure a temp reading is done next time +; Set_Adc_Ip_Temp + +; call comm6comm1 ; Commutate +; call calc_next_comm_timing_start ; Update timing and set timer +; call calc_new_wait_times +; call decrement_stepper_step +; call stepper_timer_wait + +; call comm1comm2 +; call calc_next_comm_timing_start +; call calc_new_wait_times +; call decrement_stepper_step +; call stepper_timer_wait + +; call comm2comm3 +; call calc_next_comm_timing_start +; call calc_new_wait_times +; call decrement_stepper_step +; call stepper_timer_wait + +; call comm3comm4 +; call calc_next_comm_timing_start +; call calc_new_wait_times +; call decrement_stepper_step +; call stepper_timer_wait + +; call comm4comm5 +; call calc_next_comm_timing_start +; call calc_new_wait_times +; call decrement_stepper_step +; call stepper_timer_wait + +; call comm5comm6 +; call calc_next_comm_timing_start +; call calc_new_wait_times +; call decrement_stepper_step +; ; Check stepper step versus end criteria +; clr C +; mov A, Wt_Stepper_Step_L +; subb A, Stepper_Step_End_L ; Minimum Stepper_Step_End +; mov A, Wt_Stepper_Step_H +; subb A, Stepper_Step_End_H +; jc stepper_rot_exit ; Branch if lower than minimum + +; ; Wait for step +; call stepper_timer_wait +; clr C +; mov A, New_Rcp ; Load new pulse value +; subb A, #RCP_STOP ; Check if pulse is below stop value +; jnc stepper_rot_beg + +; jmp run_to_wait_for_power_on + +;stepper_rot_exit: +; ; Wait for step +; call stepper_timer_wait +; ; Clear stepper phase +; clr Flags1.STEPPER_PHASE ; Clear motor start stepper phase flag +; ; Set dondamped low pwm frequency +; mov Temp1, #Pgm_Pwm_Freq +; mov A, @Temp1 +; mov Temp7, A ; Store setting in Temp7 +; mov @Temp1, #2 ; Set nondamped low frequency pwm mode +; call decode_parameters ; (Decode_parameters uses Temp1 and Temp8) +; mov Temp1, #Pgm_Pwm_Freq +; mov A, Temp7 +; mov @Temp1, A ; Restore settings +; ; Set spoolup power variables (power is now controlled from RCP) +; mov Pwm_Limit, Requested_Pwm +; mov Pwm_Limit_Spoolup, Pwm_Spoolup_Beg +; mov Current_Pwm_Limited, Pwm_Spoolup_Beg +; mov Spoolup_Limit_Cnt, #0 +; mov Spoolup_Limit_Skip, #1 +; ; Set direct startup phase to aquire sync quickly +; setb Flags1.DIRECT_STARTUP_PHASE ; Set direct startup phase flag +; mov Direct_Startup_Ok_Cnt, #0 ; Reset ok counter +; clr EA ; Disable interrupts +; ApFET_off ; Ap off. Turn off unused pfets (to turn off damping fets that might be on) +; CpFET_off ; Cp off +; mov A, #45 ; 8us delay for pfets to go off +; djnz ACC, $ +; setb EA ; Enable interrupts +; call comm6comm1 +; call calc_next_comm_timing ; Calculate next timing and start advance timing wait +; call wait_advance_timing ; Wait advance timing and start zero cross wait +; call calc_new_wait_times +; call wait_before_zc_scan ; Wait zero cross wait and start zero cross timeout +; mov Adc_Conversion_Cnt, #0 ; Make sure a voltage reading is done next time +; Set_Adc_Ip_Volt ; Set adc measurement to voltage +; jmp run1 + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Run entry point +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +damped_transition: + ; Transition from nondamped to damped if applicable + call decode_parameters ; Set programmed parameters + call comm6comm1 + mov Adc_Conversion_Cnt, #0 ; Make sure a voltage reading is done next time + Set_Adc_Ip_Volt ; Set adc measurement to voltage + +; Run 1 = B(p-on) + C(n-pwm) - comparator A evaluated +; Out_cA changes from high to low +run1: + call wait_for_comp_out_high ; Wait zero cross wait and wait for high + call evaluate_comparator_integrity ; Check whether comparator reading has been normal + call setup_comm_wait ; Setup wait time from zero cross to commutation + call calc_governor_target ; Calculate governor target + call wait_for_comm ; Wait from zero cross to commutation + call comm1comm2 ; Commutate + call calc_next_comm_timing ; Calculate next timing and start advance timing wait + call wait_advance_timing ; Wait advance timing and start zero cross wait + call calc_new_wait_times + call wait_before_zc_scan ; Wait zero cross wait and start zero cross timeout + +; Run 2 = A(p-on) + C(n-pwm) - comparator B evaluated +; Out_cB changes from low to high +run2: + call wait_for_comp_out_low + call evaluate_comparator_integrity + call setup_comm_wait + call calc_governor_prop_error + call wait_for_comm + call comm2comm3 + call calc_next_comm_timing + call wait_advance_timing + call calc_new_wait_times + call wait_before_zc_scan + +; Run 3 = A(p-on) + B(n-pwm) - comparator C evaluated +; Out_cC changes from high to low +run3: + call wait_for_comp_out_high + call evaluate_comparator_integrity + call setup_comm_wait + call calc_governor_int_error + call wait_for_comm + call comm3comm4 + call calc_next_comm_timing + call wait_advance_timing + call calc_new_wait_times + call wait_before_zc_scan + +; Run 4 = C(p-on) + B(n-pwm) - comparator A evaluated +; Out_cA changes from low to high +run4: + call wait_for_comp_out_low + call evaluate_comparator_integrity + call setup_comm_wait + call calc_governor_prop_correction + call wait_for_comm + call comm4comm5 + call calc_next_comm_timing + call wait_advance_timing + call calc_new_wait_times + call wait_before_zc_scan + +; Run 5 = C(p-on) + A(n-pwm) - comparator B evaluated +; Out_cB changes from high to low +run5: + call wait_for_comp_out_high + call evaluate_comparator_integrity + call setup_comm_wait + call calc_governor_int_correction + call wait_for_comm + call comm5comm6 + call calc_next_comm_timing + call wait_advance_timing + call calc_new_wait_times + call wait_before_zc_scan + +; Run 6 = B(p-on) + A(n-pwm) - comparator C evaluated +; Out_cC changes from low to high +run6: + call wait_for_comp_out_low + call start_adc_conversion + call evaluate_comparator_integrity + call setup_comm_wait + call check_temp_voltage_and_limit_power + call wait_for_comm + call comm6comm1 + call calc_next_comm_timing + call wait_advance_timing + call calc_new_wait_times + call wait_before_zc_scan + + ; Check if it is direct startup + jnb Flags1.DIRECT_STARTUP_PHASE, normal_run_checks + + ; Set spoolup power variables +IF MODE == 0 OR MODE == 2 + mov Pwm_Limit, Pwm_Spoolup_Beg ; Set initial max power + mov Pwm_Limit_Spoolup, Pwm_Spoolup_Beg ; Set initial slow spoolup power +ENDIF +IF MODE == 1 + mov Pwm_Limit, #0FFh ; Allow full power + mov Pwm_Limit_Spoolup, #0FFh +ENDIF + mov Spoolup_Limit_Cnt, #0 + mov Spoolup_Limit_Skip, #1 + ; Check startup ok counter + clr C + mov A, Direct_Startup_Ok_Cnt ; Load ok counter + subb A, #100 ; Is counter above requirement? + jc direct_start_check_rcp ; No - proceed + + clr Flags1.DIRECT_STARTUP_PHASE ; Clear direct startup phase flag + setb Flags1.INITIAL_RUN_PHASE ; Set initial run phase flag + mov Startup_Rot_Cnt, #20 ; Set startup rotation count + jmp normal_run_checks + +direct_start_check_rcp: + clr C + mov A, New_Rcp ; Load new pulse value + subb A, #RCP_STOP ; Check if pulse is below stop value + jc ($+5) + + ljmp run1 ; Continue to run + + jmp run_to_wait_for_power_on + + +normal_run_checks: + ; Check if it is initial run phase + jnb Flags1.INITIAL_RUN_PHASE, initial_run_phase_done; If not initial run phase - branch + + ; Decrement startup rotaton count + mov A, Startup_Rot_Cnt + dec A + ; Check number of nondamped rotations + jnz normal_run_check_startup_rot ; Branch if counter is not zero + + clr Flags1.INITIAL_RUN_PHASE ; Clear initial run phase flag + ljmp damped_transition ; Do damped transition if counter is zero + +normal_run_check_startup_rot: + mov Startup_Rot_Cnt, A ; Not zero - store counter + + clr C + mov A, New_Rcp ; Load new pulse value + subb A, #RCP_STOP ; Check if pulse is below stop value + jc ($+5) + + ljmp run1 ; Continue to run + + jmp run_to_wait_for_power_on + + +initial_run_phase_done: + ; Exit run loop after a given time + clr C + mov A, Rcp_Stop_Cnt ; Load stop RC pulse counter value +;///// subb A, #RCP_STOP_LIMIT ; Is number of stop RC pulses above limit? + subb A, Rcp_Stop_Limit ; Is number of stop RC pulses above limit? + jnc run_to_wait_for_power_on ; Yes, go back to wait for poweron + +run6_check_rcp_timeout: +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jnz run6_check_speed ; If a flag is set (PWM) - branch + + mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value + jz run_to_wait_for_power_on ; If it is zero - go back to wait for poweron + +run6_check_speed: + clr C + mov A, Comm_Period4x_H ; Is Comm_Period4x more than 32ms (~1220 eRPM)? + subb A, #0F0h + jnc run_to_wait_for_power_on ; Yes - go back to motor start + jmp run1 ; Go back to run 1 + + +run_to_wait_for_power_on: + + call switch_power_off + mov Temp1, #Pgm_Pwm_Freq + mov A, @Temp1 + mov Temp7, A ; Store setting in Temp7 + mov @Temp1, #1 ; Set low pwm mode (in order to turn off damping) + call decode_parameters ; (Decode_parameters uses Temp1 and Temp8) + mov Temp1, #Pgm_Pwm_Freq + mov A, Temp7 + mov @Temp1, A ; Restore settings + clr A + mov Requested_Pwm, A ; Set requested pwm to zero + mov Governor_Req_Pwm, A ; Set governor requested pwm to zero + mov Current_Pwm, A ; Set current pwm to zero + mov Current_Pwm_Limited, A ; Set limited current pwm to zero + mov Pwm_Motor_Idle, A ; Set motor idle to zero + clr Flags1.MOTOR_SPINNING ; Clear motor spinning flag + call wait1ms ; Wait for pwm to be stopped + call switch_power_off + call wait10ms + clr ET0 + jb Flags2.PGM_PWMOFF_DAMPED, light_damp + ajmp damp_exit + +light_damp: + jb Flags2.PGM_PWMOFF_DAMPED_LIGHT, ($+7) + setb P1.BnFET + ajmp damp_exit + jb Flags2.PGM_PWMOFF_DAMPED_FULL, high_damp + A_B_nFETs_On + ajmp damp_exit +high_damp: + All_nFETs_On +damp_exit: + +IF MODE == 0 ; Main + mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) + anl A, Flags3 ; Check pwm frequency flags + jnz run_to_next_state_main ; If a flag is set (PWM) - branch + + mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value + jnz run_to_next_state_main ; If it is not zero - branch + + jmp measure_pwm_freq_init ; If it is zero (pulses missing) - go back to measure pwm frequency + +run_to_next_state_main: + mov Temp1, #Pgm_Startup_Method ; Check if it is stepped startup + mov A, @Temp1 + jnb ACC.0, run_to_next_state_main_wait_done ; If direct startup - jump + + call wait1s ; 3 second delay before new startup (in stepped mode) + call wait1s + call wait1s +run_to_next_state_main_wait_done: +;读取Pgm_Main_Rearm_Start + mov Temp1, #Pgm_Main_Rearm_Start + mov A, @Temp1 + clr C + subb A, #1 ; Is re-armed start enabled? + jc jmp_wait_for_power_on ; No - do like tail and start immediately + + jmp validate_rcp_start ; Yes - go back to validate RC pulse +;Pgm_Main_Rearm_Start = 第2项 disabled +jmp_wait_for_power_on: + jmp wait_for_power_on ; Go back to wait for power on +ENDIF +IF MODE >= 1 ; Tail or multi +; mov A, #((1 SHL RCP_PWM_FREQ_1KHZ)+(1 SHL RCP_PWM_FREQ_2KHZ)+(1 SHL RCP_PWM_FREQ_4KHZ)+(1 SHL RCP_PWM_FREQ_8KHZ)) +; anl A, Flags3 ; Check pwm frequency flags +; jnz jmp_wait_for_power_on ; If a flag is set (PWM) - branch + + mov A, Rcp_Timeout_Cnt ; Load RC pulse timeout counter value + jnz jmp_wait_for_power_on ; If it is not zero - go back to wait for poweron + + jmp measure_pwm_freq_init ; If it is zero (pulses missing) - go back to measure pwm frequency + +jmp_wait_for_power_on: + jmp wait_for_power_on_loop ; Go back to wait for power on +ENDIF + +;**** **** **** **** **** **** **** **** **** **** **** **** **** + +$include (BLHeliTxPgm.inc) ; Include source code for programming the ESC with the TX + +;**** **** **** **** **** **** **** **** **** **** **** **** **** + + + + +END diff --git a/SiLabs/EMAX_BLHeliTxPgm.inc b/SiLabs/EMAX_BLHeliTxPgm.inc new file mode 100644 index 00000000..fd68e598 --- /dev/null +++ b/SiLabs/EMAX_BLHeliTxPgm.inc @@ -0,0 +1,1213 @@ +;**** **** **** **** **** +; +; BLHeli program for controlling brushless motors in helicopters +; +; Copyright 2011, 2012 Steffen Skaug +; This program is distributed under the terms of the GNU General Public License +; +; This file is part of BLHeli. +; +; BLHeli is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. +; +; BLHeli is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with BLHeli. If not, see . +; +;**** **** **** **** **** +; +; BLHeliTxPgm SiLabs +; +; EEPROM is not available in SiLabs MCUs +; Therefore a segment of the flash is used as "EEPROM" +; +;**** **** **** **** **** + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Read all eeprom perameters routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** + + + + +read_all_eeprom_parameters: + ; Check initialized signature + mov DPTR, #Eep_Initialized_L + mov Temp1, #Bit_Access + call read_eeprom_byte + mov A, Bit_Access +IF MODE == 0 + cjne A, #0A5h, read_eeprom_store_defaults +ENDIF +IF MODE == 1 + cjne A, #05Ah, read_eeprom_store_defaults +ENDIF +IF MODE == 2 + cjne A, #055h, read_eeprom_store_defaults +ENDIF + inc DPTR ; Now Eep_Initialized_H + call read_eeprom_byte + mov A, Bit_Access +IF MODE == 0 + cjne A, #05Ah, read_eeprom_store_defaults +ENDIF +IF MODE == 1 + cjne A, #0A5h, read_eeprom_store_defaults +ENDIF +IF MODE == 2 + cjne A, #0AAh, read_eeprom_store_defaults +ENDIF + jmp read_eeprom_read + + +read_eeprom_store_defaults: + call set_default_parameters + call set_commu_sum_to_zero ;////////////////////////////////////************************** + call erase_and_store_all_in_eeprom + jmp read_eeprom_exit + +read_eeprom_read: + ; Read eeprom +IF MODE == 0 + mov DPTR, #Eep_Pgm_Gov_P_Gain + mov Temp1, #Pgm_Gov_P_Gain + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_I_Gain + inc Temp1 ; Now Pgm_Gov_I_Gain + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_Mode + inc Temp1 ; Now Pgm_Gov_Mode + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Low_Voltage_Lim + inc Temp1 ; Now Pgm_Low_Voltage_Lim + call read_eeprom_byte + + inc DPTR ; Motor_Gain + inc Temp1 + + inc DPTR ; Motor_Idle + inc Temp1 +ENDIF +IF MODE == 1 + mov Temp1, #Pgm_Gov_Mode + mov @Temp1, #4 + + mov DPTR, #Eep_Pgm_Motor_Gain + mov Temp1, #Pgm_Motor_Gain + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Motor_Idle + inc Temp1 ; Now Pgm_Motor_Idle + call read_eeprom_byte +ENDIF +IF MODE == 2 + mov DPTR, #Eep_Pgm_Fir_Key + mov Temp1, #Pgm_Fir_Key + call read_eeprom_byte + +; mov DPTR, #Eep_Pgm_Gov_P_Gain +; mov Temp1, #Pgm_Gov_P_Gain + inc DPTR ; Now Eep_Pgm_Gov_P_Gain + inc Temp1 ; Now Pgm_Gov_P_Gain + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_I_Gain + inc Temp1 ; Now Pgm_Gov_I_Gain + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_Mode + inc Temp1 ; Now Pgm_Gov_Mode + call read_eeprom_byte + +; mov DPTR, #Eep_Pgm_Low_Voltage_Lim +; mov Temp1, #Pgm_Low_Voltage_Lim + inc DPTR ; Now Eep_Pgm_Low_Voltage_Lim + inc Temp1 ; Now Pgm_Low_Voltage_Lim + call read_eeprom_byte + +; mov DPTR, #Eep_Pgm_Low_Voltage_Ctl +; mov Temp1, #Pgm_Low_Voltage_Ctl + inc DPTR ; Now Eep_Pgm_Low_Voltage_Ctl + inc Temp1 ; Now Pgm_Low_Voltage_Ctl + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Motor_Gain + inc Temp1 ; Now Pgm_Motor_Gain + call read_eeprom_byte + + inc DPTR ; Motor_Idle + inc Temp1 +ENDIF + + inc DPTR ; Now Eep_Pgm_Startup_Pwr + inc Temp1 ; Now Pgm_Startup_Pwr + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Pwm_Freq + inc Temp1 ; Now Pgm_Pwm_Freq + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Direction_Rev + inc Temp1 ; Now Pgm_Direction_Rev + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Input_Pol + inc Temp1 ; Now Pgm_Input_Pol + call read_eeprom_byte + + inc DPTR ; Initialized_L + inc Temp1 + + inc DPTR ; Initialized_H + inc Temp1 + + inc DPTR ; Now Eep_Enable_TX_Program + inc Temp1 ; Now Pgm_Enable_TX_Program + call read_eeprom_byte + +IF MODE == 0 + inc DPTR ; Now Eep_Main_Rearm_Start + inc Temp1 ; Now Pgm_Main_Rearm_Start + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_Setup_Target + inc Temp1 ; Now Pgm_Gov_Setup_Target + call read_eeprom_byte +ENDIF +IF MODE == 1 + inc DPTR ; Main_Rearm_Start + inc Temp1 + + inc DPTR ; Gov_Setup_Target + inc Temp1 +ENDIF +IF MODE == 2 + inc DPTR ; Main_Rearm_Start + inc Temp1 + + inc DPTR ; Gov_Setup_Target + inc Temp1 + call read_eeprom_byte +ENDIF + + inc DPTR ; Now Eep_Pgm_Startup_Rpm + inc Temp1 ; Now Pgm_Startup_Rpm + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Startup_Accel + inc Temp1 ; Now Pgm_Startup_Accel + call read_eeprom_byte + + inc DPTR ; Volt_Comp + inc Temp1 + + inc DPTR ; Now Eep_Pgm_Comm_Timing + inc Temp1 ; Now Pgm_Comm_Timing + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Damping_Force + inc Temp1 ; Now Pgm_Damping_Force + call read_eeprom_byte + +IF MODE == 0 + inc DPTR ; Now Eep_Pgm_Gov_Range + inc Temp1 ; Now Pgm_Gov_Range + call read_eeprom_byte +ENDIF +IF MODE >= 1 + inc DPTR ; Gov_Range + inc Temp1 +ENDIF + +; inc DPTR ; Now Eep_Pgm_Startup_Method +; inc Temp1 ; Now Pgm_Startup_Method +; call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Ppm_Min_Throttle + inc Temp1 ; Now Pgm_Ppm_Min_Throttle + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Ppm_Max_Throttle + inc Temp1 ; Now Pgm_Ppm_Max_Throttle + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Beep_Strength + inc Temp1 ; Now Pgm_Beep_Strength + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Beacon_Strength + inc Temp1 ; Now Pgm_Beacon_Strength + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Beacon_Delay + inc Temp1 ; Now Pgm_Beacon_Delay + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Throttle_Rate + inc Temp1 ; Now Pgm_Throttle_Rate + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Demag_Comp + inc Temp1 ; Now Pgm_Demag_Comp + call read_eeprom_byte + + inc DPTR ; Now Eep_Pgm_BEC_Voltage_High + inc Temp1 ; Now Pgm_BEC_Voltage_High + call read_eeprom_byte + + mov DPTR, #Eep_Dummy ; Set pointer to uncritical area + +read_eeprom_exit: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Erase flash and store all parameter value in EEPROM routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +erase_and_store_all_in_eeprom: + clr EA ; Disable interrupts +; call read_tags + call erase_flash ; Erase flash + + mov DPTR, #Eep_FW_Main_Revision ; Store firmware main revision + mov A, #EEPROM_FW_MAIN_REVISION + call write_eeprom_byte_from_acc + + inc DPTR ; Now firmware sub revision + mov A, #EEPROM_FW_SUB_REVISION + call write_eeprom_byte_from_acc + + inc DPTR ; Now layout revision + mov A, #EEPROM_LAYOUT_REVISION + call write_eeprom_byte_from_acc + +IF MODE == 0 + mov DPTR, #Eep_Pgm_Gov_P_Gain + mov Temp1, #Pgm_Gov_P_Gain + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_I_Gain + inc Temp1 ; Now Pgm_Gov_I_Gain + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_Mode + inc Temp1 ; Now Pgm_Gov_Mode + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Low_Voltage_Lim + inc Temp1 ; Now Pgm_Low_Voltage_Lim + call write_eeprom_byte + + inc DPTR ; Motor_Gain + inc Temp1 + + inc DPTR ; Motor_Idle + inc Temp1 +ENDIF +IF MODE == 1 + mov DPTR, #Eep_Pgm_Motor_Gain + mov Temp1, #Pgm_Motor_Gain + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Motor_Idle + inc Temp1 ; Now Pgm_Motor_Idle + call write_eeprom_byte +ENDIF +IF MODE == 2 + mov DPTR, #Eep_Pgm_Fir_Key + mov Temp1, #Pgm_Fir_Key + call write_eeprom_byte + +; mov DPTR, #Eep_Pgm_Gov_P_Gain +; mov Temp1, #Pgm_Gov_P_Gain + inc DPTR ; Now Eep_Pgm_Gov_P_Gain + inc Temp1 ; Now Pgm_Gov_P_Gain + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_I_Gain + inc Temp1 ; Now Pgm_Gov_I_Gain + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_Mode + inc Temp1 ; Now Pgm_Gov_Mode + call write_eeprom_byte + +; mov DPTR, #Eep_Pgm_Low_Voltage_Lim +; mov Temp1, #Pgm_Low_Voltage_Lim + inc DPTR ; Now Eep_Pgm_Low_Voltage_Lim + inc Temp1 ; Now Pgm_Low_Voltage_Lim + call write_eeprom_byte + +; mov DPTR, #Eep_Pgm_Low_Voltage_Ctl +; mov Temp1, #Pgm_Low_Voltage_Ctl + inc DPTR ; Now Eep_Pgm_Low_Voltage_Ctl + inc Temp1 ; Now Pgm_Low_Voltage_Ctl + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Motor_Gain + inc Temp1 ; Now Pgm_Motor_Gain + call write_eeprom_byte + + inc DPTR ; Motor_Idle + inc Temp1 +ENDIF + + inc DPTR ; Now Eep_Pgm_Startup_Pwr + inc Temp1 ; Now Pgm_Startup_Pwr + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Pwm_Freq + inc Temp1 ; Now Pgm_Pwm_Freq + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Direction_Rev + inc Temp1 ; Now Pgm_Direction_Rev + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Input_Pol + inc Temp1 ; Now Pgm_Input_Pol + call write_eeprom_byte + + inc DPTR ; Initialized_L + inc Temp1 + + inc DPTR ; Initialized_H + inc Temp1 + + inc DPTR ; Now Eep_Enable_TX_Program + inc Temp1 ; Now Pgm_Enable_TX_Program + call write_eeprom_byte + +IF MODE == 0 + inc DPTR ; Now Eep_Main_Rearm_Start + inc Temp1 ; Now Pgm_Main_Rearm_Start + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Gov_Setup_Target + inc Temp1 ; Now Pgm_Gov_Setup_Target + call write_eeprom_byte +ENDIF +IF MODE == 1 + inc DPTR ; Main_Rearm_Start + inc Temp1 + + inc DPTR ; Gov_Setup_Target + inc Temp1 +ENDIF +IF MODE == 2 + inc DPTR ; Main_Rearm_Start + inc Temp1 + + inc DPTR ; Gov_Setup_Target + inc Temp1 + call write_eeprom_byte +ENDIF + + inc DPTR ; Now Eep_Pgm_Startup_Rpm + inc Temp1 ; Now Pgm_Startup_Rpm + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Startup_Accel + inc Temp1 ; Now Pgm_Startup_Accel + call write_eeprom_byte + + inc DPTR ; Volt_Comp + inc Temp1 + + inc DPTR ; Now Eep_Pgm_Comm_Timing + inc Temp1 ; Now Pgm_Comm_Timing + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Damping_Force + inc Temp1 ; Now Pgm_Damping_Force + call write_eeprom_byte + +IF MODE == 0 + inc DPTR ; Now Eep_Pgm_Gov_Range + inc Temp1 ; Now Pgm_Gov_Range + call write_eeprom_byte +ENDIF +IF MODE >= 1 + inc DPTR ; Gov_Range + inc Temp1 +ENDIF + +; inc DPTR ; Now Eep_Pgm_Startup_Method +; inc Temp1 ; Now Pgm_Startup_Method +; call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Ppm_Min_Throttle + inc Temp1 ; Now Pgm_Ppm_Min_Throttle + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Ppm_Max_Throttle + inc Temp1 ; Now Pgm_Ppm_Max_Throttle + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Beep_Strength + inc Temp1 ; Now Pgm_Beep_Strength + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Beacon_Strength + inc Temp1 ; Now Pgm_Beacon_Strength + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Beacon_Delay + inc Temp1 ; Now Pgm_Beacon_Delay + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Throttle_Rate + inc Temp1 ; Now Pgm_Throttle_Rate + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_Demag_Comp + inc Temp1 ; Now Pgm_Demag_Comp + call write_eeprom_byte + + inc DPTR ; Now Eep_Pgm_BEC_Voltage_High + inc Temp1 ; Now Pgm_BEC_Voltage_High + call write_eeprom_byte + +; call write_tags + call write_eeprom_signature + mov DPTR, #Eep_Dummy ; Set pointer to uncritical area + setb EA ;保存数据后如果不产生复位,则必须加 此语句 2013.7.12 + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +CSEG AT 1C00h ; Last code segment. Take care that there is enough space! +;**** **** **** **** **** **** **** **** **** **** **** **** **** + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Read eeprom byte routine +; +; Gives data in A and in address given by Temp1. Assumes address in DPTR +; Also assumes address high byte to be zero +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +read_eeprom_byte: + clr A + movc A, @A+DPTR ; Read from flash + mov @Temp1, A + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Write eeprom byte routine +; +; Assumes data in address given by Temp1, or in accumulator. Assumes address in DPTR +; Also assumes address high byte to be zero +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +write_eeprom_byte: + mov A, @Temp1 +write_eeprom_byte_from_acc: + orl PSCTL, #01h ; Set the PSWE bit + anl PSCTL, #0FDh ; Clear the PSEE bit + mov RSTSRC, #02h ; Set VDD monitor as a reset source (PORSF) + mov FLKEY, #0A5h ; First key code + mov FLKEY, #0F1h ; Second key code + movx @DPTR, A ; Write to flash + anl PSCTL, #0FEh ; Clear the PSWE bit + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Erase flash routine (erases the flash segment used for "eeprom" variables) +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +erase_flash: + orl PSCTL, #02h ; Set the PSEE bit + orl PSCTL, #01h ; Set the PSWE bit + mov RSTSRC, #02h ; Set VDD monitor as a reset source (PORSF) + mov FLKEY, #0A5h ; First key code + mov FLKEY, #0F1h ; Second key code + mov DPTR, #Eep_Initialized_L + movx @DPTR, A + anl PSCTL, #0FCh ; Clear the PSEE and PSWE bits + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Write eeprom signature routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +write_eeprom_signature: +IF MODE == 0 + mov DPTR, #Eep_Initialized_L + mov A, #0A5h + call write_eeprom_byte_from_acc + + mov DPTR, #Eep_Initialized_H + mov A, #05Ah + call write_eeprom_byte_from_acc +ENDIF +IF MODE == 1 + mov DPTR, #Eep_Initialized_L + mov A, #05Ah + call write_eeprom_byte_from_acc + + mov DPTR, #Eep_Initialized_H + mov A, #0A5h + call write_eeprom_byte_from_acc +ENDIF +IF MODE == 2 + mov DPTR, #Eep_Initialized_L + mov A, #055h + call write_eeprom_byte_from_acc + + mov DPTR, #Eep_Initialized_H + mov A, #0AAh + call write_eeprom_byte_from_acc +ENDIF + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Read all tags from flash and store in temporary storage +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +read_tags: + mov Temp3, #48 ; Number of tags + mov Temp2, #Tag_Temporary_Storage ; Set RAM address + mov Temp1, #Bit_Access + mov DPTR, #Eep_ESC_Layout ; Set flash address +read_tag: + call read_eeprom_byte + mov A, Bit_Access + mov @Temp2, A ; Write to RAM + inc Temp2 + inc DPTR + djnz Temp3, read_tag + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Write all tags from temporary storage and store in flash +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +write_tags: + mov Temp3, #48 ; Number of tags + mov Temp2, #Tag_Temporary_Storage ; Set RAM address + mov DPTR, #Eep_ESC_Layout ; Set flash address +write_tag: + mov A, @Temp2 ; Read from RAM + call write_eeprom_byte_from_acc + inc Temp2 + inc DPTR + djnz Temp3, write_tag + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Store new parameter value in ram routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +store_new_value_in_ram: + mov Temp4, Tx_Pgm_Func_No ; Function no + mov Temp1, Tx_Pgm_Paraval_No ; Parameter value no +IF MODE == 0 +store_main_func_1: + cjne Temp4, #1, store_main_func_2 + mov Temp2, #Pgm_Gov_P_Gain + jmp store_in_ram_exit + +store_main_func_2: + cjne Temp4, #2, store_main_func_3 + mov Temp2, #Pgm_Gov_I_Gain + jmp store_in_ram_exit + +store_main_func_3: + cjne Temp4, #3, store_main_func_4 + mov Temp2, #Pgm_Gov_Mode + jmp store_in_ram_exit + +store_main_func_4: + cjne Temp4, #4, store_main_func_5 + mov Temp2, #Pgm_Gov_Range + jmp store_in_ram_exit + +store_main_func_5: + cjne Temp4, #5, store_main_func_6 + mov Temp2, #Pgm_Low_Voltage_Lim + jmp store_in_ram_exit + +store_main_func_6: + cjne Temp4, #6, store_main_func_7 + mov Temp2, #Pgm_Startup_Method + jmp store_in_ram_exit + +store_main_func_7: + cjne Temp4, #7, store_main_func_8 + mov Temp2, #Pgm_Startup_Pwr + jmp store_in_ram_exit + +store_main_func_8: + cjne Temp4, #8, store_main_func_9 + mov Temp2, #Pgm_Startup_Rpm + jmp store_in_ram_exit + +store_main_func_9: + cjne Temp4, #9, store_main_func_10 + mov Temp2, #Pgm_Startup_Accel + jmp store_in_ram_exit + +store_main_func_10: + cjne Temp4, #10, store_main_func_11 + mov Temp2, #Pgm_Comm_Timing + jmp store_in_ram_exit + +store_main_func_11: + cjne Temp4, #11, store_main_func_12 + mov Temp2, #Pgm_Throttle_Rate + jmp store_in_ram_exit + +store_main_func_12: + cjne Temp4, #12, store_main_func_13 + mov Temp2, #Pgm_Damping_Force + jmp store_in_ram_exit + +store_main_func_13: + cjne Temp4, #13, store_main_func_14 + mov Temp2, #Pgm_Pwm_Freq + jmp store_in_ram_exit + +store_main_func_14: + cjne Temp4, #14, store_main_func_15 + mov Temp2, #Pgm_Demag_Comp + jmp store_in_ram_exit + +store_main_func_15: + cjne Temp4, #15, store_main_func_16 + mov Temp2, #Pgm_Direction_Rev + jmp store_in_ram_exit + +store_main_func_16: + mov Temp2, #Pgm_Input_Pol + jmp store_in_ram_exit +ENDIF +IF MODE == 1 +store_tail_func_1: + cjne Temp4, #1, store_tail_func_2 + mov Temp2, #Pgm_Motor_Gain + jmp store_in_ram_exit + +store_tail_func_2: + cjne Temp4, #2, store_tail_func_3 + mov Temp2, #Pgm_Motor_Idle + jmp store_in_ram_exit + +store_tail_func_3: + cjne Temp4, #3, store_tail_func_4 + mov Temp2, #Pgm_Startup_Method + jmp store_in_ram_exit + +store_tail_func_4: + cjne Temp4, #4, store_tail_func_5 + mov Temp2, #Pgm_Startup_Pwr + jmp store_in_ram_exit + +store_tail_func_5: + cjne Temp4, #5, store_tail_func_6 + mov Temp2, #Pgm_Startup_Rpm + jmp store_in_ram_exit + +store_tail_func_6: + cjne Temp4, #6, store_tail_func_7 + mov Temp2, #Pgm_Startup_Accel + jmp store_in_ram_exit + +store_tail_func_7: + cjne Temp4, #7, store_tail_func_8 + mov Temp2, #Pgm_Comm_Timing + jmp store_in_ram_exit + +store_tail_func_8: + cjne Temp4, #8, store_tail_func_9 + mov Temp2, #Pgm_Throttle_Rate + jmp store_in_ram_exit + +store_tail_func_9: + cjne Temp4, #9, store_tail_func_10 + mov Temp2, #Pgm_Damping_Force + jmp store_in_ram_exit + +store_tail_func_10: + cjne Temp4, #10, store_tail_func_11 + mov Temp2, #Pgm_Pwm_Freq + jmp store_in_ram_exit + +store_tail_func_11: + cjne Temp4, #11, store_tail_func_12 + mov Temp2, #Pgm_Demag_Comp + jmp store_in_ram_exit + +store_tail_func_12: + cjne Temp4, #12, store_tail_func_13 + mov Temp2, #Pgm_Direction_Rev + jmp store_in_ram_exit + +store_tail_func_13: + mov Temp2, #Pgm_Input_Pol + jmp store_in_ram_exit +ENDIF +IF MODE == 2 +;///////store_multi_func_1: +;/////// cjne Temp4, #1, store_multi_func_2 +;/////// mov Temp2, #Pgm_Gov_P_Gain ;读取Closed loop P gain地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_2: +;/////// cjne Temp4, #2, store_multi_func_3 +;/////// mov Temp2, #Pgm_Gov_I_Gain ;读取Closed loop I gain地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_3: +;/////// cjne Temp4, #3, store_multi_func_4 +;/////// mov Temp2, #Pgm_Gov_Mode ;读取Closed loop mode(曲线)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_4: +;/////// cjne Temp4, #4, store_multi_func_5 +;/////// mov Temp2, #Pgm_Motor_Gain ;读取Multi gain地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_5: +;/////// cjne Temp4, #5, store_multi_func_6 +;/////// mov Temp2, #Pgm_Low_Voltage_Lim ;读取Low voltage limit(低压保护)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_6: +;/////// cjne Temp4, #6, store_multi_func_7 +;/////// mov Temp2, #Pgm_Startup_Method ;读取Startup method(启动方式)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_7: +;/////// cjne Temp4, #7, store_multi_func_8 +;/////// mov Temp2, #Pgm_Startup_Pwr ;读取Startup power(启动力度)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_8: +;/////// cjne Temp4, #8, store_multi_func_9 +;/////// mov Temp2, #Pgm_Startup_Rpm ;读取Startup rpm(启动转速)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_9: +;/////// cjne Temp4, #9, store_multi_func_10 +;/////// mov Temp2, #Pgm_Startup_Accel ;读取Startup acceleration(启动...)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_10: +;/////// cjne Temp4, #10, store_multi_func_11 +;/////// mov Temp2, #Pgm_Comm_Timing ;读取Commutation timing(进角)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_11: +;/////// cjne Temp4, #11, store_multi_func_12 +;/////// mov Temp2, #Pgm_Throttle_Rate ;读取Throttle change rate(中点范围)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_12: +;/////// cjne Temp4, #12, store_multi_func_13 +;/////// mov Temp2, #Pgm_Damping_Force ;读取Damping force(刹车力度)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_13: +;/////// cjne Temp4, #13, store_multi_func_14 +;/////// mov Temp2, #Pgm_Pwm_Freq ;读取Pwm frequence(PWM频率)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_14: +;/////// cjne Temp4, #14, store_multi_func_15 +;/////// mov Temp2, #Pgm_Demag_Comp ;读取Demag compensation(刹车...)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_15: +;/////// cjne Temp4, #15, store_multi_func_16 +;/////// mov Temp2, #Pgm_Direction_Rev ;读取Rotation direction(旋转方式)地址 +;/////// jmp store_in_ram_exit + +;///////store_multi_func_16: +;/////// mov Temp2, #Pgm_Input_Pol ;读取Input pwm polarity(PWM输入信号方式)地址 +;/////// jmp store_in_ram_exit + + + + +store_multi_func_1: + cjne Temp4, #1, store_multi_func_2 + mov Temp2, #Pgm_Damping_Force ;读取Damping force(刹车力度)地址 + jmp store_in_ram_exit + +store_multi_func_2: + cjne Temp4, #2, store_multi_func_3 + mov Temp2, #Pgm_Comm_Timing ;读取Commutation timing(进角)地址 + jmp store_in_ram_exit + +;store_multi_func_3: +; cjne Temp4, #3, store_multi_func_4 +; mov Temp2, #Pgm_Direction_Rev ;读取Rotation direction(旋转方式)地址 +; jmp store_in_ram_exit + +store_multi_func_3: + cjne Temp4, #3, store_multi_func_4 + mov Temp2, #Pgm_Startup_Pwr ;读取Startup power(启动力度)地址 + jmp store_in_ram_exit + +store_multi_func_4: + cjne Temp4, #4, store_multi_func_5 + mov Temp2, #Pgm_Gov_Mode ;读取Closed loop mode(曲线)地址 + jmp store_in_ram_exit + +store_multi_func_5: + cjne Temp4, #5, store_multi_func_6 + mov Temp2, #Pgm_Pwm_Freq ;读取Startup method(启动方式)地址 + jmp store_in_ram_exit + +store_multi_func_6: + cjne Temp4, #6, store_multi_func_7 + mov Temp2, #Pgm_Low_Voltage_Lim ;读取Low voltage limit(低压保护)地址 + jmp store_in_ram_exit + +store_multi_func_7: + mov Temp2, #Pgm_Low_Voltage_Ctl ;读取Low voltage limit(低压保护)地址 + jmp store_in_ram_exit +ENDIF + +store_in_ram_exit: + mov A, Temp1 + mov @Temp2, A + ret + + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Program by TX routine +; +; No assumptions +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +program_by_tx: + ; Programming mode entry beeps + call success_beep + setb Flags0.PROGRAM_FUNC_FLAG ;编程功能标志 +wait_for_program: + mov Temp5, #10 +default_set_check: + call wait200ms + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_STOP ; Below stop? + jc wait_for_next_status + + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_MAX ; Below max? + jc wait_for_program + djnz Temp5, default_set_check ;等待进入新设置 + ajmp function_no_entry + +wait_for_next_status: + mov Temp5, #10 +wait_for_exit: + call wait200ms + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_STOP ; Below stop? + jnc ($+7) + djnz Temp5, wait_for_exit + ajmp program_exit + + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_MAX ; Below max? + jc wait_for_next_status + call set_default_parameters ; Load all defaults + call set_commu_sum_to_zero ;////////////////////////////////////************************** + call erase_and_store_all_in_eeprom ; Erase flash and program + call success_beep_inverted + ajmp wait_for_program + + + ; Start at function 1, parameter value 1 +function_no_entry: + mov Tx_Pgm_Func_No, #1 +function_no_beep: + call function_paraval_beep + mov Temp5, #10 ; Wait is 5x 200ms +function_no_wait: + mov Temp6, New_Rcp + call wait200ms + clr C + mov A, Temp6 + subb A, New_Rcp + jnz function_no_wait ; No - branch + + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_STOP ; Below stop? + jc paraval_no_wait + + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_MAX ; Below max? + jnc function_no_next + + ajmp function_no_wait ;等待摇杆拉高或拉低 + +function_no_next: ; Yes - Next function value + jnb Flags0.PROGRAM_FUNC_FLAG, func_paraval_store ;=0,则存储参数 + djnz Temp5,function_no_wait + inc Tx_Pgm_Func_No ; Function value no 功能+1 + mov A,Tx_Pgm_Func_No + subb A,#8 + jc function_no_beep + + mov Temp5, #10 +func_over_wait: + call wait200ms + clr C + mov A, New_Rcp + subb A, #RCP_STOP + jc program_by_tx_exit ;below stop---exit + + clr C + mov A, New_Rcp + subb A, #RCP_MAX + jc func_over_wait ;等待摇杆拉高或拉低 + djnz Temp5, func_over_wait ; 摇杆一直处于拉高,等待2s结束 + + ajmp function_no_entry ;返回从第一项开始 + +func_paraval_store: + setb Flags0.PROGRAM_FUNC_FLAG ;编程功能标志 + call store_new_value_in_ram ; Yes - store new value in RAM + call set_commu_sum_to_zero ;////////////////////////////////////************************** + call erase_and_store_all_in_eeprom ; Store all values in EEPROM + call success_beep_inverted ; Beep success 改变存储叫声 + mov Temp5, #10 ;存储完后等待时间 +store_wait: ; + call wait200ms + clr C + mov A, New_Rcp + subb A, #RCP_STOP + jc program_by_tx_exit ; + + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_MAX ; Below max? + jc store_wait + djnz Temp5, store_wait ;摇杆一直处于拉高状态,等待2s结束 + mov Temp5, #1 + ajmp function_no_next + + + +paraval_no_wait: + mov Temp5, #10 ;10*200=1s时间 +paraval_wait: + call wait200ms + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_MAX ; Below max? + jnc function_no_wait + + clr C + mov A, New_Rcp + subb A, #RCP_STOP ; Below stop? + jnc paraval_wait ;等待摇杆拉高或拉低 + + djnz Temp5,paraval_wait ; 摇杆一直处于拉低,等待1s结束 + clr Flags0.PROGRAM_FUNC_FLAG ;保存标志 +paraval_no_entry: + mov Tx_Pgm_Paraval_No, #1 +paraval_no_beep: + call function_paraval_beep + mov Temp5, #10 +paraval_no_next: + call wait200ms + clr C + mov A, New_Rcp ; Load new RC pulse value + subb A, #RCP_MAX ; Below max? + jnc function_no_next ; Yes - branch 跳回项目编程 + + clr C + mov A, New_Rcp + subb A, #RCP_STOP ; Below stop? + jnc paraval_no_next ;等待摇杆拉高或拉低 + + djnz Temp5, paraval_no_next ; 摇杆一直处于拉低,等待1s结束 + + inc Tx_Pgm_Paraval_No ; Function value no 参数+1 + mov A, Tx_Pgm_Func_No ; Decode number of parameters + dec A + mov DPTR, #TX_PGM_PARAMS_MULTI + movc A, @A+DPTR + mov Temp1, A + + inc Temp1 + clr C + mov A, Tx_Pgm_Paraval_No + subb A, Temp1 + jnc paraval_no_entry ; Last parameter value? + ajmp paraval_no_beep ; No - go back + +program_by_tx_exit: + mov Temp5, #10 ;10*200=2s时间 +exit_wait: + call wait200ms + clr C + mov A, New_Rcp + subb A, #RCP_STOP ; Below stop? + jnc exit_wait ;等待退出 + djnz Temp5,exit_wait +program_exit: +ret + + + + +; mov Tx_Pgm_Func_No, #1 +;paraval_no_entry: +; mov Tx_Pgm_Paraval_No, #1 +;beep_no_entry: +; mov Tx_Pgm_Beep_No, #0 +;func_paraval: +; call function_paraval_beep +; mov Temp5, #5 ; Wait is 5x 200ms +;func_paraval_wait: +; mov Temp6, New_Rcp ; Store RC pulse +; call wait200ms +; clr C +; mov A, Temp6 +; subb A, New_Rcp ; Is RC pulse stable? (Avoid issues from 3in1 interference) +; jnz func_paraval_wait ; No - branch +; clr C +; mov A, New_Rcp ; Load new RC pulse value +; subb A, #RCP_STOP ; Below stop? +; jc func_paraval_store ; Yes - branch + +; clr C +; mov A, New_Rcp ; Load new RC pulse value +; subb A, #RCP_MAX ; Below max? +; jc function_next ; Yes - branch + +; ajmp func_paraval_cont_wait ; No - branch + +;func_paraval_store: +; call store_new_value_in_ram ; Yes - store new value in RAM +; call erase_and_store_all_in_eeprom ; Store all values in EEPROM +; call success_beep_inverted ; Beep success 改变存储叫声 +; clr EA ; Disable all interrupts +; mov RSTSRC, #12h ; Generate hardware reset 强制复位系统 +; call wait1s + +;func_paraval_cont_wait: +; djnz Temp5, func_paraval_wait +; inc Tx_Pgm_Beep_No ; Check number of beeps +; clr C +; mov A, Tx_Pgm_Beep_No +; subb A, #3 ; Three beeps done? +; jnc paraval_next ; Yes - Next parameter value + +; jmp func_paraval ; No - go back + +;paraval_next: +; call wait1s +; inc Tx_Pgm_Paraval_No ; Parameter value no +;IF MODE == 0 +; mov A, Tx_Pgm_Func_No ; Decode number of parameters +; dec A +; mov DPTR, #TX_PGM_PARAMS_MAIN +; movc A, @A+DPTR +; mov Temp1, A +;ENDIF +;IF MODE == 1 +; mov A, Tx_Pgm_Func_No ; Decode number of parameters +; dec A +; mov DPTR, #TX_PGM_PARAMS_TAIL +; movc A, @A+DPTR +; mov Temp1, A +;ENDIF +;IF MODE == 2 +; mov A, Tx_Pgm_Func_No ; Decode number of parameters +; dec A +; mov DPTR, #TX_PGM_PARAMS_MULTI +; movc A, @A+DPTR +; mov Temp1, A +;ENDIF +; inc Temp1 +; clr C +; mov A, Tx_Pgm_Paraval_No +; subb A, Temp1 +; jnc function_next ; Last parameter value? +; jmp beep_no_entry ; No - go back + +;function_next: ; Yes - Next function value +; call wait1s +; call wait1s +; inc Tx_Pgm_Func_No ; Function value no +;IF MODE == 0 +; clr C +; mov A, Tx_Pgm_Func_No +; subb A, #17 ; Main has 16 functions +;ENDIF +;IF MODE == 1 +; clr C +; mov A, Tx_Pgm_Func_No +; subb A, #14 ; Tail has 13 functions +;ENDIF +;IF MODE == 2 +; clr C +; mov A, Tx_Pgm_Func_No +;////// subb A, #17 ; Multi has 16 functions +; subb A, #8 ; Multi has 16 functions +;ENDIF +; jnc program_by_tx_exit ; Last function value? +; jmp paraval_no_entry ; No - go back + +;program_by_tx_exit: +; call set_default_parameters ; Load all defaults +; call erase_and_store_all_in_eeprom ; Erase flash and program +; clr EA ; Disable all interrupts +; mov RSTSRC, #12h ; Generate hardware reset 强制复位系统 +; call wait1s diff --git a/SiLabs/EMAX_BLHeli_20A.inc b/SiLabs/EMAX_BLHeli_20A.inc new file mode 100644 index 00000000..273a3762 --- /dev/null +++ b/SiLabs/EMAX_BLHeli_20A.inc @@ -0,0 +1,472 @@ +;--------------------------------------------------------------------------- +; +; +; +; +; FILE NAME: C8051F330.INC +; TARGET MCUs: C8051F330, F331 +; DESCRIPTION: Register/bit definitions for the C8051F330 product family. +; +; REVISION 1.0 +; +;--------------------------------------------------------------------------- + +;REGISTER DEFINITIONS +; +P0 DATA 080H ; PORT 0 LATCH +SP DATA 081H ; STACK POINTER +DPL DATA 082H ; DATA POINTER LOW +DPH DATA 083H ; DATA POINTER HIGH +PCON DATA 087H ; POWER CONTROL +TCON DATA 088H ; TIMER/COUNTER CONTROL +TMOD DATA 089H ; TIMER/COUNTER MODE +TL0 DATA 08AH ; TIMER/COUNTER 0 LOW +TL1 DATA 08BH ; TIMER/COUNTER 1 LOW +TH0 DATA 08CH ; TIMER/COUNTER 0 HIGH +TH1 DATA 08DH ; TIMER/COUNTER 1 HIGH +CKCON DATA 08EH ; CLOCK CONTROL +PSCTL DATA 08FH ; PROGRAM STORE R/W CONTROL +P1 DATA 090H ; PORT 1 LATCH +TMR3CN DATA 091H ; TIMER/COUNTER 3 CONTROL +TMR3RLL DATA 092H ; TIMER/COUNTER 3 RELOAD LOW +TMR3RLH DATA 093H ; TIMER/COUNTER 3 RELOAD HIGH +TMR3L DATA 094H ; TIMER/COUNTER 3 LOW +TMR3H DATA 095H ; TIMER/COUNTER 3 HIGH +IDA0L DATA 096H ; CURRENT MODE DAC0 LOW +IDA0H DATA 097H ; CURRENT MODE DAC0 HIGH +SCON0 DATA 098H ; UART0 CONTROL +SBUF0 DATA 099H ; UART0 DATA BUFFER +CPT0CN DATA 09BH ; COMPARATOR0 CONTROL +CPT0MD DATA 09DH ; COMPARATOR0 MODE SELECTION +CPT0MX DATA 09FH ; COMPARATOR0 MUX SELECTION +P2 DATA 0A0H ; PORT 2 LATCH +SPI0CFG DATA 0A1H ; SPI CONFIGURATION +SPI0CKR DATA 0A2H ; SPI CLOCK RATE CONTROL +SPI0DAT DATA 0A3H ; SPI DATA +P0MDOUT DATA 0A4H ; PORT 0 OUTPUT MODE CONFIGURATION +P1MDOUT DATA 0A5H ; PORT 1 OUTPUT MODE CONFIGURATION +P2MDOUT DATA 0A6H ; PORT 2 OUTPUT MODE CONFIGURATION +IE DATA 0A8H ; INTERRUPT ENABLE +CLKSEL DATA 0A9H ; CLOCK SELECT +EMI0CN DATA 0AAH ; EXTERNAL MEMORY INTERFACE CONTROL +OSCXCN DATA 0B1H ; EXTERNAL OSCILLATOR CONTROL +OSCICN DATA 0B2H ; INTERNAL OSCILLATOR CONTROL +OSCICL DATA 0B3H ; INTERNAL OSCILLATOR CALIBRATION +FLSCL DATA 0B6H ; FLASH SCALE +FLKEY DATA 0B7H ; FLASH LOCK AND KEY +IP DATA 0B8H ; INTERRUPT PRIORITY +IDA0CN DATA 0B9H ; CURRENT MODE DAC0 CONTROL +AMX0N DATA 0BAH ; AMUX0 NEGATIVE CHANNEL SELECT +AMX0P DATA 0BBH ; AMUX0 POSITIVE CHANNEL SELECT +ADC0CF DATA 0BCH ; ADC0 CONFIGURATION +ADC0L DATA 0BDH ; ADC0 LOW +ADC0H DATA 0BEH ; ADC0 HIGH +SMB0CN DATA 0C0H ; SMBUS CONTROL +SMB0CF DATA 0C1H ; SMBUS CONFIGURATION +SMB0DAT DATA 0C2H ; SMBUS DATA +ADC0GTL DATA 0C3H ; ADC0 GREATER-THAN COMPARE LOW +ADC0GTH DATA 0C4H ; ADC0 GREATER-THAN COMPARE HIGH +ADC0LTL DATA 0C5H ; ADC0 LESS-THAN COMPARE WORD LOW +ADC0LTH DATA 0C6H ; ADC0 LESS-THAN COMPARE WORD HIGH +TMR2CN DATA 0C8H ; TIMER/COUNTER 2 CONTROL +TMR2RLL DATA 0CAH ; TIMER/COUNTER 2 RELOAD LOW +TMR2RLH DATA 0CBH ; TIMER/COUNTER 2 RELOAD HIGH +TMR2L DATA 0CCH ; TIMER/COUNTER 2 LOW +TMR2H DATA 0CDH ; TIMER/COUNTER 2 HIGH +PSW DATA 0D0H ; PROGRAM STATUS WORD +REF0CN DATA 0D1H ; VOLTAGE REFERENCE CONTROL +P0SKIP DATA 0D4H ; PORT 0 SKIP +P1SKIP DATA 0D5H ; PORT 1 SKIP +PCA0CN DATA 0D8H ; PCA CONTROL +PCA0MD DATA 0D9H ; PCA MODE +PCA0CPM0 DATA 0DAH ; PCA MODULE 0 MODE REGISTER +PCA0CPM1 DATA 0DBH ; PCA MODULE 1 MODE REGISTER +PCA0CPM2 DATA 0DCH ; PCA MODULE 2 MODE REGISTER +ACC DATA 0E0H ; ACCUMULATOR +XBR0 DATA 0E1H ; PORT I/O CROSSBAR CONTROL 0 +XBR1 DATA 0E2H ; PORT I/O CROSSBAR CONTROL 1 +OSCLCN DATA 0E3H ; LOW-FREQUENCY OSCILLATOR CONTROL +IT01CF DATA 0E4H ; INT0/INT1 CONFIGURATION +EIE1 DATA 0E6H ; EXTENDED INTERRUPT ENABLE 1 +ADC0CN DATA 0E8H ; ADC0 CONTROL +PCA0CPL1 DATA 0E9H ; PCA CAPTURE 1 LOW +PCA0CPH1 DATA 0EAH ; PCA CAPTURE 1 HIGH +PCA0CPL2 DATA 0EBH ; PCA CAPTURE 2 LOW +PCA0CPH2 DATA 0ECH ; PCA CAPTURE 2 HIGH +RSTSRC DATA 0EFH ; RESET SOURCE CONFIGURATION/STATUS +B DATA 0F0H ; B REGISTER +P0MDIN DATA 0F1H ; PORT 0 INPUT MODE CONFIGURATION +P1MDIN DATA 0F2H ; PORT 1 INPUT MODE CONFIGURATION +EIP1 DATA 0F6H ; EXTENDED INTERRUPT PRIORITY 1 +SPI0CN DATA 0F8H ; SPI CONTROL +PCA0L DATA 0F9H ; PCA COUNTER LOW +PCA0H DATA 0FAH ; PCA COUNTER HIGH +PCA0CPL0 DATA 0FBH ; PCA CAPTURE 0 LOW +PCA0CPH0 DATA 0FCH ; PCA CAPTURE 0 HIGH +VDM0CN DATA 0FFH ; VDD MONITOR CONTROL + +; +;------------------------------------------------------------------------------ +;BIT DEFINITIONS +; +; TCON 088H +TF1 BIT 08FH ; TIMER 1 OVERFLOW FLAG +TR1 BIT 08EH ; TIMER 1 ON/OFF CONTROL +TF0 BIT 08DH ; TIMER 0 OVERFLOW FLAG +TR0 BIT 08CH ; TIMER 0 ON/OFF CONTROL +IE1 BIT 08BH ; EXT. INTERRUPT 1 EDGE FLAG +IT1 BIT 08AH ; EXT. INTERRUPT 1 TYPE +IE0 BIT 089H ; EXT. INTERRUPT 0 EDGE FLAG +IT0 BIT 088H ; EXT. INTERRUPT 0 TYPE + +; SCON0 098H +S0MODE BIT 09FH ; UART 0 MODE +MCE0 BIT 09DH ; UART 0 MCE +REN0 BIT 09CH ; UART 0 RX ENABLE +TB80 BIT 09BH ; UART 0 TX BIT 8 +RB80 BIT 09AH ; UART 0 RX BIT 8 +TI0 BIT 099H ; UART 0 TX INTERRUPT FLAG +RI0 BIT 098H ; UART 0 RX INTERRUPT FLAG + +; IE 0A8H +EA BIT 0AFH ; GLOBAL INTERRUPT ENABLE +ESPI0 BIT 0AEH ; SPI0 INTERRUPT ENABLE +ET2 BIT 0ADH ; TIMER 2 INTERRUPT ENABLE +ES0 BIT 0ACH ; UART0 INTERRUPT ENABLE +ET1 BIT 0ABH ; TIMER 1 INTERRUPT ENABLE +EX1 BIT 0AAH ; EXTERNAL INTERRUPT 1 ENABLE +ET0 BIT 0A9H ; TIMER 0 INTERRUPT ENABLE +EX0 BIT 0A8H ; EXTERNAL INTERRUPT 0 ENABLE + +; IP 0B8H +PSPI0 BIT 0BEH ; SPI0 PRIORITY +PT2 BIT 0BDH ; TIMER 2 PRIORITY +PS0 BIT 0BCH ; UART0 PRIORITY +PT1 BIT 0BBH ; TIMER 1 PRIORITY +PX1 BIT 0BAH ; EXTERNAL INTERRUPT 1 PRIORITY +PT0 BIT 0B9H ; TIMER 0 PRIORITY +PX0 BIT 0B8H ; EXTERNAL INTERRUPT 0 PRIORITY + +; SMB0CN 0C0H +MASTER BIT 0C7H ; SMBUS 0 MASTER/SLAVE +TXMODE BIT 0C6H ; SMBUS 0 TRANSMIT MODE +STA BIT 0C5H ; SMBUS 0 START FLAG +STO BIT 0C4H ; SMBUS 0 STOP FLAG +ACKRQ BIT 0C3H ; SMBUS 0 ACKNOWLEDGE REQUEST +ARBLOST BIT 0C2H ; SMBUS 0 ARBITRATION LOST +ACK BIT 0C1H ; SMBUS 0 ACKNOWLEDGE FLAG +SI BIT 0C0H ; SMBUS 0 INTERRUPT PENDING FLAG + +; TMR2CN 0C8H +TF2H BIT 0CFH ; TIMER 2 HIGH BYTE OVERFLOW FLAG +TF2L BIT 0CEH ; TIMER 2 LOW BYTE OVERFLOW FLAG +TF2LEN BIT 0CDH ; TIMER 2 LOW BYTE INTERRUPT ENABLE +TF2CEN BIT 0CCH ; TIMER 2 LFO CAPTURE ENABLE +T2SPLIT BIT 0CBH ; TIMER 2 SPLIT MODE ENABLE +TR2 BIT 0CAH ; TIMER 2 ON/OFF CONTROL +T2XCLK BIT 0C8H ; TIMER 2 EXTERNAL CLOCK SELECT + +; PSW 0D0H +CY BIT 0D7H ; CARRY FLAG +AC BIT 0D6H ; AUXILIARY CARRY FLAG +F0 BIT 0D5H ; USER FLAG 0 +RS1 BIT 0D4H ; REGISTER BANK SELECT 1 +RS0 BIT 0D3H ; REGISTER BANK SELECT 0 +OV BIT 0D2H ; OVERFLOW FLAG +F1 BIT 0D1H ; USER FLAG 1 +P BIT 0D0H ; ACCUMULATOR PARITY FLAG + +; PCA0CN 0D8H +CF BIT 0DFH ; PCA 0 COUNTER OVERFLOW FLAG +CR BIT 0DEH ; PCA 0 COUNTER RUN CONTROL BIT +CCF2 BIT 0DAH ; PCA 0 MODULE 2 INTERRUPT FLAG +CCF1 BIT 0D9H ; PCA 0 MODULE 1 INTERRUPT FLAG +CCF0 BIT 0D8H ; PCA 0 MODULE 0 INTERRUPT FLAG + ; ADC 0 WINDOW INTERRUPT FLAG +; ADC0CN 0E8H +AD0EN BIT 0EFH ; ADC 0 ENABLE +AD0TM BIT 0EEH ; ADC 0 TRACK MODE +AD0INT BIT 0EDH ; ADC 0 EOC INTERRUPT FLAG +AD0BUSY BIT 0ECH ; ADC 0 BUSY FLAG +AD0WINT BIT 0EBH ; ADC 0 WINDOW INTERRUPT FLAG +AD0CM2 BIT 0EAH ; ADC 0 CONVERT START MODE BIT 2 +AD0CM1 BIT 0E9H ; ADC 0 CONVERT START MODE BIT 1 +AD0CM0 BIT 0E8H ; ADC 0 CONVERT START MODE BIT 0 + +; SPI0CN 0F8H +SPIF BIT 0FFH ; SPI 0 INTERRUPT FLAG +WCOL BIT 0FEH ; SPI 0 WRITE COLLISION FLAG +MODF BIT 0FDH ; SPI 0 MODE FAULT FLAG +RXOVRN BIT 0FCH ; SPI 0 RX OVERRUN FLAG +NSSMD1 BIT 0FBH ; SPI 0 SLAVE SELECT MODE 1 +NSSMD0 BIT 0FAH ; SPI 0 SLAVE SELECT MODE 0 +TXBMT BIT 0F9H ; SPI 0 TX BUFFER EMPTY FLAG +SPIEN BIT 0F8H ; SPI 0 SPI ENABLE + + +;**** **** **** **** **** +; Uses internal calibrated oscillator set to 24Mhz +;**** **** **** **** **** + +;**** **** **** **** **** +; Constant definitions +;**** **** **** **** **** +CSEG AT 1A40h +Eep_ESC_Layout: DB "#XP18A# " ; ESC layout tag +CSEG AT 1A50h +Eep_ESC_MCU: DB "#BLHELI#F330# " ; Project and MCU tag (16 Bytes) + +PORT3_EXIST EQU 0 ; Set to 1 if MCU has port3 +COMP1_USED EQU 0 ; Set to 1 if MCU has comparator 1 and it is being used +DUAL_BEC_VOLTAGE EQU 0 ; Set to 1 if dual BEC voltage is supported +DAMPED_MODE_ENABLE EQU 1 ; Damped mode disabled +NFETON_DELAY EQU 1 ; Wait delay from pfets off to nfets on +PFETON_DELAY EQU 1 ; Wait delay from nfets off to pfets on +COMP_PWM_HIGH_ON_DELAY EQU 15 ; Wait delay from pwm on until comparator can be read (for high pwm frequency) +COMP_PWM_HIGH_OFF_DELAY EQU 20 ; Wait delay from pwm off until comparator can be read (for high pwm frequency) +COMP_PWM_LOW_ON_DELAY EQU 5 ; Wait delay from pwm on until comparator can be read (for low pwm frequency) +COMP_PWM_LOW_OFF_DELAY EQU 7 ; Wait delay from pwm off until comparator can be read (for low pwm frequency) +ADC_LIMIT_L EQU 80 ;改一节电池低压基值 2.8V 2013.05.31 +;ADC_LIMIT_L EQU 85 ; Power supply measurement ADC value for which main motor power is limited (low byte) +ADC_LIMIT_H EQU 0 ; Power supply measurement ADC value for which main motor power is limited (2 MSBs) +TEMP_LIMIT EQU 92 ; 2013.8.20 温度140改120 Temperature measurement ADC value for which main motor power is limited (low byte, assuming high byte is 1) +TEMP_LIMIT_STEP EQU 5 ; Temperature measurement ADC value increment for which main motor power is further limited +MAIN_SPOOLUP_TIME EQU 10 ; Main motor spoolup time + +;**** **** **** **** **** +; ESC specific defaults +;**** **** **** **** **** +DEFAULT_PGM_MAIN_STARTUP_PWR EQU 10 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50 +DEFAULT_PGM_TAIL_STARTUP_PWR EQU 10 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50 +DEFAULT_PGM_MULTI_STARTUP_PWR EQU 10 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50 +DEFAULT_PGM_MAIN_STARTUP_METHOD EQU 2 ; 1=Stepped 2=Direct +DEFAULT_PGM_TAIL_STARTUP_METHOD EQU 2 ; 1=Stepped 2=Direct +DEFAULT_PGM_MULTI_STARTUP_METHOD EQU 2 ; 1=Stepped 2=Direct + + +;********************* +; PORT 0 definitions * +;********************* +Rcp_In EQU 7 ;i +Adc_Ip EQU 6 ;i +Mux_A EQU 5 ;i +; EQU 4 ;i +Mux_B EQU 3 ;i +Comp_Com EQU 2 ;i +Mux_C EQU 1 ;i +Vref EQU 0 ;i + +P0_DIGITAL EQU NOT((1 SHL Mux_A)+(1 SHL Mux_B)+(1 SHL Mux_C)+(1 SHL Comp_Com)+(1 SHL Adc_Ip)+(1 SHL Vref)) +P0_INIT EQU 0FFh +P0_PUSHPULL EQU 0 +P0_SKIP EQU NOT(1 SHL Rcp_In) AND 0FFh + +MACRO Read_Rcp_Int + mov A, P0 + jnb Flags3.PGM_RCP_PWM_POL, ($+4) ; Is pwm polarity negative? + cpl A ; Yes - invert +ENDM +MACRO Rcp_Int_Enable + orl PCA0CPM0, #01h ; Interrupt enabled +ENDM +MACRO Rcp_Int_Disable + anl PCA0CPM0, #0FEh ; Interrupt disabled +ENDM +MACRO Rcp_Int_First + anl PCA0CPM0, #0CFh + jb Flags3.PGM_RCP_PWM_POL, ($+6) ; Is pwm polarity positive? + orl PCA0CPM0, #20h ; Capture rising edge + jnb Flags3.PGM_RCP_PWM_POL, ($+6) ; Is pwm polarity negative? + orl PCA0CPM0, #10h ; Capture falling edge +ENDM +MACRO Rcp_Int_Second + anl PCA0CPM0, #0CFh + jb Flags3.PGM_RCP_PWM_POL, ($+6) ; Is pwm polarity positive? + orl PCA0CPM0, #10h ; Capture falling edge + jnb Flags3.PGM_RCP_PWM_POL, ($+6) ; Is pwm polarity negative? + orl PCA0CPM0, #20h ; Capture rising edge +ENDM +MACRO Rcp_Clear_Int_Flag + clr CCF0 ; Clear interrupt flag +ENDM + + +;********************* +; PORT 1 definitions * +;********************* +DriverEn EQU 7 ;o At least on some escs. Others are hardwired +; EQU 6 ;i +AnFET EQU 2 ;o "nFETs" are really the high side drivers +BnFET EQU 1 ;o +CnFET EQU 0 ;o +ApFET EQU 5 ;o "pFETs" are really the low side drivers +BpFET EQU 4 ;o +CpFET EQU 3 ;o + +P1_DIGITAL EQU (1 SHL AnFET)+(1 SHL BnFET)+(1 SHL CnFET)+(1 SHL ApFET)+(1 SHL BpFET)+(1 SHL CpFET)+(1 SHL DriverEn) +P1_INIT EQU 080h +P1_PUSHPULL EQU (1 SHL AnFET)+(1 SHL BnFET)+(1 SHL CnFET)+(1 SHL ApFET)+(1 SHL BpFET)+(1 SHL CpFET)+(1 SHL DriverEn) +P1_SKIP EQU 0 + +MACRO AnFET_on + mov A, Current_Pwm_Limited + jz ($+12) + jb Flags3.PGM_DIR_REV, ($+5) + setb P1.AnFET + jnb Flags3.PGM_DIR_REV, ($+5) + setb P1.CnFET +ENDM +MACRO AnFET_off + jb Flags3.PGM_DIR_REV, ($+5) + clr P1.AnFET + jnb Flags3.PGM_DIR_REV, ($+5) + clr P1.CnFET +ENDM +MACRO BnFET_on + mov A, Current_Pwm_Limited + jz ($+4) + setb P1.BnFET +ENDM +MACRO BnFET_off + clr P1.BnFET +ENDM +MACRO CnFET_on + mov A, Current_Pwm_Limited + jz ($+12) + jb Flags3.PGM_DIR_REV, ($+5) + setb P1.CnFET + jnb Flags3.PGM_DIR_REV, ($+5) + setb P1.AnFET +ENDM +MACRO CnFET_off + jb Flags3.PGM_DIR_REV, ($+5) + clr P1.CnFET + jnb Flags3.PGM_DIR_REV, ($+5) + clr P1.AnFET +ENDM +MACRO All_nFETs_Off + clr P1.AnFET + clr P1.BnFET + clr P1.CnFET +ENDM +MACRO All_nFETs_On + setb P1.AnFET + setb P1.BnFET + setb P1.CnFET +ENDM +MACRO A_B_nFETs_On + setb P1.AnFET + setb P1.BnFET +ENDM + +MACRO ApFET_on + jb Flags3.PGM_DIR_REV, ($+5) + setb P1.ApFET + jnb Flags3.PGM_DIR_REV, ($+5) + setb P1.CpFET +ENDM +MACRO ApFET_off + jb Flags3.PGM_DIR_REV, ($+5) + clr P1.ApFET + jnb Flags3.PGM_DIR_REV, ($+5) + clr P1.CpFET +ENDM +MACRO BpFET_on + setb P1.BpFET +ENDM +MACRO BpFET_off + clr P1.BpFET +ENDM +MACRO CpFET_on + jb Flags3.PGM_DIR_REV, ($+5) + setb P1.CpFET + jnb Flags3.PGM_DIR_REV, ($+5) + setb P1.ApFET +ENDM +MACRO CpFET_off + jb Flags3.PGM_DIR_REV, ($+5) + clr P1.CpFET + jnb Flags3.PGM_DIR_REV, ($+5) + clr P1.ApFET +ENDM +MACRO All_pFETs_Off + clr P1.ApFET + clr P1.BpFET + clr P1.CpFET +ENDM +;MACRO All_pFETs_On +; setb P1.ApFET +; setb P1.BpFET +; setb P1.CpFET +;ENDM + +MACRO Set_Comp_Phase_A + jb Flags3.PGM_DIR_REV, ($+6) + mov CPT0MX, #21h ; Set comparator multiplexer to phase A + jnb Flags3.PGM_DIR_REV, ($+6) + mov CPT0MX, #01h +ENDM +MACRO Set_Comp_Phase_B + mov CPT0MX, #11h ; Set comparator multiplexer to phase B +ENDM +MACRO Set_Comp_Phase_C + jb Flags3.PGM_DIR_REV, ($+6) + mov CPT0MX, #01h ; Set comparator multiplexer to phase C + jnb Flags3.PGM_DIR_REV, ($+6) + mov CPT0MX, #21h +ENDM +MACRO Read_Comp_Out + mov A, CPT0CN ; Read comparator output + cpl A +ENDM + + +;********************* +; PORT 2 definitions * +;********************* +DebugPin EQU 0 ;o + +P2_PUSHPULL EQU (1 SHL DebugPin) + + +;********************** +; MCU specific macros * +;********************** +MACRO Interrupt_Table_Definition +CSEG AT 0 ; Code segment start + jmp reset +CSEG AT 0Bh ; Timer0 interrupt + jmp t0_int +CSEG AT 2Bh ; Timer2 interrupt + jmp t2_int +CSEG AT 5Bh ; PCA interrupt + jmp pca_int +CSEG AT 73h ; Timer3 interrupt + jmp t3_int +ENDM + +MACRO Initialize_Adc + mov REF0CN, #0Eh ; Set vdd (3.3V) as reference. Enable temp sensor and bias + mov ADC0CF, #58h ; ADC clock 2MHz + mov AMX0P, #Adc_Ip ; Select positive input + mov AMX0N, #11h ; Select negative input as ground + mov ADC0CN, #80h ; ADC enabled +ENDM +MACRO Set_Adc_Ip_Volt + mov AMX0P, #Adc_Ip ; Select positive input 选择电压检测,P0.6为电压正输入 +ENDM +MACRO Set_Adc_Ip_Temp + mov AMX0P, #10h ; Select temp sensor input +ENDM +MACRO Start_Adc + mov ADC0CN, #90h ; ADC start +ENDM +MACRO Get_Adc_Status + mov A, ADC0CN +ENDM +MACRO Read_Adc_Result + mov Temp1, ADC0L + mov Temp2, ADC0H +ENDM +MACRO Stop_Adc +ENDM diff --git a/SiLabs/Hex files/EMAX_BLHeli_20A.hex b/SiLabs/Hex files/EMAX_BLHeli_20A.hex new file mode 100644 index 00000000..b6926e20 --- /dev/null +++ b/SiLabs/Hex files/EMAX_BLHeli_20A.hex @@ -0,0 +1,426 @@ +:030000000212CE1B +:03000B000200B838 +:03002B000203E9E4 +:03005B000204E5B7 +:030073000204DBA9 +:1000800002030406080C10182030406080020304AC +:1000900006080C101820304080FF0406080C1018C9 +:1000A0002030406080A0C000000001010003020277 +:1000B0000106050D04020402C2AFC0D0C0E02062F8 +:1000C0000D302F02E47330680280F90203D5306BE3 +:1000D00006C292C291C29085258AC262E525F4705B +:1000E0000221C8055C306813207219758B00D0E0BE +:1000F000D0D0C292C291C290D2AF32C292C291C24B +:10010000900201B8D276C277E560601CC3E55C144A +:1001100095604014C276D277C3E55C955F500302C8 +:1001200001B8755C000201B82074030201B8D277EF +:10013000C292C291C290E53A20E24020E1167401D9 +:10014000D5E0FDE525600A207C02D290307C02D209 +:10015000920201B820E0167401D5E0FDE525600AA1 +:10016000207C02D290307C02D2920201B87401D578 +:10017000E0FDE5256002D2910201B820E12720E0F0 +:100180000E7401D5E0FDE5256002D2910201B8743C +:1001900001D5E0FDE525600A207C02D292307C0288 +:1001A000D2900201B87401D5E0FDE525600A207CFB +:1001B00002D292307C02D290758B00D0E0D0D0C2B7 +:1001C00092C291C290D2AF32D0E0D0D0D2AF3261E1 +:1001D000D5E525600A207C02D292307C02D290C202 +:1001E0009161D5E5256002D291207C02C290307CDD +:1001F00002C29261D5E525600A207C02D290307C53 +:1002000002D292207C02C292307C02C29061D52040 +:100210007C02C295307C02C293E525600A207C02F4 +:10022000D292307C02D290207C02C293307C02C2F7 +:1002300095C29161D5207C02C295307C02C2932088 +:100240007C02C293307C02C2957401D5E0FDE525A5 +:10025000600A207C02D292307C02D290C29161D599 +:10026000207C02C295307C02C293E525600A207C86 +:1002700002D292307C02D290C294C29161D5207C8D +:1002800002C295307C02C293C2947401D5E0FDE5B0 +:1002900025600A207C02D292307C02D290C2916109 +:1002A000D5C294E5256002D291207C02C295307CB3 +:1002B00002C293207C02C290307C02C29261D5C2FD +:1002C00094207C02C295307C02C2937401D5E0FD7B +:1002D000E5256002D291207C02C290307C02C2925D +:1002E00061D5C294E5256002D291207C02C2933090 +:1002F0007C02C295207C02C290307C02C29261D501 +:10030000C294207C02C293307C02C2957401D5E075 +:10031000FDE5256002D291207C02C290307C02C2B1 +:100320009261D5207C02C293307C02C295E52560A3 +:100330000A207C02D290307C02D292C294207C02AD +:10034000C292307C02C29061D5207C02C293307C84 +:1003500002C295C2947401D5E0FDE525600A207CB7 +:1003600002D290307C02D292207C02C292307C0277 +:10037000C29061D5207C02C293307C02C295E525F3 +:10038000600A207C02D290307C02D292207C02C291 +:1003900095307C02C293207C02C292307C02C290D3 +:1003A00061D5207C02C293307C02C295207C02C2BF +:1003B00095307C02C2937401D5E0FDE525600A20EA +:1003C0007C02D290307C02D292207C02C292307C9D +:1003D00002C29061D5E525F4F58A758B00755B0046 +:1003E000D262D0E0D0D0D2AF32C2AFC0D0C0E0D263 +:1003F000D3C2CEE5286002813578007900E58030EF +:100400007D01F430E70278FF53DACF207D0343DA31 +:1004100020307D0343DA10C2D8C271E580307D01FF +:10042000F430E70279FFC3E89970CE306103752894 +:10043000288853D270E52960041529813D20700277 +:10044000819BE553F8C270C3E8955A5003E55AF80A +:10045000E52D540670458822306B12C3E52295576E +:100460004005855722816DE522240BF5227883B65D +:0E0470000129C3E5229524401278A196400D83 +:10047E00E52426F52450097524FF02048E852224D6 +:10048E00852425C3E5249557400385572520CF099C +:10049E00D0E0D0D0C2D3D2AF32C2CF7801E528603F +:1004AE00021528C3E5539401400575560081C4E535 +:1004BE00560460020556E558C3240A50057558FFC8 +:1004CE0081D2F558D0E0D0D0C2D3D2AF32C2AF5322 +:1004DE00917FC260D2AF32C2AFC0D0C0E0C0F0D206 +:1004EE00D3A8FBA9FCC2D8307102A14853DACF20A1 +:1004FE007D0343DA10307D0343DA20D271E580307C +:10050E007D01F420E702A11C88268927C18453DAD5 +:10051E00CF207D0343DA20307D0343DA10C2D8C2E8 +:10052E00717401552F7002C1787800E580307D011D +:10053E00F430E702C1788853C17853DACF207D03B7 +:10054E0043DA20307D0343DA10C271206102A1B874 +:10055E0053DACF207D0343DA10307D0343DA20C215 +:10056E00D8D271884E894FC3E8954CF8E9954DF96C +:10057E007AFAC3E89498E994085002C178C3E895D2 +:10058E0050FCE99551FD30E708ECF42401FCEDF444 +:10059E00FD7552007008C3EC9A50037552018850D5 +:1005AE008951A84EA94F884C894DE4FBC3E8952686 +:1005BE00F8E99527F9E9C313F9E813F8E9C313F934 +:1005CE00E813F8C3E894FAE994005007E530B40153 +:1005DE0002C149E9C313FDE813FC206118C3EC9472 +:1005EE001CED94024003020678ED7009C3EC94C82A +:1005FE0050030206847400207E037897E624FAFEE8 +:10060E00E43400FFC3EC9EFCED9FFD5006780079AC +:10061E0000C161C3EC94FFED9400400678FF7900B1 +:10062E00C161EC8567F0A4C5F0A2F733F8790040FC +:10063E000302066C78FF790002066CC3E894F0E9B9 +:10064E0094005026C3E89414E99400401DE4D2E0CF +:10065E00FBC16CC3E894FFE99400400278FF885315 +:10066E00D2707401F4552F4BF52F7528287401554F +:10067E002F70037528407529067401552F70037568 +:10068E00290AD0F0D0E0D0D0C2D3D2AF327901C196 +:10069E00B37903C1B3790AC1B3791EC1B37964C109 +:1006AE00B379C8C1B37817E4D5E0FDD8FAD9F622EC +:1006BE007C05D1AFDCFC22C2AF1208E51208EB12AA +:1006CE0008F1D1A31208E51208EB1208F1D2AF22FD +:1006DE00C2AF1208F11208EB1208E5D1A31208F10D +:1006EE001208EB1208E5D1A3D2AF22AE69AF6AC2EF +:1006FE00AF30662EC3EE940540196001FE1208F16C +:10070E001208F11208F11208F11208F1D1A7BE0574 +:10071E0002E1691208E51208E51208E5D1ABDEF335 +:10072E00E169E4FEC3EF940A40070E0E600DFFE18F +:10073E0049C3EF9405401B0E6001FF1208EB12082F +:10074E00EB1208EBD1A7DEF3BF0A02E169BF050287 +:10075E00E169D1AB1208F7D1ABDFF7D2AF227F0040 +:10076E00756C007B08E580307D01F420E703308F47 +:10077E00F4758A00758C00D28CE580307D01F430E2 +:10078E00E703308FF4C28C858A53C3E5539414402B +:10079E0020C3E553944E5005EF23FFE1C1C3E5534B +:1007AE009466400DC3E55394CC5006EF2304FFE14D +:1007BE00C1D27F308F04D27FE1CCDBA98F6C227C3B +:1007CE003079D0756C00F16CA76C09DCF92279D008 +:1007DE007C30BC2D057883020815BC2C057884026C +:1007EE000815BC2B057885020815BC2805788802EB +:1007FE000815BC27057889020815BC1C05789402DB +:10080E000815BC1B0B7895876CA66C121807C2AF27 +:10081E0009DCBF22C2AFD28C7B08E56CD28730E7F1 +:10082E0005758A670137758ACD758CFFC28D308D3F +:10083E00FDC287758ACD758CFFC28D308DFD23DB91 +:10084E00DB22C28775A4807C307880866C081122EA +:10085E00DCF975A47FD28722756D007C3079D0E7E4 +:0F086E00C3356DF56D09DCF7227F007C2F79D043 +:10087D00E7C33FFF09DCF9F404F722756C0012069B +:10088D00A3C27F758B00758D00D28EC28F12076C3F +:10089D00207FE8E56CB4050812069F115002088808 +:1008AD00B409D8756C00758B00758D00D28EC28F12 +:1008BD001207CD1166E56D70C279D0E7B466BC1232 +:1008CD00069BC28775A480756C88112275A47FD292 +:1008DD00871207DC020888227A127B6401FD7A0EEA +:1008ED007B7801FD7A0C7BA001FD7A097BB401FDBB +:1008FD00AC257525017902B27CE4C294D5E0FDE505 +:10090D00256002D291D5E0FDC291D5E0FDD294D5FE +:10091D00E0FDE525600A207C02D292307C02D29067 +:10092D00E568D5E0FD207C02C292307C02C2907455 +:10093D0064D5E0FDD9C1EAF8D5E0FDD8FBDBB1C245 +:10094D00948C2522C37C007D0075F00005F0EA3300 +:10095D00FAEB33FB50F6EB13FBEA13FAC3E9FFE8AE +:10096D00FEE89AF8E99BF95004EFF9EEF8B3EC3391 +:10097D00FCED33FDD5F0DFEDF9ECF822E889F08AD6 +:10098D0020D2D4F8A9F07B0030F70B7BFFF42401C3 +:10099D00F8E9F43400F9E88520F0A4ADF0F8E98524 +:1009AD0020F0A4AFF0FEED2EF974003FFA7C04C3E5 +:1009BD00EA13FAE913F9E813F8DCF48BF030F70ACF +:1009CD00E8F42401F8E9F43400F9E889F0C2D4F828 +:1009DD00A9F0227883B60103020A40C3E5539401BE +:1009ED004003020A05852224E4F53CF53DF53EF56C +:1009FD003FF540F545020A407883E6FC754501E573 +:100A0D0022F523783879C7AA38AB39C3EB13FBEA43 +:100A1D0013FAEC141414146014C3EB13FBEA13FA59 +:100A2D00EC1414146007C3EB13FBEA13FA3151886D +:100A3D003C893D22E5456034C3E53C9523F8E53D11 +:100A4D009400F9500CC3E89480E994FF4016020A13 +:100A5D0075C3E8947FE994005003020A75787F7995 +:100A6D0000020A75788079FF8841894222E5456048 +:100A7D0058E541253EF8E542353FF9854220E43001 +:100A8D000701F43540FA30E709C3EA94F040150246 +:100A9D000AB7C3EA940F5003020AB778FF79FF7AB9 +:100AAD000F020AB7780079007AF0C3E52495575004 +:100ABD0006E524600941D0E54220E70D41D0E5422D +:100ACD0030E706883E893F8A4022E5457003020BD8 +:100ADD003A789FE6FAC3E54133F8E54233F93189B7 +:100AED00E930E70BC3E89480E994FF40136111C32B +:100AFD00E8947FE9940050026111787F79006111CB +:100B0D00788079FFE820E715C3E52398F84009C3FD +:100B1D00E894014003020B387801020B38E8F42405 +:100B2D00012523F84003020B3878FF884322E54561 +:100B3D007003020B9C78A0E6FAA83FA9403189E921 +:100B4D0030E70CC3E89401E994FF4016020B73C320 +:100B5D00E894FFE994005003020B7378FF790002CB +:100B6D000B73780179FFE920E715C3E54398F84049 +:100B7D0009C3E894014003020B9A7800020B9AE82E +:100B8D00F424012543F84003020B9A78FF882422B0 +:100B9D007564007884E6F520207C02C290307C02DA +:100BAD00C292E5256002D291207C03759F01307CB5 +:100BBD0003759F21753A0675E890E5E820ECD1A8FC +:100BCD00BDA9BE121139756150756200C374001351 +:100BDD00FD745013FC74502C2403FC74003DFDEC8B +:100BED00FAEDFB0564C3E89AE99B4014E5612450D6 +:100BFD00F561E5623400F562EA2CFAEB3DFB80E32A +:100C0D00AE61AF62C3E56213F9E56113F8C3E91391 +:100C1D00F9E813F87A02C3E913F9E813F8DAF7AA39 +:100C2D0020BA0409756100756200020C4B1AEA6066 +:100C3D0009C3EE28FEEF39FFDAF78E618F62227558 +:100C4D00E890227884E6FFE5E820ECF7A8BDA9BE80 +:100C5D000563C3E56394084052756300E97007E5C9 +:0E0C6D0066601B020C7FC3E895666010E566AA +:100C7B005006600C14020C8B0460F9020C8BE566B9 +:100C8B00F566C3945CF840217557C0C3E89405F82A +:100C9B004017755780C3E89405F8400D755740C34E +:100CAB00E89405F8400375571075BB0622EFC39403 +:100CBB0004603BC3E894FFE994035032C3E89561A9 +:100CCB00E9956250297885E6C39401600BE557944A +:100CDB0005500BD20702170BE5579450401AE565E8 +:100CEB0060041565A1037565051557020D03756540 +:100CFB0005E557F460020557A857C3E52498500241 +:100D0B00A8248825C3E5259558400B855825E5581B +:100D1B00F46003855857C3E563B4070375BB102212 +:100D2B003069027832306A027878E52D54066021FA +:100D3B00E879A287F0A4C5F0A2F733F8C3E895577A +:100D4B004002A857882288248825306904C3E8F517 +:100D5B00592275380075390822A846A947759100A4 +:100D6B00C3E498F594E499F595759104D26075C830 +:100D7B0020A8CCA9CD75C824AA36AB3788368937BD +:100D8B00C3E89AF8E99BF9AA38AB39C3EB13FDEA30 +:100D9B0013FCC3ED13FDEC13FCC3EA9CFAEB9DFBB8 +:100DAB00EA28FAEB39FB8A388B394001227538FF78 +:100DBB007539FF22306002A1BF759100C3E49548DD +:100DCB00F594E49549F595759104D260227894E6F3 +:100DDB00FF7E103063027F05306B047F037E00A91A +:100DEB0039A8387A04C3E913F9E813F8DAF7C3E83A +:100DFB009EF8E99400F94009C3E89402E994005085 +:100E0B00047802E4F9E9FBE8FAC3E913FDE813FC03 +:100E1B00C3EF9403602EEF20E00DE82CF8E93DF9C9 +:100E2B00ECFAEDFB020E3CE828F8E939F97A02E41A +:100E3B00FBC3EF9403400D8A4A8B4B884689478C42 +:100E4B00488D4922884A894B8A468B478C488D4965 +:100E5B0022306002C15C759100C3E49538F594E4CF +:100E6B009539F595759104D26022753B007520007C +:100E7B00020E84753B00752040D2AF053B2060010C +:100E8B0022759D00E539C313C313F8086030307227 +:100E9B0006C313C313F808C3E8940A4002780A3058 +:100EAB007508C3E8940440027804C3E539940840FC +:100EBB000D759D02C3E53994104003759D032060A9 +:100ECB0003D2AF22790F2075027905D2AF0000C291 +:100EDB00AF20620A791420750279073077E0306B06 +:100EEB00027978C3E58B99206B0240F740D0E59BE4 +:100EFB00F4F45440B52002C184D8C3D2AF22C263EC +:100F0B00789DE6146007E53B147002D263306B0BDF +:100F1B000535206010753500020F302060071581F4 +:100F2B00158102170B22759100C3E4954AF594E4E1 +:100F3B00954BF595759104D26022AE2530634F78B1 +:100F4B00A4E6FFBF010BD264752500C292C291C209 +:100F5B0090B1C4306403752500306002E15EBF02BE +:100F6B000BD264752500C292C291C29078A3B601D0 +:100F7B000DB1C4306403752500306002E17EBF0300 +:100F8B000BD264752500C292C291C290F1313064CC +:100F9B0003752500306002E199306304C2648E252D +:100FAB0022C2AFC294207203020FCB90034930765A +:100FBB000F207C02C293307C02C2957401D5E0FDF8 +:100FCB00207C02D295307C02D293759F11753A0228 +:100FDB00D2AF22C2AF207203021000900300307612 +:100FEB0017C294207C02C293307C02C2957401D547 +:100FFB00E0FD0210039001E3207C02C290307C02E2 +:10100B00C292306206E5256002D291207C03759F67 +:10101B0001307C03759F21753A03D2AF22C2AF20FA +:10102B007C02C295307C02C293207203021047905F +:10103B0002BF307607C2947401D5E0FD207C02D24A +:10104B0093307C02D295207C03759F21307C0375F5 +:10105B009F01753A04D2AF22C2AF207203021085F2 +:0E106B0090027E307617207C02C295307C0207 +:10107900C293C2947401D5E0FD0210889001D1C2D7 +:101089009130620EE525600A207C02D292307C0202 +:10109900D290759F11753A05D2AF22C2AF207C025A +:1010A900C293307C02C2952072030210CB900235A4 +:1010B90030760F207C02C295307C02C2937401D530 +:1010C900E0FDD294207C03759F01307C03759F213C +:1010D900753A06D2AF22C2AF2072030211099003FA +:1010E900A230761F207C02C295307C02C293207CFC +:1010F90002C293307C02C2957401D5E0FD02110C45 +:101109009001F5207C02C292307C02C29030620EBE +:10111900E525600A207C02D290307C02D292207CA4 +:1011290003759F21307C03759F01753A01D2AF2267 +:101139009001CFC295C294C293C292C291C2902229 +:10114900788076667881760978827609788376015F +:101159007886760378847602788576017888760AA7 +:10116900789176017892760578947603789C760D55 +:101179007895760178897601789D7602788A760164 +:10118900788B760178877600788E7601788F76006D +:10119900789076B478977625789876D0789976503D +:1011A900789A7664789B7602789E7600227895E61E +:1011B900FFC272C274C273C276D277755F09756055 +:1011C90001752BFAC3BF0103021227D272D276C26C +:1011D90077755F05756001752B3CC3BF0203021269 +:1011E90027D274755F05756002752B1EC3BF030393 +:1011F900021227755F05756003752B19C3BF0403B8 +:10120900021227D273755F05756004752B14C3BF6D +:101219000503021227755F05756005752B0A788924 +:10122900E6FFC27C788AE630E102D27CC27D788B07 +:10123900E630E102D27DC3EF94016008758E01D2D8 +:1012490075021252758E00C275227881E6149000DB +:101259008093789FF67882E6149000809378A0F6C0 +:10126900313922789CE61490008D9378A1F63139B2 +:10127900227888E61490009A9378A2F63139227878 +:101289009DE6149000A79378A3F6789DE614900044 +:10129900AC9378A4F6313922227897E6FA7898E661 +:1012A900FB307E047A007BFFC3EB9AFCC394825027 +:1012B900027C827567000567EC8567F0A4C3E5F0D9 +:1012C900948040F222C2D353D9BF7581C043FF80B5 +:1012D9007903D5E0FDD9FB75EF0243B203E5B324E9 +:1012E900044002F5B37580FF75A40075F19075D4BB +:1012F9007F75908075A5BF75F2BF75D50075A6017C +:1013090075E2413139E4F8F6D8FD31491217533104 +:10131900B65153516C517A518851A151A27899868D +:1013290068313975885075890275C82475910475B5 +:10133900D8401206BE1206BE75A82275B80275E617 +:101349009075F610759B80759D0375D10E75BC5807 +:1013590075BB0675BA1175E88012069BD2AF120BE0 +:101369009D43DA0153DACF207D0343DA20307D0330 +:1013790043DA10C2D8C2711206AF753001D2617A50 +:1013890005E552702812069FE553C394E64005759A +:1013990033006188E553C3941E5005753300618895 +:1013A9000533E533C3940550047A05618A12069F13 +:1013B900E553C3940240C8E52F5401855554F555AA +:1013C900B554BCDABCC26153DACF207D0343DA20BD +:1013D900307D0343DA10C2D8C2711206AB12069FE0 +:1013E90078027401552F70027800C3E5539840EDD7 +:1013F9001206AF75440012069F788EE6C394015019 +:10140900030214DFE530C39401500302153C7897B9 +:10141900E6F56E7401552F601AC2AF1208EB120877 +:10142900F11208E5758911758E0275F18075D4FF81 +:101439001208887F05D27E51A21206ABC2AFC27EC6 +:1014490051A2C3E55394DCD2AF4004DFE8816DC3F8 +:10145900E553956E500281E9C2AF1208E51206AB59 +:0F146900D2AF813CC3E55394057898F61208770B +:10147800121807C2AF1208E51208E51206A71208EB +:10148800F71208F7D2AF1206BE1206BEC3E5539490 +:10149800D75009C3E553943C50F281A7121C9D7F95 +:1014A80005D27E51A21206ABC2AFC27E51A2C3E5DD +:1014B80053943CD2AF50E8DFE8E55324057897F61B +:1014C80012087712180712175331B65153516C513D +:1014D8007A518851A151A2C3E553954440038553DD +:1014E800441206ABC3E5539401400280F4C2AF1224 +:1014F80008E51208E51208E51206BEAF641208E511 +:101508001208E51206A7DFF51206AF1206AF120899 +:10151800E51206A71206A71208EB1206A71206A7DD +:101528001208F11206A71206A7D2AF1206AB120BC9 +:101538009D7530007F32C20712069FE52870026150 +:1015480086C3E553940840ECDFEE2007EB1206ABA8 +:10155800E5287003021386D2A93139E4F522F52370 +:10156800F524F5257557FF7887865AF53CF53DF53E +:101578003EF53FF540F563F545F52CF52DF556F5A7 +:101588002BF564F565755300120D5D75630875BB21 +:101598001012069B120C4CE5E820ECFBA8BDA9BE76 +:1015A800E97001F88866120C5075630875BB1078ED +:1015B80089E6FE760131B67889EEF6D269C2AF12B5 +:1015C8000D2B852257852258D2AFC2697525007523 +:1015D8005D00755E01D268D26B75350011A411DF0C +:1015E800120D64120D5D0215FB31B611DF75630033 +:1015F80075BB06120E7E120F09120F311209E01286 +:101608000F45120FAC120D64120DBF120DD8120E39 +:101618005C120E75120F09120F31120A41120F4592 +:10162800120FDE120D64120DBF120DD8120E5C12CD +:101638000E7E120F09120F31120A7A120F45112865 +:10164800120D64120DBF120DD8120E5C120E751217 +:101658000F09120F31120AD7120F451163120D64C8 +:10166800120DBF120DD8120E5C120E7E120F091247 +:101678000F31120B3B120F4511A4120D64120DBF4E +:10168800120DD8120E5C120E75120C4C120F0912A4 +:101698000F31120C50120F4511DF120D64120DBFDD +:1016A800120DD8120E5C306B2A855957855958751A +:1016B8005D00755E01C3E5359464400AC26BD26C67 +:1016C8007534140216DBC3E553940140030215FB7D +:1016D80002170B306C19E534147005C26C0215F151 +:1016E800F534C3E553940140030215FB02170BC3FD +:1016F800E556952B500DE5286009C3E53994F0505F +:1017080002A1FB31397889E6FE760131B67889EE97 +:10171800F6E4F522F523F524F525F55AC2681206F4 +:101728009B31391206A3C2A9207202E14B2074042E +:10173800D291E14B207306D292D291E14BD292D250 +:1017480091D290E52870026186A140901A0F782006 +:10175800121C00E520B4550CA3121C00E520B4AA05 +:1017680003021777314912087712180702180690F2 +:101778001A037880121C00A308121C00A308121C6C +:1017880000A308121C00A308121C00A308121C00C6 +:10179800A308121C00A308A308121C00A308121C0B +:1017A80000A308121C00A308121C00A308A308A386 +:1017B80008121C00A308A308121C00A308121C008E +:1017C800A308121C00A308A308121C00A308121CDB +:1017D80000A308A308121C00A308121C00A30812E7 +:1017E8001C00A308121C00A308121C00A308121C4A +:1017F80000A308121C00A308121C00901A2222C27F +:10180800AF121C19901A00740A121C05A374021254 +:101818001C05A37410121C05901A037880121C046E +:10182800A308121C04A308121C04A308121C04A376 +:1018380008121C04A308121C04A308121C04A30801 +:10184800A308121C04A308121C04A308121C04A356 +:1018580008121C04A308A308A308121C04A308A3C5 +:0F18680008121C04A308121C04A308121C04A3DA +:1018770008A308121C04A308121C04A308A3081237 +:101887001C04A308121C04A308121C04A308121C9E +:1018970004A308121C04A308121C04A308121C04A6 +:0E18A700A308121C04121C30901A22D2AF2289 +:101A00000A021066090901020103FF0A01010155DA +:101A1000AA01FFFF0105FF0301FF25D05064020D5D +:031A20000200FFC2 +:101A400023585031384123202020202020202020DE +:101A500023424C48454C4923463333302320202031 +:101A60002020202020202020202020202020202076 +:101C0000E493F622E6438F01538FFD75EF0275B71B +:101C1000A575B7F1F0538FFE22438F02438F0175F4 +:101C2000EF0275B7A575B7F1901A0FF0538FFC222C +:101C3000901A0F74559105901A1074AA9105227A82 +:101C40003079D07820901A409100E520F709A3DA86 +:101C5000F7227A3079D0901A40E7910509A3DAF992 +:101C600022AB69A86ABB01057995021C9ABB0205E3 +:101C70007994021C9ABB03057988021C9ABB04055F +:101C80007983021C9ABB05057989021C9ABB06055B +:101C90007984021C9A7985021C9AE8F7221206C5FB +:101CA000D2667C0A1206AFC3E5539401400BC3E52C +:101CB0005394FF40EDDCED81DE7C0A1206AFC3E5F4 +:101CC0005394015005DCF4A19EC3E55394FF40E911 +:101CD0001211491208771218071206DE81A27569DF +:101CE000011206F97C0AAD531206AFC3ED9553708D +:101CF000F5C3E55394014053C3E55394FF5002816B +:101D0000E6306621DCE00569E569940840D37C0A89 +:101D10001206AFC3E55394014076C3E55394FF40E8 +:101D2000EFDCED81DED2669161120877121807129E +:101D300006DE7C0A1206AFC3E55394014052C3E5A8 +:101D40005394FF40EFDCED7C01A1017C0A1206AF49 +:101D5000C3E55394FF508FC3E553940150EFDCED7E +:101D6000C266756A011206F97C0A1206AFC3E55312 +:101D700094FF508DC3E553940150EFDCED056AE507 +:101D800069149000B193F808C3E56A9850D4A1652E +:0F1D90007C0A1206AFC3E553940150F6DCF4222F +:00000001FF