From f69f42f0f89518d928affde4c6f157b864b4e94c Mon Sep 17 00:00:00 2001 From: Nick-HZ Date: Thu, 16 Oct 2014 11:19:38 +0800 Subject: [PATCH] V1.0 --- SiLabs/EMAX_BLHeli.a51 | 6848 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6848 insertions(+) create mode 100644 SiLabs/EMAX_BLHeli.a51 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