diff --git a/Atmel/BLHeli.asm b/Atmel/BLHeli.asm index 38176441..b5a5fa2d 100644 --- a/Atmel/BLHeli.asm +++ b/Atmel/BLHeli.asm @@ -1,6617 +1,6635 @@ -;**** **** **** **** **** -; -; BLHeli program for controlling brushless motors in helicopters and multirotors -; -; 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 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, 8kHz or 12kHz PWM (e.g. taken from the "resistor tap" on mCPx) -; And the input signal can be PPM (1-2ms) or OneShot125 (125-250us) at rates up to several hundred Hz. -; The code autodetects the various input modes/frequencies -; The code 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: -; - Rev0.0: Initial revision -; - Rev1.0: Governor functionality added -; - Rev1.1: Increased tail gain to 1.0625. Implemented for tail only -; Decreased governor proportional and integral gain by 4 -; Fixed bug that caused tail power not always to be max -; - Rev1.2: Governor integral gain should be higher in order to achieve full PWM range -; Integral gain can be higher, and is increased by 2x. An integral of +-128 can now be added to requested PWM -; - Rev1.3: Governor integral extended to 24bit -; Governor proportional gain increased by 2x -; Added slow spoolup/down for governor -; Set pwm to 100% (do not turn off nFET) for high values of current pwm -; Added support for PPM input (1us to 2us pulse) -; Removed USE_COMP_STORED as it was never used -; - Rev2.0 Added measurement of pwm frequency and support for 1kHz, 2kHz, 4kHz and 8kHz -; Optimized pwm on and off routines -; Improved mosfet switching in beep routines, to reduce current draw -; Added support for ICP1 interrupt pin input -; Added ADC measurement of supply voltage, with limiting of main motor power for low voltage -; Miscellaneous other changes -; - Rev2.1 Rewritten INT0 routine to be similar to ICP -; Reduced validation threshold (RCP_VALIDATE) -; Removed requirement for RCP to go to zero again in tail arming sequence -; Removed PPM support -; - Rev2.2 Added support for HC 5A 1S ESC with Atmega48V MPU -; Increased governor proportional gain by 2x -; - Rev3.0 Added functionality for programming from TX -; Added low voltage limit scaling for 2S and 3S -; - Rev11.2 Copied over from the SiLabs version and adapted to Atmel -; Now requiring a 16MHz capable MCU for fullspec performance -; - Rev12.0 Added programmable main spoolup time -; Added programmable temperature protection enable -; Bidirectional mode stop/start improved. Motor is now stopped before starting -; Power is limited for very low rpms (when BEMF is low), in order to avoid sync loss -; Damped light mode is made more smooth and quiet, particularly at low and high rpms -; Comparator signal qualification scheme is changed -; Demag compensation scheme is significantly changed -; Increased jitter tolerance for PPM frequency measurement -; Fully damped mode removed, and damped light only supported on damped capable ESCs -; Default tail mode changed to damped light -; Miscellaneous other changes -; - Rev12.1 Fixed bug in tail code -; Improved startup for Atmel -; Added support for multiple high BEC voltages -; Added support for RPM output -; - Rev12.2 Improved running smoothness, particularly for damped light -; Avoiding lockup at full throttle when input signal is noisy -; Avoiding detection of 1-wire programming signal as valid throttle signal -; - Rev13.0 Removed throttle change rate and damping force parameters -; Temperature protection default set to off -; Added support for OneShot125 -; Improved commutation timing accuracy -; - Rev13.1 Removed startup ramp for MULTI -; Improved startup for some odd ESCs -; - Rev13.2 Still tweaking startup to make it more reliable and faster for all ESC/motor combos -; Increased deadband for bidirectional operation -; Relaxed signal detection criteria -; Miscellaneous other changes -; - Rev14.0 Improved running at high RPMs and increased max RPM limit -; Improved reliability of 3D (bidirectional) mode and startup -; Avoid being locked in bootloader (implemented in Suite 13202) -; Smoother running and greatly reduced step to full power in damped light mode -; Removed low voltage limiting for MULTI -; Added pwm dither parameter -; Added setting for enable/disable of low RPM power protection -; Added setting for enable/disable of PWM input -; Better AFW and damping for some ESCs (that have a slow high side driver) -; Miscellaneous other changes -; - Rev14.1 Fixed max throttle calibration bug (for non-oneshot) -; Fixed some closed loop mode bugs -; Relaxed signal jitter requirement for looptimes below 1000 -; Added skipping of damping fet switching near max power, for improved high end throttle linearity, using the concept of SimonK -; Improved sync hold at high rpms -; - Rev14.2 Improved quality of comparator reading, giving better bemf detection (for improved startup amongst others) -; Removed mechanism where some ESCs could reset upon starting motor (due to ADC being read) -; Added stalled motor shutoff after about 10 seconds (for tail and multi code with PPM input) -; Greatly increased maximum rpm limit, and added rpm limiting at 250k erpm -; Improved bidirectional operation -; - Rev14.3 Moved reset vector to be just before the settings segment, in order to better recover from partially failed flashing operation -; Shortened stall detect time to about 5sec, and prevented going into tx programming after a stall -; Optimizations of software timing and running reliability -; - Rev14.4 Improved startup, particularly for larger motors -; Improved running at very high rpms -; Made damped light default for MULTI on ESCs that support it -; Miscellaneous other changes -; - Rev14.5 Longer between beacon beeps (to reduce motor heating), and now again beeping on two motor phases -; Implemented programmable brake on zero throttle -; Slightly modified throttle calibration -; Improved startup, particularly for small motors -; Improved smoothness -; - Rev14.6 Fixed bug that caused tail motor not to stop -; Fixed bug that caused brake not to work for low side pwm ESCs -; Fixed bug where noisy input signal could cause loss of sync -; Made low rpm power limiting programmable through the startup power parameter -; - Rev14.7 Beeps can be turned off by programming beep strength to 1 -; Throttle cal difference is checked to be above required minimum before storing. Throttle cal max is not stored until successful min throttle cal -; In order to have a good code for fixed wing planes, that has low voltage limiting, a main code spoolup time setting of 0 is made fast -; Some small changes for improved sync hold -; - Rev14.8 No change, just created to stay in sync with SiLabs code -; - Rev14.9 Improved bidirectional mode for high input signal rates -; -; -;**** **** **** **** **** -; 8K Bytes of In-System Self-Programmable Flash -; 1K Bytes Internal SRAM -; 512 Bytes Internal EEPROM -; 16MHz clock -; -;**** **** **** **** **** -; Timer 0 (500ns counts) always counts up and is used for -; - RC pulse timeout and skip counts -; Timer 1 (500ns counts) always counts up and is used for -; - RC pulse measurement (via external interrupt 0 or input capture pin) -; - Commutation timing (via output compare register A interrupt) -; Timer 2 (500ns counts) always counts up and is used for -; - PWM generation -; -;**** **** **** **** **** -; Interrupt handling -; The Atmega8 disables all interrupts when entering an interrupt routine, -; The code reenables interrupts in some interrupt routines, in order to nest pwm 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: -; There is a startup phase and an initial run phase, before normal bemf commutation run begins. -; -;**** **** **** **** **** -; Select the ESC and mode to use (or unselect all for use with external batch compile file); -;#define BLUESERIES_12A_MAIN -;#define BLUESERIES_12A_TAIL -;#define BLUESERIES_12A_MULTI -;#define BLUESERIES_20A_MAIN -;#define BLUESERIES_20A_TAIL -;#define BLUESERIES_20A_MULTI -;#define BLUESERIES_30A_MAIN -;#define BLUESERIES_30A_TAIL -;#define BLUESERIES_30A_MULTI -;#define BLUESERIES_40A_MAIN -;#define BLUESERIES_40A_TAIL -;#define BLUESERIES_40A_MULTI -;#define BLUESERIES_60A_MAIN -;#define BLUESERIES_60A_TAIL -;#define BLUESERIES_60A_MULTI -;#define BLUESERIES_70A_MAIN -;#define BLUESERIES_70A_TAIL -;#define BLUESERIES_70A_MULTI -;#define HK_UBEC_6A_MAIN -;#define HK_UBEC_6A_TAIL -;#define HK_UBEC_6A_MULTI -;#define HK_UBEC_10A_MAIN -;#define HK_UBEC_10A_TAIL -;#define HK_UBEC_10A_MULTI -;#define HK_UBEC_20A_MAIN -;#define HK_UBEC_20A_TAIL -;#define HK_UBEC_20A_MULTI -;#define HK_UBEC_30A_MAIN -;#define HK_UBEC_30A_TAIL -;#define HK_UBEC_30A_MULTI -;#define HK_UBEC_40A_MAIN -;#define HK_UBEC_40A_TAIL -;#define HK_UBEC_40A_MULTI -;#define SUPERSIMPLE_18A_MAIN -;#define SUPERSIMPLE_18A_TAIL -;#define SUPERSIMPLE_18A_MULTI -;#define SUPERSIMPLE_20A_MAIN -;#define SUPERSIMPLE_20A_TAIL -;#define SUPERSIMPLE_20A_MULTI -;#define SUPERSIMPLE_30A_MAIN -;#define SUPERSIMPLE_30A_TAIL -;#define SUPERSIMPLE_30A_MULTI -;#define SUPERSIMPLE_40A_MAIN -;#define SUPERSIMPLE_40A_TAIL -;#define SUPERSIMPLE_40A_MULTI -;#define MULTISTAR_10Av2_MAIN -;#define MULTISTAR_10Av2_TAIL -;#define MULTISTAR_10Av2_MULTI -;#define MULTISTAR_15A_MAIN ; Inverted input -;#define MULTISTAR_15A_TAIL -;#define MULTISTAR_15A_MULTI -;#define MULTISTAR_20A_MAIN ; Inverted input -;#define MULTISTAR_20A_TAIL -;#define MULTISTAR_20A_MULTI -;#define MULTISTAR_20A_NFET_MAIN ; Inverted input -;#define MULTISTAR_20A_NFET_TAIL -;#define MULTISTAR_20A_NFET_MULTI -;#define MULTISTAR_20Av2_MAIN -;#define MULTISTAR_20Av2_TAIL -;#define MULTISTAR_20Av2_MULTI -;#define MULTISTAR_30A_MAIN ; Inverted input -;#define MULTISTAR_30A_TAIL -;#define MULTISTAR_30A_MULTI -;#define MULTISTAR_40Av2_MAIN -;#define MULTISTAR_40Av2_TAIL -;#define MULTISTAR_40Av2_MULTI -;#define MULTISTAR_45A_MAIN ; Inverted input -;#define MULTISTAR_45A_TAIL -;#define MULTISTAR_45A_MULTI -;#define MYSTERY_12A_MAIN -;#define MYSTERY_12A_TAIL -;#define MYSTERY_12A_MULTI -;#define MYSTERY_30A_MAIN -;#define MYSTERY_30A_TAIL -;#define MYSTERY_30A_MULTI -;#define MYSTERY_40A_MAIN -;#define MYSTERY_40A_TAIL -;#define MYSTERY_40A_MULTI -;#define SUNRISE_HIMULTI_20A_MAIN ; Inverted input -;#define SUNRISE_HIMULTI_20A_TAIL -;#define SUNRISE_HIMULTI_20A_MULTI -;#define SUNRISE_HIMULTI_30A_MAIN ; Inverted input -;#define SUNRISE_HIMULTI_30A_TAIL -;#define SUNRISE_HIMULTI_30A_MULTI -;#define SUNRISE_HIMULTI_40A_MAIN ; Inverted input -;#define SUNRISE_HIMULTI_40A_TAIL -;#define SUNRISE_HIMULTI_40A_MULTI -;#define RCTIMER_40A_MAIN -;#define RCTIMER_40A_TAIL -;#define RCTIMER_40A_MULTI -;#define RCTIMER_NFS_30A_MAIN ; ICP1 as input -;#define RCTIMER_NFS_30A_TAIL -;#define RCTIMER_NFS_30A_MULTI -;#define YEP_7A_MAIN -;#define YEP_7A_TAIL -;#define YEP_7A_MULTI -;#define AFRO_12A_MAIN ; ICP1 as input -;#define AFRO_12A_TAIL -;#define AFRO_12A_MULTI -;#define AFRO_20A_MAIN ; ICP1 as input -;#define AFRO_20A_TAIL -;#define AFRO_20A_MULTI -;#define AFRO_20A_HV_MAIN ; ICP1 as input -;#define AFRO_20A_HV_TAIL -;#define AFRO_20A_HV_MULTI -;#define AFRO_30A_MAIN ; ICP1 as input -;#define AFRO_30A_TAIL -;#define AFRO_30A_MULTI -;#define SUNRISE_BLHELI_SLIM_20A_MAIN -;#define SUNRISE_BLHELI_SLIM_20A_TAIL -;#define SUNRISE_BLHELI_SLIM_20A_MULTI -;#define SUNRISE_BLHELI_SLIM_30A_MAIN -;#define SUNRISE_BLHELI_SLIM_30A_TAIL -;#define SUNRISE_BLHELI_SLIM_30A_MULTI -;#define DYS_SN20A_MAIN ; ICP1 as input -;#define DYS_SN20A_TAIL -;#define DYS_SN20A_MULTI -;#define TBS_CUBE_20A_MAIN ; ICP1 as input -;#define TBS_CUBE_20A_TAIL -;#define TBS_CUBE_20A_MULTI -;#define ZTW_SPIDER_LITE_18Av2_MAIN -;#define ZTW_SPIDER_LITE_18Av2_TAIL -;#define ZTW_SPIDER_LITE_18Av2_MULTI -;#define HTIRC_DRAGONFLY_6A_MAIN -;#define HTIRC_DRAGONFLY_6A_TAIL -;#define HTIRC_DRAGONFLY_6A_MULTI -;#define HTIRC_DRAGONFLY_12A_MAIN -;#define HTIRC_DRAGONFLY_12A_TAIL -;#define HTIRC_DRAGONFLY_12A_MULTI -;#define HTIRC_DRAGONFLY_20A_MAIN -;#define HTIRC_DRAGONFLY_20A_TAIL -;#define HTIRC_DRAGONFLY_20A_MULTI -;#define HTIRC_DRAGONFLY_30A_MAIN -;#define HTIRC_DRAGONFLY_30A_TAIL -;#define HTIRC_DRAGONFLY_30A_MULTI -;#define HTIRC_DRAGONFLY_40A_MAIN -;#define HTIRC_DRAGONFLY_40A_TAIL -;#define HTIRC_DRAGONFLY_40A_MULTI -;#define TBS_BULLETPROOF_4A_MAIN ; ICP1 as input -;#define TBS_BULLETPROOF_4A_TAIL -;#define TBS_BULLETPROOF_4A_MULTI -;#define TBS_BULLETPROOF_30A_MAIN ; ICP1 as input -;#define TBS_BULLETPROOF_30A_TAIL -;#define TBS_BULLETPROOF_30A_MULTI - - - -;**** **** **** **** **** -; ESC selection statements -#if defined(BLUESERIES_12A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "BlueSeries_12A.inc" ; Select BlueSeries 12A pinout -#endif - -#if defined(BLUESERIES_12A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "BlueSeries_12A.inc" ; Select BlueSeries 12A pinout -#endif - -#if defined(BLUESERIES_12A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "BlueSeries_12A.inc" ; Select BlueSeries 12A pinout -#endif - -#if defined(BLUESERIES_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "BlueSeries_20A.inc" ; Select BlueSeries 20A pinout -#endif - -#if defined(BLUESERIES_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "BlueSeries_20A.inc" ; Select BlueSeries 20A pinout -#endif - -#if defined(BLUESERIES_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "BlueSeries_20A.inc" ; Select BlueSeries 20A pinout -#endif - -#if defined(BLUESERIES_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "BlueSeries_30A.inc" ; Select BlueSeries 30A pinout -#endif - -#if defined(BLUESERIES_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "BlueSeries_30A.inc" ; Select BlueSeries 30A pinout -#endif - -#if defined(BLUESERIES_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "BlueSeries_30A.inc" ; Select BlueSeries 30A pinout -#endif - -#if defined(BLUESERIES_40A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "BlueSeries_40A.inc" ; Select BlueSeries 40A pinout -#endif - -#if defined(BLUESERIES_40A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "BlueSeries_40A.inc" ; Select BlueSeries 40A pinout -#endif - -#if defined(BLUESERIES_40A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "BlueSeries_40A.inc" ; Select BlueSeries 40A pinout -#endif - -#if defined(BLUESERIES_60A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "BlueSeries_60A.inc" ; Select BlueSeries 60A pinout -#endif - -#if defined(BLUESERIES_60A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "BlueSeries_60A.inc" ; Select BlueSeries 60A pinout -#endif - -#if defined(BLUESERIES_60A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "BlueSeries_60A.inc" ; Select BlueSeries 60A pinout -#endif - -#if defined(BLUESERIES_70A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "BlueSeries_70A.inc" ; Select BlueSeries 70A pinout -#endif - -#if defined(BLUESERIES_70A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "BlueSeries_70A.inc" ; Select BlueSeries 70A pinout -#endif - -#if defined(BLUESERIES_70A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "BlueSeries_70A.inc" ; Select BlueSeries 70A pinout -#endif - -#if defined(HK_UBEC_6A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "HK_UBEC_6A.inc" ; Select Hobbyking UBEC 6A pinout -#endif - -#if defined(HK_UBEC_6A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "HK_UBEC_6A.inc" ; Select Hobbyking UBEC 6A pinout -#endif - -#if defined(HK_UBEC_6A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "HK_UBEC_6A.inc" ; Select Hobbyking UBEC 6A pinout -#endif - -#if defined(HK_UBEC_10A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "HK_UBEC_10A.inc" ; Select Hobbyking UBEC 10A pinout -#endif - -#if defined(HK_UBEC_10A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "HK_UBEC_10A.inc" ; Select Hobbyking UBEC 10A pinout -#endif - -#if defined(HK_UBEC_10A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "HK_UBEC_10A.inc" ; Select Hobbyking UBEC 10A pinout -#endif - -#if defined(HK_UBEC_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "HK_UBEC_20A.inc" ; Select Hobbyking UBEC 20A pinout -#endif - -#if defined(HK_UBEC_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "HK_UBEC_20A.inc" ; Select Hobbyking UBEC 20A pinout -#endif - -#if defined(HK_UBEC_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "HK_UBEC_20A.inc" ; Select Hobbyking UBEC 20A pinout -#endif - -#if defined(HK_UBEC_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "HK_UBEC_30A.inc" ; Select Hobbyking UBEC 30A pinout -#endif - -#if defined(HK_UBEC_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "HK_UBEC_30A.inc" ; Select Hobbyking UBEC 30A pinout -#endif - -#if defined(HK_UBEC_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "HK_UBEC_30A.inc" ; Select Hobbyking UBEC 30A pinout -#endif - -#if defined(HK_UBEC_40A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "HK_UBEC_40A.inc" ; Select Hobbyking UBEC 40A pinout -#endif - -#if defined(HK_UBEC_40A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "HK_UBEC_40A.inc" ; Select Hobbyking UBEC 40A pinout -#endif - -#if defined(HK_UBEC_40A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "HK_UBEC_40A.inc" ; Select Hobbyking UBEC 40A pinout -#endif - -#if defined(SUPERSIMPLE_18A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "SuperSimple_18A.inc" ; Select SuperSimple 18A pinout -#endif - -#if defined(SUPERSIMPLE_18A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "SuperSimple_18A.inc" ; Select SuperSimple 18A pinout -#endif - -#if defined(SUPERSIMPLE_18A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "SuperSimple_18A.inc" ; Select SuperSimple 18A pinout -#endif - -#if defined(SUPERSIMPLE_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "SuperSimple_20A.inc" ; Select SuperSimple 20A pinout -#endif - -#if defined(SUPERSIMPLE_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "SuperSimple_20A.inc" ; Select SuperSimple 20A pinout -#endif - -#if defined(SUPERSIMPLE_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "SuperSimple_20A.inc" ; Select SuperSimple 20A pinout -#endif - -#if defined(SUPERSIMPLE_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "SuperSimple_30A.inc" ; Select SuperSimple 30A pinout -#endif - -#if defined(SUPERSIMPLE_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "SuperSimple_30A.inc" ; Select SuperSimple 30A pinout -#endif - -#if defined(SUPERSIMPLE_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "SuperSimple_30A.inc" ; Select SuperSimple 30A pinout -#endif - -#if defined(SUPERSIMPLE_40A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "SuperSimple_40A.inc" ; Select SuperSimple 40A pinout -#endif - -#if defined(SUPERSIMPLE_40A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "SuperSimple_40A.inc" ; Select SuperSimple 40A pinout -#endif - -#if defined(SUPERSIMPLE_40A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "SuperSimple_40A.inc" ; Select SuperSimple 40A pinout -#endif - -#if defined(MULTISTAR_10Av2_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_10Av2.inc" ; Select Multistar 10A v2 pinout -#endif - -#if defined(MULTISTAR_10Av2_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_10Av2.inc" ; Select Multistar 10A v2 pinout -#endif - -#if defined(MULTISTAR_10Av2_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_10Av2.inc" ; Select Multistar 10A v2 pinout -#endif - -#if defined(MULTISTAR_15A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_15A.inc" ; Select Multistar 15A pinout -#endif - -#if defined(MULTISTAR_15A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_15A.inc" ; Select Multistar 15A pinout -#endif - -#if defined(MULTISTAR_15A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_15A.inc" ; Select Multistar 15A pinout -#endif - -#if defined(MULTISTAR_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_20A.inc" ; Select Multistar 20A pinout -#endif - -#if defined(MULTISTAR_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_20A.inc" ; Select Multistar 20A pinout -#endif - -#if defined(MULTISTAR_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_20A.inc" ; Select Multistar 20A pinout -#endif - -#if defined(MULTISTAR_20A_NFET_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_20A_NFET.inc" ; Select Multistar 20A NFET pinout -#endif - -#if defined(MULTISTAR_20A_NFET_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_20A_NFET.inc" ; Select Multistar 20A NFET pinout -#endif - -#if defined(MULTISTAR_20A_NFET_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_20A_NFET.inc" ; Select Multistar 20A NFET pinout -#endif - -#if defined(MULTISTAR_20Av2_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_20Av2.inc" ; Select Multistar 20A v2 pinout -#endif - -#if defined(MULTISTAR_20Av2_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_20Av2.inc" ; Select Multistar 20A v2 pinout -#endif - -#if defined(MULTISTAR_20Av2_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_20Av2.inc" ; Select Multistar 20A v2 pinout -#endif - -#if defined(MULTISTAR_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_30A.inc" ; Select Multistar 30A pinout -#endif - -#if defined(MULTISTAR_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_30A.inc" ; Select Multistar 30A pinout -#endif - -#if defined(MULTISTAR_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_30A.inc" ; Select Multistar 30A pinout -#endif - -#if defined(MULTISTAR_40Av2_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_40Av2.inc" ; Select Multistar 40A v2 pinout -#endif - -#if defined(MULTISTAR_40Av2_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_40Av2.inc" ; Select Multistar 40A v2 pinout -#endif - -#if defined(MULTISTAR_40Av2_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_40Av2.inc" ; Select Multistar 40A v2 pinout -#endif - -#if defined(MULTISTAR_45A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Multistar_45A.inc" ; Select Multistar 45A pinout -#endif - -#if defined(MULTISTAR_45A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Multistar_45A.inc" ; Select Multistar 45A pinout -#endif - -#if defined(MULTISTAR_45A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Multistar_45A.inc" ; Select Multistar 45A pinout -#endif - -#if defined(MYSTERY_12A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Mystery_12A.inc" ; Select Mystery 12A pinout -#endif - -#if defined(MYSTERY_12A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Mystery_12A.inc" ; Select Mystery 12A pinout -#endif - -#if defined(MYSTERY_12A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Mystery_12A.inc" ; Select Mystery 12A pinout -#endif - -#if defined(MYSTERY_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Mystery_30A.inc" ; Select Mystery 30A pinout -#endif - -#if defined(MYSTERY_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Mystery_30A.inc" ; Select Mystery 30A pinout -#endif - -#if defined(MYSTERY_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Mystery_30A.inc" ; Select Mystery 30A pinout -#endif - -#if defined(MYSTERY_40A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Mystery_40A.inc" ; Select Mystery 40A pinout -#endif - -#if defined(MYSTERY_40A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Mystery_40A.inc" ; Select Mystery 40A pinout -#endif - -#if defined(MYSTERY_40A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Mystery_40A.inc" ; Select Mystery 40A pinout -#endif - -#if defined(SUNRISE_HIMULTI_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Sunrise_HiMulti_20A.inc" ; Select Sunrise HiMulti 20A pinout -#endif - -#if defined(SUNRISE_HIMULTI_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Sunrise_HiMulti_20A.inc" ; Select Sunrise HiMulti 20A pinout -#endif - -#if defined(SUNRISE_HIMULTI_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Sunrise_HiMulti_20A.inc" ; Select Sunrise HiMulti 20A pinout -#endif - -#if defined(SUNRISE_HIMULTI_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Sunrise_HiMulti_30A.inc" ; Select Sunrise HiMulti 30A pinout -#endif - -#if defined(SUNRISE_HIMULTI_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Sunrise_HiMulti_30A.inc" ; Select Sunrise HiMulti 30A pinout -#endif - -#if defined(SUNRISE_HIMULTI_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Sunrise_HiMulti_30A.inc" ; Select Sunrise HiMulti 30A pinout -#endif - -#if defined(SUNRISE_HIMULTI_40A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Sunrise_HiMulti_40A.inc" ; Select Sunrise HiMulti 40A pinout -#endif - -#if defined(SUNRISE_HIMULTI_40A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Sunrise_HiMulti_40A.inc" ; Select Sunrise HiMulti 40A pinout -#endif - -#if defined(SUNRISE_HIMULTI_40A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Sunrise_HiMulti_40A.inc" ; Select Sunrise HiMulti 40A pinout -#endif - -#if defined(RCTIMER_40A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "RCTimer_40A.inc" ; Select RCTimer 40A pinout -#endif - -#if defined(RCTIMER_40A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "RCTimer_40A.inc" ; Select RCTimer 40A pinout -#endif - -#if defined(RCTIMER_40A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "RCTimer_40A.inc" ; Select RCTimer 40A pinout -#endif - -#if defined(RCTIMER_NFS_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "RCTimer_NFS_30A.inc" ; Select RCTimer NFS 30A pinout -#endif - -#if defined(RCTIMER_NFS_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "RCTimer_NFS_30A.inc" ; Select RCTimer NFS 30A pinout -#endif - -#if defined(RCTIMER_NFS_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "RCTimer_NFS_30A.inc" ; Select RCTimer NFS 30A pinout -#endif - -#if defined(YEP_7A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "YEP_7A.inc" ; Select YEP 7A pinout -#endif - -#if defined(YEP_7A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "YEP_7A.inc" ; Select YEP 7A pinout -#endif - -#if defined(YEP_7A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "YEP_7A.inc" ; Select YEP 7A pinout -#endif - -#if defined(AFRO_12A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "AFRO_12A.inc" ; Select AFRO 12A pinout -#endif - -#if defined(AFRO_12A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "AFRO_12A.inc" ; Select AFRO 12A pinout -#endif - -#if defined(AFRO_12A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "AFRO_12A.inc" ; Select AFRO 12A pinout -#endif - -#if defined(AFRO_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "AFRO_20A.inc" ; Select AFRO 20A pinout -#endif - -#if defined(AFRO_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "AFRO_20A.inc" ; Select AFRO 20A pinout -#endif - -#if defined(AFRO_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "AFRO_20A.inc" ; Select AFRO 20A pinout -#endif - -#if defined(AFRO_20A_HV_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "AFRO_20A_HV.inc" ; Select AFRO 20A HV pinout -#endif - -#if defined(AFRO_20A_HV_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "AFRO_20A_HV.inc" ; Select AFRO 20A HV pinout -#endif - -#if defined(AFRO_20A_HV_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "AFRO_20A_HV.inc" ; Select AFRO 20A HV pinout -#endif - -#if defined(AFRO_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "AFRO_30A.inc" ; Select AFRO 30A pinout -#endif - -#if defined(AFRO_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "AFRO_30A.inc" ; Select AFRO 30A pinout -#endif - -#if defined(AFRO_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "AFRO_30A.inc" ; Select AFRO 30A pinout -#endif - -#if defined(SUNRISE_BLHELI_SLIM_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Sunrise_BLHeli_Slim_20A.inc" ; Select Sunrise BLHeli slim 20A pinout -#endif - -#if defined(SUNRISE_BLHELI_SLIM_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Sunrise_BLHeli_Slim_20A.inc" ; Select Sunrise BLHeli slim 20A pinout -#endif - -#if defined(SUNRISE_BLHELI_SLIM_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Sunrise_BLHeli_Slim_20A.inc" ; Select Sunrise BLHeli slim 20A pinout -#endif - -#if defined(SUNRISE_BLHELI_SLIM_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Sunrise_BLHeli_Slim_30A.inc" ; Select Sunrise BLHeli slim 30A pinout -#endif - -#if defined(SUNRISE_BLHELI_SLIM_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Sunrise_BLHeli_Slim_30A.inc" ; Select Sunrise BLHeli slim 30A pinout -#endif - -#if defined(SUNRISE_BLHELI_SLIM_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Sunrise_BLHeli_Slim_30A.inc" ; Select Sunrise BLHeli slim 30A pinout -#endif - -#if defined(DYS_SN20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "DYS_SN20A.inc" ; Select DYS SN20A pinout -#endif - -#if defined(DYS_SN20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "DYS_SN20A.inc" ; Select DYS SN20A pinout -#endif - -#if defined(DYS_SN20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "DYS_SN20A.inc" ; Select DYS SN20A pinout -#endif - -#if defined(TBS_CUBE_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "TBS_CUBE_20A.inc" ; Select TBS CUBE 20A pinout -#endif - -#if defined(TBS_CUBE_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "TBS_CUBE_20A.inc" ; Select TBS CUBE 20A pinout -#endif - -#if defined(TBS_CUBE_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "TBS_CUBE_20A.inc" ; Select TBS CUBE 20A pinout -#endif - -#if defined(ZTW_SPIDER_LITE_18Av2_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "ZTW_Spider_Lite_18Av2.inc" ; Select ZTW Spider Lite 18Av2 pinout -#endif - -#if defined(ZTW_SPIDER_LITE_18Av2_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "ZTW_Spider_Lite_18Av2.inc" ; Select ZTW Spider Lite 18Av2 pinout -#endif - -#if defined(ZTW_SPIDER_LITE_18Av2_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "ZTW_Spider_Lite_18Av2.inc" ; Select ZTW Spider Lite 18Av2 pinout -#endif - -#if defined(HTIRC_DRAGONFLY_6A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Htirc_Dragonfly_6A.inc" ; Select HTIRC Dragonfly 6A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_6A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Htirc_Dragonfly_6A.inc" ; Select HTIRC Dragonfly 6A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_6A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Htirc_Dragonfly_6A.inc" ; Select HTIRC Dragonfly 6A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_12A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Htirc_Dragonfly_12A.inc" ; Select HTIRC Dragonfly 12A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_12A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Htirc_Dragonfly_12A.inc" ; Select HTIRC Dragonfly 12A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_12A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Htirc_Dragonfly_12A.inc" ; Select HTIRC Dragonfly 12A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_20A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Htirc_Dragonfly_20A.inc" ; Select HTIRC Dragonfly 20A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_20A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Htirc_Dragonfly_20A.inc" ; Select HTIRC Dragonfly 20A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_20A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Htirc_Dragonfly_20A.inc" ; Select HTIRC Dragonfly 20A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Htirc_Dragonfly_30A.inc" ; Select HTIRC Dragonfly 30A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Htirc_Dragonfly_30A.inc" ; Select HTIRC Dragonfly 30A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Htirc_Dragonfly_30A.inc" ; Select HTIRC Dragonfly 30A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_40A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "Htirc_Dragonfly_40A.inc" ; Select HTIRC Dragonfly 40A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_40A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "Htirc_Dragonfly_40A.inc" ; Select HTIRC Dragonfly 40A pinout -#endif - -#if defined(HTIRC_DRAGONFLY_40A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "Htirc_Dragonfly_40A.inc" ; Select HTIRC Dragonfly 40A pinout -#endif - -#if defined(TBS_BULLETPROOF_4A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "TBS_BULLETPROOF_4A.inc" ; Select TBS BULLETPROOF 4A pinout -#endif - -#if defined(TBS_BULLETPROOF_4A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "TBS_BULLETPROOF_4A.inc" ; Select TBS BULLETPROOF 4A pinout -#endif - -#if defined(TBS_BULLETPROOF_4A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "TBS_BULLETPROOF_4A.inc" ; Select TBS BULLETPROOF 4A pinout -#endif - -#if defined(TBS_BULLETPROOF_30A_MAIN) -.EQU MODE = 0 ; Choose mode. Set to 0 for main motor -.INCLUDE "TBS_BULLETPROOF_30A.inc" ; Select TBS BULLETPROOF 30A pinout -#endif - -#if defined(TBS_BULLETPROOF_30A_TAIL) -.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor -.INCLUDE "TBS_BULLETPROOF_30A.inc" ; Select TBS BULLETPROOF 30A pinout -#endif - -#if defined(TBS_BULLETPROOF_30A_MULTI) -.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor -.INCLUDE "TBS_BULLETPROOF_30A.inc" ; Select TBS BULLETPROOF 30A 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) -; -; Main -.EQU DEFAULT_PGM_MAIN_P_GAIN = 7 ; 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 -.EQU DEFAULT_PGM_MAIN_I_GAIN = 7 ; 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 -.EQU DEFAULT_PGM_MAIN_GOVERNOR_MODE = 1 ; 1=Tx 2=Arm 3=Setup 4=Off -.EQU DEFAULT_PGM_MAIN_GOVERNOR_RANGE = 1 ; 1=High 2=Middle 3=Low -.EQU DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM = 4 ; 1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c -.EQU DEFAULT_PGM_MAIN_COMM_TIMING = 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High -.IF DAMPED_MODE_ENABLE == 1 -.EQU DEFAULT_PGM_MAIN_PWM_FREQ = 2 ; 1=High 2=Low 3=DampedLight -.ELSE -.EQU DEFAULT_PGM_MAIN_PWM_FREQ = 2 ; 1=High 2=Low -.ENDIF -.EQU DEFAULT_PGM_MAIN_DEMAG_COMP = 1 ; 1=Disabled 2=Low 3=High -.EQU DEFAULT_PGM_MAIN_DIRECTION = 1 ; 1=Normal 2=Reversed -.EQU DEFAULT_PGM_MAIN_RCP_PWM_POL = 1 ; 1=Positive 2=Negative -.EQU DEFAULT_PGM_MAIN_GOV_SETUP_TARGET = 180; Target for governor in setup mode. Corresponds to 70% throttle -.EQU DEFAULT_PGM_MAIN_REARM_START = 0 ; 1=Enabled 0=Disabled -.EQU DEFAULT_PGM_MAIN_BEEP_STRENGTH = 120; Beep strength -.EQU DEFAULT_PGM_MAIN_BEACON_STRENGTH = 200; Beacon strength -.EQU DEFAULT_PGM_MAIN_BEACON_DELAY = 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite - -; Tail -.EQU DEFAULT_PGM_TAIL_GAIN = 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25 -.EQU DEFAULT_PGM_TAIL_IDLE_SPEED = 4 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High -.EQU DEFAULT_PGM_TAIL_COMM_TIMING = 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High -.IF DAMPED_MODE_ENABLE == 1 -.EQU DEFAULT_PGM_TAIL_PWM_FREQ = 3 ; 1=High 2=Low 3=DampedLight -.ELSE -.EQU DEFAULT_PGM_TAIL_PWM_FREQ = 1 ; 1=High 2=Low -.ENDIF -.EQU DEFAULT_PGM_TAIL_DEMAG_COMP = 1 ; 1=Disabled 2=Low 3=High -.EQU DEFAULT_PGM_TAIL_DIRECTION = 1 ; 1=Normal 2=Reversed 3=Bidirectional -.EQU DEFAULT_PGM_TAIL_RCP_PWM_POL = 1 ; 1=Positive 2=Negative -.EQU DEFAULT_PGM_TAIL_BEEP_STRENGTH = 250; Beep strength -.EQU DEFAULT_PGM_TAIL_BEACON_STRENGTH = 250; Beacon strength -.EQU DEFAULT_PGM_TAIL_BEACON_DELAY = 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite -.EQU DEFAULT_PGM_TAIL_PWM_DITHER = 3 ; 1=Off 2=3 3=7 4=15 5=31 - -; Multi -.EQU DEFAULT_PGM_MULTI_P_GAIN = 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 -.EQU DEFAULT_PGM_MULTI_I_GAIN = 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 -.EQU DEFAULT_PGM_MULTI_GOVERNOR_MODE = 4 ; 1=HiRange 2=MidRange 3=LoRange 4=Off -.EQU DEFAULT_PGM_MULTI_GAIN = 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25 -.EQU DEFAULT_PGM_MULTI_COMM_TIMING = 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High -.IF DAMPED_MODE_ENABLE == 1 -.EQU DEFAULT_PGM_MULTI_PWM_FREQ = 3 ; 1=High 2=Low 3=DampedLight -.ELSE -.EQU DEFAULT_PGM_MULTI_PWM_FREQ = 1 ; 1=High 2=Low -.ENDIF -.EQU DEFAULT_PGM_MULTI_DEMAG_COMP = 2 ; 1=Disabled 2=Low 3=High -.EQU DEFAULT_PGM_MULTI_DIRECTION = 1 ; 1=Normal 2=Reversed 3=Bidirectional -.EQU DEFAULT_PGM_MULTI_RCP_PWM_POL = 1 ; 1=Positive 2=Negative -.EQU DEFAULT_PGM_MULTI_BEEP_STRENGTH = 40 ; Beep strength -.EQU DEFAULT_PGM_MULTI_BEACON_STRENGTH = 80 ; Beacon strength -.EQU DEFAULT_PGM_MULTI_BEACON_DELAY = 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite -.EQU DEFAULT_PGM_MULTI_PWM_DITHER = 3 ; 1=Off 2=3 3=7 4=15 5=31 - -; Common -.EQU DEFAULT_PGM_ENABLE_TX_PROGRAM = 1 ; 1=Enabled 0=Disabled -.EQU DEFAULT_PGM_PPM_MIN_THROTTLE = 37 ; 4*37+1000=1148 -.EQU DEFAULT_PGM_PPM_MAX_THROTTLE = 208; 4*208+1000=1832 -.EQU DEFAULT_PGM_PPM_CENTER_THROTTLE = 122; 4*122+1000=1488 (used in bidirectional mode) -.EQU DEFAULT_PGM_BEC_VOLTAGE_HIGH = 0 ; 0=Low 1= High -.EQU DEFAULT_PGM_ENABLE_TEMP_PROT = 0 ; 1=Enabled 0=Disabled -.EQU DEFAULT_PGM_ENABLE_POWER_PROT = 1 ; 1=Enabled 0=Disabled -.EQU DEFAULT_PGM_ENABLE_PWM_INPUT = 0 ; 1=Enabled 0=Disabled -.EQU DEFAULT_PGM_BRAKE_ON_STOP = 0 ; 1=Enabled 0=Disabled - -;**** **** **** **** **** -; Constant definitions for main -.IF MODE == 0 - -.EQU GOV_SPOOLRATE = 2 ; Number of steps for governor requested pwm per 32ms - -.EQU RCP_TIMEOUT_PPM = 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost -.EQU RCP_TIMEOUT = 64 ; Number of timer2L overflows (about 128us) before considering rc pulse lost -.EQU RCP_SKIP_RATE = 32 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection -.EQU RCP_MIN = 0 ; This is minimum RC pulse length -.EQU RCP_MAX = 255 ; This is maximum RC pulse length -.EQU RCP_VALIDATE = 2 ; Require minimum this pulse length to validate RC pulse -.EQU RCP_STOP = 1 ; Stop motor at or below this pulse length -.EQU RCP_STOP_LIMIT = 250 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit - -.EQU PWM_START = 50 ; PWM used as max power during start - -.EQU COMM_TIME_MIN = 1 ; Minimum time (in us) for commutation wait - -.EQU TEMP_CHECK_RATE = 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 - -.EQU GOV_SPOOLRATE = 1 ; Number of steps for governor requested pwm per 32ms -.EQU RCP_TIMEOUT_PPM = 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost -.EQU RCP_TIMEOUT = 24 ; Number of timer2L overflows (about 128us) before considering rc pulse lost -.EQU RCP_SKIP_RATE = 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection -.EQU RCP_MIN = 0 ; This is minimum RC pulse length -.EQU RCP_MAX = 255 ; This is maximum RC pulse length -.EQU RCP_VALIDATE = 2 ; Require minimum this pulse length to validate RC pulse -.EQU RCP_STOP = 1 ; Stop motor at or below this pulse length -.EQU RCP_STOP_LIMIT = 130 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit - -.EQU PWM_START = 50 ; PWM used as max power during start - -.EQU COMM_TIME_MIN = 1 ; Minimum time (in us) for commutation wait - -.EQU TEMP_CHECK_RATE = 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 - -.EQU GOV_SPOOLRATE = 1 ; Number of steps for governor requested pwm per 32ms - -.EQU RCP_TIMEOUT_PPM = 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost -.EQU RCP_TIMEOUT = 24 ; Number of timer2L overflows (about 128us) before considering rc pulse lost -.EQU RCP_SKIP_RATE = 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection -.EQU RCP_MIN = 0 ; This is minimum RC pulse length -.EQU RCP_MAX = 255 ; This is maximum RC pulse length -.EQU RCP_VALIDATE = 2 ; Require minimum this pulse length to validate RC pulse -.EQU RCP_STOP = 1 ; Stop motor at or below this pulse length -.EQU RCP_STOP_LIMIT = 250 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit - -.EQU PWM_START = 50 ; PWM used as max power during start - -.EQU COMM_TIME_MIN = 1 ; Minimum time (in us) for commutation wait - -.EQU TEMP_CHECK_RATE = 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage) - -.ENDIF - -;**** **** **** **** **** -; Register definitions -.DEF Mul_Res_L = R0 ; Reserved for mul instruction -.DEF Mul_Res_H = R1 ; Reserved for mul instruction -.DEF Zero = R2 ; Register variable initialized to 0, always at 0 -.DEF I_Sreg = R3 ; Status register saved in interrupts -.DEF II_Sreg = R4 ; Status register saved in nested interrupts (pwm interrupts from timer2) -.DEF Current_Pwm_Limited = R5 ; Current_Pwm_Limited is allocated to a register for fast access -.DEF Next_Wt_L = R14 ; Next wait value (lo byte) -.DEF Next_Wt_H = R15 ; Next wait value (hi byte) - -.DEF Temp1 = R16 ; Main temporary -.DEF Temp2 = R17 ; Main temporary (Temp1/2 must be two consecutive registers) -.DEF Temp3 = R18 ; Main temporary -.DEF Temp4 = R19 ; Main temporary -.DEF Temp5 = R6 ; Main temporary (limited operations) -.DEF Temp6 = R7 ; Main temporary (limited operations) -.DEF Temp7 = R8 ; Main temporary (limited operations) -.DEF Temp8 = R9 ; Main temporary (limited operations) - -.DEF I_Temp1 = R20 ; Interrupt temporary -.DEF I_Temp2 = R21 ; Interrupt temporary -.DEF I_Temp3 = R10 ; Interrupt temporary (limited operations) -.DEF I_Temp4 = R11 ; Interrupt temporary (limited operations) -.DEF I_Temp5 = R12 ; Interrupt temporary (limited operations) -.DEF I_Temp6 = R13 ; Interrupt temporary (limited operations) - -.DEF Flags0 = R22 ; State flags. Reset upon init_start -.EQU OC1A_PENDING = 0 ; Timer1 output compare pending flag -.EQU RCP_MEAS_PWM_FREQ = 1 ; Measure RC pulse pwm frequency -.EQU PWM_ON = 2 ; Set in on part of pwm cycle -.EQU DEMAG_DETECTED = 3 ; Set when excessive demag time is detected -.EQU DEMAG_CUT_POWER = 4 ; Set when demag compensation cuts power -.EQU GOV_ACTIVE = 5 ; Set when governor is active -.EQU DIR_CHANGE_BRAKE = 6 ; Set when braking before direction change -; = 7 - -.DEF Flags1 = R23 ; State flags. Reset upon init_start -.EQU MOTOR_SPINNING = 0 ; Set when in motor is spinning -.EQU STARTUP_PHASE = 1 ; Set when in startup phase -.EQU INITIAL_RUN_PHASE = 2 ; Set when in initial run phase, before synchronized run is achieved -.EQU MOTOR_STARTED = 3 ; Set when motor is started -.EQU ADC_READ_TEMP = 4 ; Set when ADC input shall be set to read temperature -.EQU COMP_TIMED_OUT = 5 ; Set when comparator reading timed out -.EQU SKIP_DAMP_ON = 6 ; Set when turning damping fet on is skipped -.EQU HIGH_RPM = 7 ; Set when motor rpm is high (Comm_Period4x_H less than 2) - -.DEF Flags2 = R24 ; State flags. NOT reset upon init_start -.EQU RCP_UPDATED = 0 ; New RC pulse length value available -.EQU RCP_EDGE_NO = 1 ; RC pulse edge no. 0=rising, 1=falling -.EQU PGM_PWMOFF_DAMPED = 2 ; Programmed pwm off damped mode -.EQU PGM_PWM_HIGH_FREQ = 3 ; Progremmed pwm high frequency -.EQU RCP_INT_NESTED_ENABLED = 4 ; Set when RC pulse interrupt is enabled around nested interrupts -.EQU RCP_PPM = 5 ; RC pulse ppm type input (set also when oneshot is set) -.EQU RCP_PPM_ONESHOT125 = 6 ; RC pulse ppm type input is OneShot125 -.EQU RCP_DIR_REV = 7 ; RC pulse direction in bidirectional mode - -.DEF Flags3 = R25 ; State flags. NOT reset upon init_start -.EQU RCP_PWM_FREQ_1KHZ = 0 ; RC pulse pwm frequency is 1kHz -.EQU RCP_PWM_FREQ_2KHZ = 1 ; RC pulse pwm frequency is 2kHz -.EQU RCP_PWM_FREQ_4KHZ = 2 ; RC pulse pwm frequency is 4kHz -.EQU RCP_PWM_FREQ_8KHZ = 3 ; RC pulse pwm frequency is 8kHz -.EQU RCP_PWM_FREQ_12KHZ = 4 ; RC pulse pwm frequency is 12kHz -.EQU PGM_DIR_REV = 5 ; Programmed direction. 0=normal, 1=reversed -.EQU PGM_RCP_PWM_POL = 6 ; Programmed RC pulse pwm polarity. 0=positive, 1=negative -.EQU FULL_THROTTLE_RANGE = 7 ; When set full throttle range is used (1000-2000us) and stored calibration values are ignored - - -; Here the general temporary register XYZ are placed (R26-R31) - -; XH: General temporary used by main routines -; XL: General temporary used by interrupt routines -; Y: General temporary used by timer2 pwm interrupt routine -; Z: Address of current PWM FET ON routine (eg: pwm_afet_on) - -;**** **** **** **** **** -; RAM definitions -.DSEG ; Data segment -.ORG SRAM_START -Timer0_Int_Cnt: .BYTE 1 ; Timer0 interrupt counter - -Requested_Pwm: .BYTE 1 ; Requested pwm (from RC pulse value) -Governor_Req_Pwm: .BYTE 1 ; Governor requested pwm (sets governor target) -Current_Pwm: .BYTE 1 ; Current pwm -Current_Pwm_Lim_Dith: .BYTE 1 ; Current pwm that is limited and dithered (applied to the motor output) -Rcp_Prev_Edge_L: .BYTE 1 ; RC pulse previous edge timer3 timestamp (lo byte) -Rcp_Prev_Edge_H: .BYTE 1 ; RC pulse previous edge timer3 timestamp (hi byte) -Rcp_Outside_Range_Cnt: .BYTE 1 ; RC pulse outside range counter (incrementing) -Rcp_Timeout_Cntd: .BYTE 1 ; RC pulse timeout counter (decrementing) -Rcp_Skip_Cntd: .BYTE 1 ; RC pulse skip counter (decrementing) - -Initial_Arm: .BYTE 1 ; Variable that is set during the first arm sequence after power on - -Power_On_Wait_Cnt_L: .BYTE 1 ; Power on wait counter (lo byte) -Power_On_Wait_Cnt_H: .BYTE 1 ; Power on wait counter (hi byte) - -Startup_Cnt: .BYTE 1 ; Startup phase commutations counter (incrementing) -Startup_Zc_Timeout_Cntd: .BYTE 1 ; Startup zero cross timeout counter (decrementing) -Initial_Run_Rot_Cntd: .BYTE 1 ; Initial run rotations counter (decrementing) -Stall_Cnt: .BYTE 1 ; Counts start/run attempts that resulted in stall. Reset upon a proper stop -Demag_Detected_Metric: .BYTE 1 ; Metric used to gauge demag event frequency -Demag_Pwr_Off_Thresh: .BYTE 1 ; Metric threshold above which power is cut -Low_Rpm_Pwr_Slope: .BYTE 1 ; Sets the slope of power increase for low rpms - -Timer2_X: .BYTE 1 ; Timer 2 extended byte -Prev_Comm_L: .BYTE 1 ; Previous commutation timer timestamp (lo byte) -Prev_Comm_H: .BYTE 1 ; Previous commutation timer timestamp (hi byte) -Prev_Comm_X: .BYTE 1 ; Previous commutation timer3 timestamp (ext byte) -Prev_Prev_Comm_L: .BYTE 1 ; Pre-previous commutation timer timestamp (lo byte) -Prev_Prev_Comm_H: .BYTE 1 ; Pre-previous commutation timer timestamp (hi byte) -Comm_Period4x_L: .BYTE 1 ; Timer3 counts between the last 4 commutations (lo byte) -Comm_Period4x_H: .BYTE 1 ; Timer3 counts between the last 4 commutations (hi byte) -Comm_Phase: .BYTE 1 ; Current commutation phase -Comparator_Read_Cnt: .BYTE 1 ; Number of comparator reads done - -Gov_Target_L: .BYTE 1 ; Governor target (lo byte) -Gov_Target_H: .BYTE 1 ; Governor target (hi byte) -Gov_Integral_L: .BYTE 1 ; Governor integral error (lo byte) -Gov_Integral_H: .BYTE 1 ; Governor integral error (hi byte) -Gov_Integral_X: .BYTE 1 ; Governor integral error (ex byte) -Gov_Proportional_L: .BYTE 1 ; Governor proportional error (lo byte) -Gov_Proportional_H: .BYTE 1 ; Governor proportional error (hi byte) -Gov_Prop_Pwm: .BYTE 1 ; Governor calculated new pwm based upon proportional error -Gov_Arm_Target: .BYTE 1 ; Governor arm target value - -Wt_Advance_L: .BYTE 1 ; Timer3 counts for commutation advance timing (lo byte) -Wt_Advance_H: .BYTE 1 ; Timer3 counts for commutation advance timing (hi byte) -Wt_Zc_Scan_L: .BYTE 1 ; Timer3 counts from commutation to zero cross scan (lo byte) -Wt_Zc_Scan_H: .BYTE 1 ; Timer3 counts from commutation to zero cross scan (hi byte) -Wt_Zc_Timeout_L: .BYTE 1 ; Timer3 counts for zero cross scan timeout (lo byte) -Wt_Zc_Timeout_H: .BYTE 1 ; Timer3 counts for zero cross scan timeout (hi byte) -Wt_Comm_L: .BYTE 1 ; Timer3 counts from zero cross to commutation (lo byte) -Wt_Comm_H: .BYTE 1 ; Timer3 counts from zero cross to commutation (hi byte) - -Rcp_PrePrev_Edge_L: .BYTE 1 ; RC pulse pre previous edge pca timestamp (lo byte) -Rcp_PrePrev_Edge_H: .BYTE 1 ; RC pulse pre previous edge pca timestamp (hi byte) -Rcp_Edge_L: .BYTE 1 ; RC pulse edge pca timestamp (lo byte) -Rcp_Edge_H: .BYTE 1 ; RC pulse edge pca timestamp (hi byte) -Rcp_Prev_Period_L: .BYTE 1 ; RC pulse previous period (lo byte) -Rcp_Prev_Period_H: .BYTE 1 ; RC pulse previous period (hi byte) -Rcp_Period_Diff_Accepted: .BYTE 1 ; RC pulse period difference acceptable -New_Rcp: .BYTE 1 ; New RC pulse value in pca counts -Prev_Rcp_Pwm_Freq: .BYTE 1 ; Previous RC pulse pwm frequency (used during pwm frequency measurement) -Curr_Rcp_Pwm_Freq: .BYTE 1 ; Current RC pulse pwm frequency (used during pwm frequency measurement) -Rcp_Stop_Cnt: .BYTE 1 ; Counter for RC pulses below stop value (lo byte) -Auto_Bailout_Armed: .BYTE 1 ; Set when auto rotation bailout is armed - -Pwm_Limit: .BYTE 1 ; Maximum allowed pwm -Pwm_Limit_Spoolup: .BYTE 1 ; Maximum allowed pwm during spoolup of main -Pwm_Limit_By_Rpm: .BYTE 1 ; Maximum allowed pwm for low or high rpms -Pwm_Spoolup_Beg: .BYTE 1 ; Pwm to begin main spoolup with -Pwm_Motor_Idle: .BYTE 1 ; Motor idle speed pwm -Pwm_Dither_Decoded: .BYTE 1 ; Decoded pwm dither value -Pwm_Dither_Excess_Power: .BYTE 1 ; Excess power (above max) from pwm dither -Random: .BYTE 1 ; Random number from LFSR - -Spoolup_Limit_Cnt: .BYTE 1 ; Interrupt count for spoolup limit -Spoolup_Limit_Skip: .BYTE 1 ; Interrupt skips for spoolup limit increment (1=no skips, 2=skip one etc) -Main_Spoolup_Time_3x: .BYTE 1 ; Main spoolup time x3 -Main_Spoolup_Time_10x: .BYTE 1 ; Main spoolup time x10 -Main_Spoolup_Time_15x: .BYTE 1 ; Main spoolup time x15 - -Lipo_Adc_Limit_L: .BYTE 1 ; Low voltage limit adc value (lo byte) -Lipo_Adc_Limit_H: .BYTE 1 ; Low voltage limit adc value (hi byte) -Adc_Conversion_Cnt: .BYTE 1 ; Adc conversion counter - -Current_Average_Temp_Adc: .BYTE 1 ; Current average temp ADC reading (lo byte of ADC, assuming hi byte is 0) - -Ppm_Throttle_Gain: .BYTE 1 ; Gain to be applied to RCP value for PPM input -Beep_Strength: .BYTE 1 ; Strength of beeps - -Tx_Pgm_Func_No: .BYTE 1 ; Function number when doing programming by tx -Tx_Pgm_Paraval_No: .BYTE 1 ; Parameter value number when doing programming by tx -Tx_Pgm_Beep_No: .BYTE 1 ; Beep number when doing programming by tx -DampingFET: .BYTE 1 ; Port position of fet used for damping - -; The variables below must be in this sequence -Pgm_Gov_P_Gain: .BYTE 1 ; Programmed governor P gain -Pgm_Gov_I_Gain: .BYTE 1 ; Programmed governor I gain -Pgm_Gov_Mode: .BYTE 1 ; Programmed governor mode -Pgm_Low_Voltage_Lim: .BYTE 1 ; Programmed low voltage limit -Pgm_Motor_Gain: .BYTE 1 ; Programmed motor gain -Pgm_Motor_Idle: .BYTE 1 ; Programmed motor idle speed -Pgm_Startup_Pwr: .BYTE 1 ; Programmed startup power -Pgm_Pwm_Freq: .BYTE 1 ; Programmed pwm frequency -Pgm_Direction: .BYTE 1 ; Programmed rotation direction -Pgm_Input_Pol: .BYTE 1 ; Programmed input pwm polarity -Initialized_L_Dummy: .BYTE 1 ; Place holder -Initialized_H_Dummy: .BYTE 1 ; Place holder -Pgm_Enable_TX_Program: .BYTE 1 ; Programmed enable/disable value for TX programming -Pgm_Main_Rearm_Start: .BYTE 1 ; Programmed enable/disable re-arming main every start -Pgm_Gov_Setup_Target: .BYTE 1 ; Programmed main governor setup target -_Pgm_Startup_Rpm: .BYTE 1 ; Programmed startup rpm (unused - place holder) -_Pgm_Startup_Accel: .BYTE 1 ; Programmed startup acceleration (unused - place holder) -_Pgm_Volt_Comp: .BYTE 1 ; Place holder -Pgm_Comm_Timing: .BYTE 1 ; Programmed commutation timing -_Pgm_Damping_Force: .BYTE 1 ; Programmed damping force (unused - place holder) -Pgm_Gov_Range: .BYTE 1 ; Programmed governor range -Pgm_Startup_Method: .BYTE 1 ; Programmed startup method -Pgm_Ppm_Min_Throttle: .BYTE 1 ; Programmed throttle minimum -Pgm_Ppm_Max_Throttle: .BYTE 1 ; Programmed throttle maximum -Pgm_Beep_Strength: .BYTE 1 ; Programmed beep strength -Pgm_Beacon_Strength: .BYTE 1 ; Programmed beacon strength -Pgm_Beacon_Delay: .BYTE 1 ; Programmed beacon delay -_Pgm_Throttle_Rate: .BYTE 1 ; Programmed throttle rate (unused - place holder) -Pgm_Demag_Comp: .BYTE 1 ; Programmed demag compensation -Pgm_BEC_Voltage_High: .BYTE 1 ; Programmed BEC voltage -Pgm_Ppm_Center_Throttle: .BYTE 1 ; Programmed throttle center (in bidirectional mode) -Pgm_Main_Spoolup_Time: .BYTE 1 ; Programmed main spoolup time -Pgm_Enable_Temp_Prot: .BYTE 1 ; Programmed temperature protection enable -Pgm_Enable_Power_Prot: .BYTE 1 ; Programmed low rpm power protection enable -Pgm_Enable_Pwm_Input: .BYTE 1 ; Programmed PWM input signal enable -Pgm_Pwm_Dither: .BYTE 1 ; Programmed output PWM dither -Pgm_Brake_On_Stop: .BYTE 1 ; Programmed braking when throttle is zero - -; The sequence of the variables below is no longer of importance -Pgm_Gov_P_Gain_Decoded: .BYTE 1 ; Programmed governor decoded P gain -Pgm_Gov_I_Gain_Decoded: .BYTE 1 ; Programmed governor decoded I gain -Pgm_Startup_Pwr_Decoded: .BYTE 1 ; Programmed startup power decoded - - -.EQU SRAM_BYTES = 255 ; Bytes used in SRAM. Used for number of bytes to reset - -;**** **** **** **** **** -.ESEG ; Eeprom segment -.ORG 0 - -.EQU EEPROM_FW_MAIN_REVISION = 14 ; Main revision of the firmware -.EQU EEPROM_FW_SUB_REVISION = 9 ; Sub revision of the firmware -.EQU EEPROM_LAYOUT_REVISION = 21 ; 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 0xFF -_Eep_Pgm_Motor_Idle: .DB 0xFF -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: .DB DEFAULT_PGM_MAIN_DIRECTION ; 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 0xA5 ; EEPROM initialized signature low byte -Eep_Initialized_H: .DB 0x5A ; 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 0xFF -_Eep_Pgm_Startup_Accel: .DB 0xFF -_Eep_Pgm_Volt_Comp: .DB 0xFF -Eep_Pgm_Comm_Timing: .DB DEFAULT_PGM_MAIN_COMM_TIMING ; EEPROM copy of programmed commutation timing -_Eep_Pgm_Damping_Force: .DB 0xFF -Eep_Pgm_Gov_Range: .DB DEFAULT_PGM_MAIN_GOVERNOR_RANGE ; EEPROM copy of programmed governor range -_Eep_Pgm_Startup_Method: .DB 0xFF -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 0xFF -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 -_Eep_Pgm_Ppm_Center_Throttle: .DB 0xFF -Eep_Pgm_Main_Spoolup_Time: .DB DEFAULT_PGM_MAIN_SPOOLUP_TIME ; EEPROM copy of programmed main spoolup time -Eep_Pgm_Temp_Prot_Enable: .DB DEFAULT_PGM_ENABLE_TEMP_PROT ; EEPROM copy of programmed temperature protection enable -Eep_Pgm_Enable_Power_Prot: .DB DEFAULT_PGM_ENABLE_POWER_PROT ; EEPROM copy of programmed low rpm power protection enable -Eep_Pgm_Enable_Pwm_Input: .DB DEFAULT_PGM_ENABLE_PWM_INPUT ; EEPROM copy of programmed PWM input signal enable -_Eep_Pgm_Pwm_Dither: .DB 0xFF -Eep_Pgm_Brake_On_Stop: .DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero -.ENDIF - -.IF MODE == 1 -_Eep_Pgm_Gov_P_Gain: .DB 0xFF -_Eep_Pgm_Gov_I_Gain: .DB 0xFF -_Eep_Pgm_Gov_Mode: .DB 0xFF -_Eep_Pgm_Low_Voltage_Lim: .DB 0xFF -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: .DB DEFAULT_PGM_TAIL_DIRECTION ; 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 0x5A ; EEPROM initialized signature low byte -Eep_Initialized_H: .DB 0xA5 ; EEPROM initialized signature high byte -Eep_Enable_TX_Program: .DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable -_Eep_Main_Rearm_Start: .DB 0xFF -_Eep_Pgm_Gov_Setup_Target: .DB 0xFF -_Eep_Pgm_Startup_Rpm: .DB 0xFF -_Eep_Pgm_Startup_Accel: .DB 0xFF -_Eep_Pgm_Volt_Comp: .DB 0xFF -Eep_Pgm_Comm_Timing: .DB DEFAULT_PGM_TAIL_COMM_TIMING ; EEPROM copy of programmed commutation timing -_Eep_Pgm_Damping_Force: .DB 0xFF -_Eep_Pgm_Gov_Range: .DB 0xFF -_Eep_Pgm_Startup_Method: .DB 0xFF -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 0xFF -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 -Eep_Pgm_Ppm_Center_Throttle: .DB DEFAULT_PGM_PPM_CENTER_THROTTLE ; EEPROM copy of programmed center throttle (final value is 4x+1000=1488) -_Eep_Pgm_Main_Spoolup_Time: .DB 0xFF -Eep_Pgm_Temp_Prot_Enable: .DB DEFAULT_PGM_ENABLE_TEMP_PROT ; EEPROM copy of programmed temperature protection enable -Eep_Pgm_Enable_Power_Prot: .DB DEFAULT_PGM_ENABLE_POWER_PROT ; EEPROM copy of programmed low rpm power protection enable -Eep_Pgm_Enable_Pwm_Input: .DB DEFAULT_PGM_ENABLE_PWM_INPUT ; EEPROM copy of programmed PWM input signal enable -Eep_Pgm_Pwm_Dither: .DB DEFAULT_PGM_TAIL_PWM_DITHER ; EEPROM copy of programmed output PWM dither -Eep_Pgm_Brake_On_Stop: .DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero -.ENDIF - -.IF MODE == 2 -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 0xFF -Eep_Pgm_Motor_Gain: .DB DEFAULT_PGM_MULTI_GAIN ; EEPROM copy of programmed tail gain -_Eep_Pgm_Motor_Idle: .DB 0xFF ; 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: .DB DEFAULT_PGM_MULTI_DIRECTION ; 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 0x55 ; EEPROM initialized signature low byte -Eep_Initialized_H: .DB 0xAA ; EEPROM initialized signature high byte -Eep_Enable_TX_Program: .DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable -_Eep_Main_Rearm_Start: .DB 0xFF -_Eep_Pgm_Gov_Setup_Target: .DB 0xFF -_Eep_Pgm_Startup_Rpm: .DB 0xFF -_Eep_Pgm_Startup_Accel: .DB 0xFF -_Eep_Pgm_Volt_Comp: .DB 0xFF -Eep_Pgm_Comm_Timing: .DB DEFAULT_PGM_MULTI_COMM_TIMING ; EEPROM copy of programmed commutation timing -_Eep_Pgm_Damping_Force: .DB 0xFF -_Eep_Pgm_Gov_Range: .DB 0xFF -_Eep_Pgm_Startup_Method: .DB 0xFF -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 0xFF -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 -Eep_Pgm_Ppm_Center_Throttle: .DB DEFAULT_PGM_PPM_CENTER_THROTTLE ; EEPROM copy of programmed center throttle (final value is 4x+1000=1488) -_Eep_Pgm_Main_Spoolup_Time: .DB 0xFF -Eep_Pgm_Temp_Prot_Enable: .DB DEFAULT_PGM_ENABLE_TEMP_PROT ; EEPROM copy of programmed temperature protection enable -Eep_Pgm_Enable_Power_Prot: .DB DEFAULT_PGM_ENABLE_POWER_PROT ; EEPROM copy of programmed low rpm power protection enable -Eep_Pgm_Enable_Pwm_Input: .DB DEFAULT_PGM_ENABLE_PWM_INPUT ; EEPROM copy of programmed PWM input signal enable -Eep_Pgm_Pwm_Dither: .DB DEFAULT_PGM_MULTI_PWM_DITHER ; EEPROM copy of programmed output PWM dither -Eep_Pgm_Brake_On_Stop: .DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero -.ENDIF - - -Eep_Dummy: .DB 0xFF ; EEPROM address for safety reason - -.ORG 0x60 -Eep_Name: .DB " " ; Name tag (16 Bytes) - -;**** **** **** **** **** -.CSEG ; Code segment -.ORG 0 - -Interrupt_Table_Definition ; ATmega interrupts - -;**** **** **** **** **** - -; Table definitions -GOV_GAIN_TABLE: .DB 0x02, 0x03, 0x04, 0x06, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40, 0x60, 0x80, 0 ; Padded zero for an even number -STARTUP_POWER_TABLE: .DB 0x04, 0x06, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0 ; Padded zero for an even number -PWM_DITHER_TABLE: .DB 0x00, 0x03, 0x07, 0x0F, 0x1F, 0 ; Padded zero for an even number -.IF MODE == 0 - .IF DAMPED_MODE_ENABLE == 1 -TX_PGM_PARAMS_MAIN: .DB 13, 13, 4, 3, 6, 13, 5, 3, 3, 2, 2, 0 ; Padded zero for an even number - .ENDIF - .IF DAMPED_MODE_ENABLE == 0 -TX_PGM_PARAMS_MAIN: .DB 13, 13, 4, 3, 6, 13, 5, 2, 3, 2, 2, 0 ; Padded zero for an even number - .ENDIF -.ENDIF -.IF MODE == 1 - .IF DAMPED_MODE_ENABLE == 1 -TX_PGM_PARAMS_TAIL: .DB 5, 5, 13, 5, 3, 5, 3, 3, 2, 0 ; Padded zero for an even number - .ENDIF - .IF DAMPED_MODE_ENABLE == 0 -TX_PGM_PARAMS_TAIL: .DB 5, 5, 13, 5, 2, 5, 3, 3, 2, 0 ; Padded zero for an even number - .ENDIF -.ENDIF -.IF MODE == 2 - .IF DAMPED_MODE_ENABLE == 1 -TX_PGM_PARAMS_MULTI: .DB 13, 13, 4, 5, 13, 5, 3, 5, 3, 3, 2, 0 ; Padded zero for an even number - .ENDIF - .IF DAMPED_MODE_ENABLE == 0 -TX_PGM_PARAMS_MULTI: .DB 13, 13, 4, 5, 13, 5, 2, 5, 3, 3, 2, 0 ; Padded zero for an even number - .ENDIF -.ENDIF - - - -;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Timer2 interrupt routine -; -; Assumptions: Z register must be set to desired pwm_nfet_on label -; Requirements: I_Temp variables can NOT be used -; -;**** **** **** **** **** **** **** **** **** **** **** **** **** -t2_int: ; Used for pwm control - in II_Sreg, SREG - ; Check if pwm is on - sbrc Flags0, PWM_ON ; Is pwm on? - rjmp t2_int_pwm_off - - ; Pwm on cycle - tst Current_Pwm_Limited - breq t2_int_pwm_on_ret - - ijmp ; Jump to pwm on routines. Z should be set to one of the pwm_nfet_on labels - -t2_int_pwm_on_exit: - ; Set timer for coming on cycle length - mov YL, Current_Pwm_Limited ; Load current pwm - com YL ; com is 255-x - sec - sbrc Flags2, PGM_PWM_HIGH_FREQ ; Use half the time when pwm frequency is high - ror YL - Set_TCNT2 YL ; Write start point for timer - ; Set other variables - sbr Flags0, (1<= 128 ; "Negative", 1's complement - sbrc Flags1, SKIP_DAMP_ON - rjmp t2_int_pwm_off_damp_done - sbrc Flags0, DEMAG_CUT_POWER - rjmp t2_int_pwm_off_damp_done - Damping_FET_on YL ; Damping fet on - ldi YL, PFETON_DELAY - com YL - dec YL - brne PC-1 -t2_int_pwm_off_damp_done: - All_nFETs_Off ; Switch off all nfets -.ENDIF -t2_int_pwm_off_exit: - out SREG, II_Sreg - reti - -t2_int_pwm_off_fullpower_exit: - Set_TCNT2 Zero ; Write start point for timer - T2_Clear_Int_Flag YL ; Clear interrupt flag - sbr Flags0, (1<= 1 ; Tail or multi - ; Boost pwm during direct start - mov XL, Flags1 - andi XL, ((1<= 1 ; Tail or multi - ; Set current_pwm_limited - lds I_Temp1, Current_Pwm ; Default not limited - lds XL, Pwm_Limit ; Check against limit - cp I_Temp1, XL - brcs PC+2 ; If current pwm below limit - branch - - mov I_Temp1, XL ; Limit pwm - -.IF MODE == 2 ; Multi - ; Limit pwm for low rpms - lds XL, Pwm_Limit_By_Rpm ; Check against limit - cp I_Temp1, XL - brcs PC+2 ; If current pwm below limit - branch - - mov I_Temp1, XL ; Limit pwm -.ENDIF - - mov Current_Pwm_Limited, I_Temp1 - ; Dither - lds XL, Pwm_Dither_Decoded ; Load pwm dither - tst XL - brne PC+2 ; If active - branch - rjmp t0_int_current_pwm_no_dither - - mov I_Temp2, I_Temp1 - sub I_Temp2, XL ; Calculate pwm minus dither value - brcc t0_int_current_pwm_full_dither; If pwm more than dither value, then do full dither - - mov XL, I_Temp1 ; Set dither level to current pwm - ldi I_Temp2, 0 ; Set pwm minus dither - -t0_int_current_pwm_full_dither: - mov I_Temp4, XL ; Store dither value in I_Temp4 - clc - rol XL ; Shift left once - mov I_Temp3, XL - lds XL, Random ; Load random number - com XL ; Invert to create proper DC bias in random code - and I_Temp3, XL ; And with double dither value - add I_Temp3, I_Temp2 ; Add pwm minus dither - brcs t0_int_current_pwm_dither_max_excess_power ; If dither cause power above max - branch and increase excess - - lds XL, Pwm_Dither_Excess_Power ; Get excess power - cp XL, Zero ; Decrement excess power - breq PC+2 - dec XL - add I_Temp3, XL ; Add excess power from previous cycles - sts Pwm_Dither_Excess_Power, XL - brcs t0_int_current_pwm_dither_max_power; If dither cause power above max - branch - - mov I_Temp1, I_Temp3 - rjmp t0_int_current_pwm_no_dither - -t0_int_current_pwm_dither_max_excess_power: - lds XL, Pwm_Dither_Excess_Power - cp I_Temp4, XL ; Limit excess power to one above in order to always reach max power - brcs PC+2 - inc XL - sts Pwm_Dither_Excess_Power, XL - -t0_int_current_pwm_dither_max_power: - ldi I_Temp1, 255 ; Set power to max - -t0_int_current_pwm_no_dither: - sts Current_Pwm_Lim_Dith, I_Temp1 -.IF DAMPED_MODE_ENABLE == 1 - ; Skip damping fet switching for high throttle - cbr Flags1, (1<= 1 ; Tail or multi - cpi I_Temp2, 3 - brne PC+3 ; No - branch - - lds I_Temp3, Pgm_Ppm_Center_Throttle ; Center throttle value is in 4us units - -.ENDIF -rcp_int_ppm_calculate: - ldi XL, 250 ; Add 1000us to minimum - add I_Temp3, XL - mov XL, Zero - adc XL, Zero - sub I_Temp5, I_Temp3 ; Subtract minimum - sbc I_Temp6, XL - in I_Temp1, SREG - andi I_Temp1, (1<= 1 ; Tail or multi - cpi I_Temp2, 3 ; Check if bidirectional operation - brne rcp_int_ppm_bidir_dir_set ; No - branch - - tst I_Temp1 - breq rcp_int_ppm_bidir_fwd ; If result is positive - branch - - sbrc Flags2, RCP_DIR_REV - rjmp rcp_int_ppm_bidir_dir_set ; If same direction - branch - - sbr Flags2, (1<= 1 ; Tail or multi - cpi I_Temp2, 3 ; Check if bidirectional operation - brne rcp_int_ppm_unidir_neg ; No - branch - - ldi XL, 0xFF ; Change sign - invert and subtract minus one - com I_Temp5 - com I_Temp6 - sub I_Temp5, XL - sbc I_Temp6, XL - rjmp rcp_int_ppm_neg_checked - -rcp_int_ppm_unidir_neg: -.ENDIF - ldi I_Temp1, RCP_MIN ; Yes - set to minimum - ldi I_Temp2, 0 - rjmp rcp_int_pwm_divide_done - -rcp_int_ppm_neg_checked: -.IF MODE >= 1 ; Tail or multi - cpi I_Temp2, 3 ; Check if bidirectional operation - brne rcp_int_ppm_bidir_done ; No - branch - - lsl I_Temp5 ; Multiply value by 2 - rol I_Temp6 - ldi XL, 10 ; Subtract deadband - sub I_Temp5, XL - sbc I_Temp6, Zero - brcc rcp_int_ppm_bidir_done - - ldi XL, RCP_MIN - mov I_Temp5, XL - mov I_Temp6, Zero - -rcp_int_ppm_bidir_done: -.ENDIF - ldi XL, RCP_MAX ; Check that RC pulse is within legal range (max 255) - cp I_Temp5, XL - cpc I_Temp6, Zero - brcs rcp_int_ppm_max_checked - - ldi I_Temp1, RCP_MAX - ldi I_Temp2, 0 - rjmp rcp_int_pwm_divide_done - -rcp_int_ppm_max_checked: - lds XL, Ppm_Throttle_Gain ; Multiply throttle value by gain - mul I_Temp5, XL - mov I_Temp1, Mul_Res_H ; Transfer result - lsl Mul_Res_L ; Multiply result by 2 (unity gain is 128) - rol I_Temp1 - ldi I_Temp2, 0 - brcs rcp_int_ppm_limit_after_mult - - rjmp rcp_int_limited - -rcp_int_ppm_limit_after_mult: - ldi I_Temp1, RCP_MAX - ldi I_Temp2, 0 - rjmp rcp_int_limited - -rcp_int_pwm_divide: - lsr I_Temp2 ; Divide by 2 - ror I_Temp1 - -rcp_int_pwm_divide_done: - sbrs Flags3, RCP_PWM_FREQ_12KHZ ; Is RC input pwm frequency 12kHz? - rjmp rcp_int_check_legal_range - - tst I_Temp2 ; Yes - check that value is not more than 255 - breq PC+2 - - ldi I_Temp1, RCP_MAX - - mov XL, I_Temp1 ; Multiply by 1.5 - lsr XL - add I_Temp1, XL - adc I_Temp2, Zero - -rcp_int_check_legal_range: - ; Check that RC pulse is within legal range - cpi I_Temp1, RCP_MAX - cpc I_Temp2, Zero - brcs rcp_int_limited - - ldi I_Temp1, RCP_MAX - -rcp_int_limited: - ; RC pulse value accepted - sts New_Rcp, I_Temp1 ; Store new pulse length - sbr Flags2, (1<= 1 ; Tail or multi - ; If not supported, then exit - rjmp measure_lipo_exit -.ENDIF -.IF MODE == 0 ; Main - ; Set commutation to BpFET on - xcall comm5comm6 - ; Start adc - Start_Adc XH - ; Wait for ADC reference to settle, and then start again - xcall wait1ms - Start_Adc XH - ; Wait for ADC conversion to complete -measure_lipo_wait_adc: - Get_Adc_Status XH - sbrc XH, ADSC - rjmp measure_lipo_wait_adc - ; Read ADC result - Read_Adc_Result Temp1, Temp2 - ; Stop ADC - Stop_Adc XH - ; Switch power off - xcall switch_power_off - ; Set limit step - ldi Temp3, ADC_LIMIT_L - sts Lipo_Adc_Limit_L, Temp3 - tst Temp3 - brne PC+2 - rjmp measure_lipo_exit ; Exit if disabled - - ldi Temp4, ADC_LIMIT_H - sts Lipo_Adc_Limit_H, Temp4 - mov Temp6, Temp4 ; Divide 3.0V value by 2 - lsr Temp6 - mov Temp5, Temp3 - lsr Temp5 - add Temp5, Temp3 ; Calculate 1.5*3.0V=4.5V value - adc Temp6, Temp4 - mov Temp3, Temp5 ; Copy step - mov Temp4, Temp6 -measure_lipo_cell_loop: - ; Check voltage against xS lower limit - cp Temp1, Temp3 ; Voltage above limit? - cpc Temp2, Temp4 - brcs measure_lipo_adjust ; No - branch - - ; Set xS voltage limit - lds Temp7, Lipo_Adc_Limit_L - ldi XH, ADC_LIMIT_L - add XH, Temp7 - sts Lipo_Adc_Limit_L, XH - lds Temp7, Lipo_Adc_Limit_H - ldi XH, ADC_LIMIT_H - adc XH, Temp7 - sts Lipo_Adc_Limit_H, XH - ; Set (x+1)S lower limit - add Temp3, Temp5 ; Add step - adc Temp4, Temp6 - rjmp measure_lipo_cell_loop ; Check for one more battery cell - -measure_lipo_adjust: - lds Temp7, Lipo_Adc_Limit_L - lds Temp8, Lipo_Adc_Limit_H - ; Calculate 3.125% - lds Temp2, Lipo_Adc_Limit_H - lsr Temp2 - lds Temp1, Lipo_Adc_Limit_L - ror Temp1 ; After this 50% - lsr Temp2 - ror Temp1 ; After this 25% - ; Divide three times to get to 3.125% - ldi Temp3, 3 -measure_lipo_divide_loop: - lsr Temp2 - ror Temp1 - dec Temp3 - brne measure_lipo_divide_loop - - ; Add the programmed number of 0.1V (or 3.125% increments) - lds Temp3, Pgm_Low_Voltage_Lim ; Load programmed limit - dec Temp3 - brne measure_lipo_limit_on ; Is low voltage limiting on? - - sts Lipo_Adc_Limit_L, Zero ; No - set limit to zero - sts Lipo_Adc_Limit_H, Zero - rjmp measure_lipo_exit - -measure_lipo_limit_on: - dec Temp3 - breq measure_lipo_update - -measure_lipo_add_loop: - add Temp7, Temp1 ; Add 3.125% - adc Temp8, Temp2 - dec Temp3 - brne measure_lipo_add_loop - -measure_lipo_update: - ; Set ADC limit - sts Lipo_Adc_Limit_L, Temp7 - sts Lipo_Adc_Limit_H, Temp8 -.ENDIF -measure_lipo_exit: - 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 - lds Temp3, Pgm_Low_Voltage_Lim ; Store in Temp3 - ; Wait for ADC conversion to complete - Get_Adc_Status XH - sbrc XH, ADSC - rjmp check_temp_voltage_and_limit_power - ; Read ADC result - Read_Adc_Result Temp1, Temp2 - ; Stop ADC - Stop_Adc XH - lds XH, Adc_Conversion_Cnt ; Increment conversion counter - inc XH - sts Adc_Conversion_Cnt, XH - cpi XH, TEMP_CHECK_RATE ; Is conversion count equal to temp rate? - brcs check_voltage_start ; No - check voltage - - sts Adc_Conversion_Cnt, Zero ; Yes - temperature check. Reset counter - lds XH, Pgm_Enable_Temp_Prot ; Is temp protection enabled? - tst XH - breq temp_check_exit ; No - branch - - tst Temp2 ; Is temperature ADC reading below 256? - breq temp_average_inc_dec ; Yes - proceed - - lds XH, Current_Average_Temp_Adc ; No - increment average - cpi XH, 0xFF - breq temp_average_updated ; Already max - no change - rjmp temp_average_inc ; Increment - -temp_average_inc_dec: - lds XH, Current_Average_Temp_Adc ; Check if current temp ADC is above or below average - cp Temp1, XH - breq temp_average_updated ; Equal - no change - - brcc temp_average_inc ; Above - increment average - - tst XH ; Below - decrement average if average is not already zero - breq temp_average_updated -temp_average_dec: - dec XH ; Decrement average - rjmp temp_average_updated - -temp_average_inc: - inc XH ; Increment average - breq temp_average_dec - -temp_average_updated: - lds Temp1, Pwm_Limit - sts Current_Average_Temp_Adc, XH - cpi XH, TEMP_LIMIT ; Is temp ADC above first limit? - brcc temp_check_set_limit ; Yes - exit - - ldi Temp1, 192 ; No - limit pwm - - cpi XH, (TEMP_LIMIT-TEMP_LIMIT_STEP) ; Is temp ADC above second limit - brcc temp_check_set_limit ; Yes - exit - - ldi Temp1, 128 ; No - limit pwm - - cpi XH, (TEMP_LIMIT-2*TEMP_LIMIT_STEP) ; Is temp ADC above third limit - brcc temp_check_set_limit ; Yes - exit - - ldi Temp1, 64 ; No - limit pwm - - cpi XH, (TEMP_LIMIT-3*TEMP_LIMIT_STEP) ; Is temp ADC above final limit - brcc temp_check_set_limit ; Yes - exit - - ldi Temp1, 0 ; No - limit pwm - -temp_check_set_limit: - sts Pwm_Limit, Temp1 ; Set pwm limit -temp_check_exit: - Set_Adc_Ip_Volt ; Select adc input for next conversion - ret - -check_voltage_start: -.IF MODE == 0 ; Main - ; Check if low voltage limiting is enabled - cpi Temp3, 1 ; Is low voltage limit disabled? - breq check_voltage_good ; Yes - voltage declared good - - ; Check if ADC is saturated - cpi Temp1, 0xFF - ldi XH, 3 - cpc Temp2, XH - brcc check_voltage_good ; ADC saturated, can not make judgement - - ldi XH, ADC_LIMIT_L ; Is low voltage limit zero (ESC does not support it)? - tst XH - breq check_voltage_good ; Yes - voltage declared good - - ; Check voltage against limit - lds XH, Lipo_Adc_Limit_L - cp Temp1, XH - lds XH, Lipo_Adc_Limit_H - cpc Temp2, XH - brcc check_voltage_good ; If voltage above limit - branch - - ; Decrease pwm limit - lds XH, Pwm_Limit - tst XH - breq check_voltage_lim ; If limit zero - branch - - dec XH ; Decrement limit - sts Pwm_Limit, XH - rjmp check_voltage_lim - -check_voltage_good: - ; Increase pwm limit - lds XH, Pwm_Limit - cpi XH, 0xFF - breq check_voltage_lim ; If limit max - branch - - inc XH ; Increment limit - sts Pwm_Limit, XH - -check_voltage_lim: - lds Temp1, Pwm_Limit ; Set limit - lds XH, Current_Pwm - sub XH, Temp1 - brcc check_voltage_spoolup_lim ; If current pwm above limit - branch and limit - - lds Temp1, Current_Pwm ; Set current pwm (no limiting) - -check_voltage_spoolup_lim: - ; Slow spoolup - lds XH, Pwm_Limit_Spoolup - cp Temp1, XH - brcs check_voltage_exit ; If current pwm below limit - branch - - lds Temp1, Pwm_Limit_Spoolup - lds XH, Pwm_Limit_Spoolup ; Check if spoolup limit is max - cpi XH, 0xFF - breq check_voltage_exit ; If max - branch - - lds XH, Pwm_Limit_Spoolup ; Set pwm limit to spoolup limit during ramp (to avoid governor integral buildup) - sts Pwm_Limit, XH - -check_voltage_exit: - mov Current_Pwm_Limited, Temp1 - sts Current_Pwm_Lim_Dith, Temp1 -.ENDIF -.IF MODE == 1 ; Tail - ; Increase pwm limit - lds XH, Pwm_Limit - inc XH - breq check_voltage_lim ; If limit max - branch - - sts Pwm_Limit, XH ; Increment limit - -check_voltage_lim: -.ENDIF -.IF MODE == 2 ; Multi - ; Increase pwm limit - lds Temp2, Pwm_Limit - ldi XH, 16 - add Temp2, XH - brcc PC+2 ; If not max - branch - - ldi Temp2, 255 - - sts Pwm_Limit, Temp2 ; Increment limit - ; Set current pwm limited if closed loop mode - lds XH, Pgm_Gov_Mode ; Governor mode? - cpi XH, 4 - breq check_voltage_pwm_done ; No - branch - - lds Temp1, Pwm_Limit ; Set limit - lds XH, Current_Pwm - sub XH, Temp1 - brcc check_voltage_low_rpm ; If current pwm above limit - branch and limit - - lds Temp1, Current_Pwm ; Set current pwm (no limiting) - -check_voltage_low_rpm: - ; Limit pwm for low rpms - lds XH, Pwm_Limit_By_Rpm ; Check against limit - cp Temp1, XH - brcs PC+2 ; If current pwm below limit - branch - - mov Temp1, XH ; Limit pwm - - mov Current_Pwm_Limited, Temp1 - sts Current_Pwm_Lim_Dith, Temp1 -check_voltage_pwm_done: -.ENDIF - ; Set adc mux for next conversion - lds XH, Adc_Conversion_Cnt ; Is next conversion for temperature? - cpi XH, (TEMP_CHECK_RATE-1) - brne check_voltage_ret - - Set_Adc_Ip_Temp ; Select temp sensor for next conversion - -check_voltage_ret: - ret - - -;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Set startup PWM routine -; -; No assumptions -; -; Used for pwm control during startup -; -;**** **** **** **** **** **** **** **** **** **** **** **** **** -set_startup_pwm: - ; Adjust startup power - ldi Temp1, PWM_START ; Set power - cli ; Disable interrupts in order to avoid interference with mul ops in interrupt routines - lds XH, Pgm_Startup_Pwr_Decoded ; Multiply startup power by programmed value - mul Temp1, XH - mov Temp1, Mul_Res_H ; Transfer result - lsl Mul_Res_L ; Multiply result by 2 (unity gain is 128) - rol Temp1 - sei - lds XH, Pwm_Limit ; Check against limit - cp Temp1, XH - brcs startup_pwm_set_pwm ; If pwm below limit - branch - - lds Temp1, Pwm_Limit ; Limit pwm - -startup_pwm_set_pwm: - ; Set pwm variables - sts Requested_Pwm, Temp1 ; Update requested pwm - sts Current_Pwm, Temp1 ; Update current pwm - mov Current_Pwm_Limited, Temp1 ; Update limited version of current pwm - sts Current_Pwm_Lim_Dith, Temp1 - sts Pwm_Spoolup_Beg, Temp1 ; Update spoolup beginning pwm - ret - - -;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Initialize timing routine -; -; No assumptions -; -; Part of initialization before motor start -; -;**** **** **** **** **** **** **** **** **** **** **** **** **** -initialize_timing: - sts Comm_Period4x_L, Zero ; Set commutation period registers - ldi XH, 0xF0 - sts Comm_Period4x_H, XH - ret - - -;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Calculate next commutation timing routine -; -; No assumptions -; -; Called immediately after each commutation -; Also sets up timer 1 to wait advance timing -; -;**** **** **** **** **** **** **** **** **** **** **** **** **** -calc_next_comm_timing: ; Entry point for run phase - ; Read commutation time - cli ; Disable interrupts while reading timer 1 - Read_TCNT1L Temp1 - Read_TCNT1H Temp2 - lds Temp3, Timer2_X - sei - ; Calculate this commutation time - lds Temp4, Prev_Comm_L - lds Temp5, Prev_Comm_H - sts Prev_Comm_L, Temp1 ; Store timestamp as previous commutation - sts Prev_Comm_H, Temp2 - sub Temp1, Temp4 ; Calculate the new commutation time - sbc Temp2, Temp5 - sbrc Flags1, STARTUP_PHASE - rjmp calc_next_comm_startup - - sbrc Flags1, HIGH_RPM ; Branch if high rpm - rjmp calc_next_comm_timing_fast - - rjmp calc_next_comm_normal - -calc_next_comm_startup: - lds Temp6, Prev_Comm_X - sts Prev_Comm_X, Temp3 ; Store extended timestamp as previous commutation - sbc Temp3, Temp6 ; Calculate the new extended commutation time - tst Temp3 - breq calc_next_comm_startup_no_X - - ldi Temp1, 0xFF - ldi Temp2, 0xFF -rjmp calc_next_comm_startup_average - -calc_next_comm_startup_no_X: - lds Temp7, Prev_Prev_Comm_L - lds Temp8, Prev_Prev_Comm_H - sts Prev_Prev_Comm_L, Temp4 - sts Prev_Prev_Comm_H, Temp5 - lds Temp1, Prev_Comm_L ; Reload this commutation time - lds Temp2, Prev_Comm_H - sub Temp1, Temp7 ; Calculate the new commutation time based upon the two last commutations (to reduce sensitivity to offset) - sbc Temp2, Temp8 - -calc_next_comm_startup_average: - lds Temp3, Comm_Period4x_L ; Average with previous and save - lds Temp4, Comm_Period4x_H - lsr Temp4 - ror Temp3 - add Temp1, Temp3 - adc Temp2, Temp4 - brcc PC+3 - - ldi Temp1, 0xFF - ldi Temp2, 0xFF - - sts Comm_Period4x_L, Temp1 - sts Comm_Period4x_H, Temp2 - rjmp calc_new_wait_times_setup - -calc_next_comm_normal: - ; Calculate new commutation time - lds Temp3, Comm_Period4x_L ; Comm_Period4x(-l-h) holds the time of 4 commutations - lds Temp4, Comm_Period4x_H - movw Temp5, Temp3 ; Copy variables - ldi XH, 4 ; Divide Comm_Period4x 4 times as default - mov Temp7, XH - ldi XH, 2 ; Divide new commutation time 2 times as default - mov Temp8, XH - cpi Temp4, 0x04 - brcs calc_next_comm_avg_period_div - - dec Temp7 ; Reduce averaging time constant for low speeds - dec Temp8 - - cpi Temp4, 0x08 - brcs calc_next_comm_avg_period_div - - sbrc Flags1, INITIAL_RUN_PHASE - rjmp calc_next_comm_avg_period_div ; Do not average very fast during initial run - - dec Temp7 ; Reduce averaging time constant more for even lower speeds - dec Temp8 - -calc_next_comm_avg_period_div: - lsr Temp6 ; Divide by 2 - ror Temp5 - dec Temp7 - brne calc_next_comm_avg_period_div - - sub Temp3, Temp5 ; Subtract a fraction - sbc Temp4, Temp6 - - tst Temp8 ; Divide new time - breq calc_next_comm_new_period_div_done - -calc_next_comm_new_period_div: - lsr Temp2 ; Divide by 2 - ror Temp1 - dec Temp8 - brne calc_next_comm_new_period_div - -calc_next_comm_new_period_div_done: - add Temp3, Temp1 ; Add the divided new time - adc Temp4, Temp2 - sts Comm_Period4x_L, Temp3 ; Store Comm_Period4x_X - sts Comm_Period4x_H, Temp4 - brcc calc_new_wait_times_setup; If period larger than 0xffff - go to slow case - - ldi Temp4, 0xFF - sts Comm_Period4x_L, Temp4 ; Set commutation period registers to very slow timing (0xffff) - sts Comm_Period4x_H, Temp4 - -calc_new_wait_times_setup: - ; Set high rpm bit (if above 156k erpm) - cpi Temp4, 2 - brcc PC+2 - - sbr Flags1, (1<35) causes the RCT4215 630 to run rough on full throttle - lds Temp1, Comm_Period4x_H ; Set number of readings higher for lower speeds - lsr Temp1 - brne PC+2 - inc Temp1 - cpi Temp1, 15 - brcs PC+2 - - ldi Temp1, 15 - - sbrs Flags1, STARTUP_PHASE ; Branch if not startup - rjmp comp_check_timeout - - ldi Temp1, 20 ; Set many samples during startup, approximately one pwm period - ldi Temp2, 20 - -comp_check_timeout: - sbrc Flags0, OC1A_PENDING ; Has zero cross scan timeout elapsed? - rjmp comp_check_timeout_not_timed_out - - lds XH, Comparator_Read_Cnt ; Check that comparator has been read - tst XH - breq comp_check_timeout_not_timed_out ; If not read - branch - - sbrs Flags1, STARTUP_PHASE ; Extend timeout during startup - rjmp comp_check_timeout_timeout_extended - - lds XH, Startup_Zc_Timeout_Cntd - dec XH - sts Startup_Zc_Timeout_Cntd, XH - brne comp_check_timeout_extend_timeout - -comp_check_timeout_timeout_extended: - sbr Flags1, (1<= 1 ; Tail or multi - cpi XH, 3 - breq decode_params_dir_set -.ENDIF - - cbr Flags3, (1<= 1 ; Tail or multi - lds XH, Pgm_Direction ; Check if bidirectional operation - cpi XH, 3 - brne PC+2 - - rjmp program_by_tx_checked ; Disable tx programming if bidirectional operation -.ENDIF - - xcall wait3ms - lds XH, Pgm_Enable_TX_Program; Start programming mode entry if enabled - cpi XH, 1 ; Is TX programming enabled? - brcc arming_initial_arm_check ; Yes - proceed - - rjmp program_by_tx_checked ; No - branch - -arming_initial_arm_check: - lds XH, Initial_Arm ; Yes - check if it is initial arm sequence - cpi XH, 1 ; Is it the initial arm sequence? - brcc arming_ppm_check ; Yes - proceed - - rjmp program_by_tx_checked ; No - branch - -arming_ppm_check: - sbrc Flags2, RCP_PPM - rjmp throttle_high_cal_start ; If flag is set (PPM) - branch - - ; PWM tx program entry - lds XH, New_Rcp ; Load new RC pulse value - cpi XH, RCP_MAX ; Is RC pulse max? - brcc program_by_tx_entry_pwm ; Yes - proceed - - rjmp program_by_tx_checked ; No - branch - -program_by_tx_entry_pwm: - cli ; Disable all interrupts - xcall beep_f4 - sei ; Enable all interrupts - xcall wait100ms - lds XH, New_Rcp ; Load new RC pulse value - cpi XH, RCP_STOP ; Below stop? - brcc program_by_tx_entry_pwm ; No - start over - -program_by_tx_entry_wait_pwm: - cli ; Disable all interrupts - xcall beep_f1 - xcall wait10ms - xcall beep_f1 - sei ; Enable all interrupts - xcall wait100ms - lds XH, New_Rcp ; Load new RC pulse value - cpi XH, RCP_MAX ; At or above max? - brcs program_by_tx_entry_wait_pwm ; No - start over - - rjmp program_by_tx ; Yes - enter programming mode - - ; PPM throttle calibration and tx program entry -throttle_high_cal_start: -.IF MODE <= 1 ; Main or tail - ldi XH, 8 ; Set 3 seconds wait time -.ELSE - ldi XH, 3 ; Set 1 second wait time -.ENDIF - mov Temp8, XH -throttle_high_cal: - sbr Flags3, (1<= 1 ; Tail or multi - lds XH, Pgm_Direction ; Check if bidirectional operation - subi XH, 3 - breq wait_for_power_on_check_timeout ; Do not wait if bidirectional operation -.ENDIF - - xcall wait100ms ; Wait to see if start pulse was only a glitch - -wait_for_power_on_check_timeout: - lds XH, Rcp_Timeout_Cntd ; Load RC pulse timeout counter value - tst XH - brne PC+2 ; If it is not zero - proceed - - rjmp init_no_signal ; If it is zero (pulses missing) - go back to detect input signal - - - -;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Start entry point -; -;**** **** **** **** **** **** **** **** **** **** **** **** **** -init_start: - cli - xcall switch_power_off - sts Requested_Pwm, Zero ; Set requested pwm to zero - sts Governor_Req_Pwm, Zero ; Set governor requested pwm to zero - sts Current_Pwm, Zero ; Set current pwm to zero - mov Current_Pwm_Limited, Zero; Set limited current pwm to zero - sts Current_Pwm_Lim_Dith, Zero - sts Pwm_Dither_Excess_Power, Zero - sei - lds XH, Pgm_Motor_Idle ; Set idle pwm to programmed value - lsl XH - sts Pwm_Motor_Idle, XH - sts Gov_Target_L, Zero ; Set target to zero - sts Gov_Target_H, Zero - sts Gov_Integral_L, Zero ; Set integral to zero - sts Gov_Integral_H, Zero - sts Gov_Integral_X, Zero - sts Adc_Conversion_Cnt, Zero - ldi Flags0, 0 ; Clear flags0 - ldi Flags1, 0 ; Clear flags1 - sts Demag_Detected_Metric, Zero ; Clear demag metric - ;**** **** **** **** **** - ; Motor start beginning - ;**** **** **** **** **** - ldi XH, TEMP_CHECK_RATE ; Make sure a temp reading is done - sts Adc_Conversion_Cnt, XH - Set_Adc_Ip_Temp - xcall wait1ms - Start_Adc XH -read_initial_temp: - Get_Adc_Status XH - sbrc XH, ADSC - rjmp read_initial_temp - Read_Adc_Result Temp1, Temp2 ; Read initial temperature - Stop_Adc XH - tst Temp2 - breq PC+2 ; Is reading below 256? - - ldi Temp1, 0xFF ; No - set average temperature value to 255 - - sts Current_Average_Temp_Adc, Temp1 ; Set initial average temp ADC reading - xcall check_temp_voltage_and_limit_power - ldi XH, TEMP_CHECK_RATE ; Make sure a temp reading is done next time - sts Adc_Conversion_Cnt, XH - Set_Adc_Ip_Temp - ; Set up start operating conditions - xcall decode_parameters ; (Decode_parameters uses Temp1 and Temp8) - ; Set max allowed power - cli ; Disable interrupts to avoid that Requested_Pwm is overwritten - ldi XH, 0xFF ; Set pwm limit to max - sts Pwm_Limit, XH - xcall set_startup_pwm - lds XH, Requested_Pwm - sts Pwm_Limit, XH - sts Pwm_Limit_Spoolup, XH - sts Pwm_Limit_By_Rpm, XH - sei - ldi XH, 1 ; Set low pwm again after calling set_startup_pwm - sts Requested_Pwm, XH - sts Current_Pwm, XH - mov Current_Pwm_Limited, XH - sts Current_Pwm_Lim_Dith, XH - sts Spoolup_Limit_Skip, XH - lds XH, Auto_Bailout_Armed - sts Spoolup_Limit_Cnt, XH - ; Begin startup sequence - lds XH, Pgm_Direction ; Check if bidirectional operation - cpi XH, 3 - brne init_start_bidir_done - - cbr Flags3, (1<= 1 ; Tail or multi - lds XH, Pgm_Direction ; Check if bidirectional operation - cpi XH, 3 - brne run6_check_speed - - sbrc Flags3, PGM_DIR_REV ; Check if actual rotation direction - rjmp run6_check_dir_rev - sbrc Flags2, RCP_DIR_REV ; Matches force direction - rjmp run6_check_dir_change - rjmp run6_check_speed - -run6_check_dir_rev: - sbrs Flags2, RCP_DIR_REV - rjmp run6_check_dir_change - rjmp run6_check_speed - -run6_check_dir_change: - sbrc Flags0, DIR_CHANGE_BRAKE - rjmp run6_check_speed - - sbr Flags0, (1<= 1 ; Tail or multi - sbrs Flags0, DIR_CHANGE_BRAKE ; If it is not a direction change - stop - rjmp run_to_wait_for_power_on - - cbr Flags0, (1<= 1 ; Tail or multi - sbrs Flags2, RCP_PPM - rjmp jmp_wait_for_power_on ; If flag is not set (PWM) - branch - - lds XH, Stall_Cnt - cpi XH, 4 - brcs jmp_wait_for_power_on - rjmp init_no_signal - -jmp_wait_for_power_on: - rjmp wait_for_power_on ; Go back to wait for power on -.ENDIF - -;**** **** **** **** **** **** **** **** **** **** **** **** **** - -.INCLUDE "BLHeliTxPgm.inc" ; Include source code for programming the ESC with the TX - -;**** **** **** **** **** **** **** **** **** **** **** **** **** - - -reset: -rjmp pgm_start - - - - -.EXIT +;**** **** **** **** **** +; +; BLHeli program for controlling brushless motors in helicopters and multirotors +; +; 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 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, 8kHz or 12kHz PWM (e.g. taken from the "resistor tap" on mCPx) +; And the input signal can be PPM (1-2ms) or OneShot125 (125-250us) at rates up to several hundred Hz. +; The code autodetects the various input modes/frequencies +; The code 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: +; - Rev0.0: Initial revision +; - Rev1.0: Governor functionality added +; - Rev1.1: Increased tail gain to 1.0625. Implemented for tail only +; Decreased governor proportional and integral gain by 4 +; Fixed bug that caused tail power not always to be max +; - Rev1.2: Governor integral gain should be higher in order to achieve full PWM range +; Integral gain can be higher, and is increased by 2x. An integral of +-128 can now be added to requested PWM +; - Rev1.3: Governor integral extended to 24bit +; Governor proportional gain increased by 2x +; Added slow spoolup/down for governor +; Set pwm to 100% (do not turn off nFET) for high values of current pwm +; Added support for PPM input (1us to 2us pulse) +; Removed USE_COMP_STORED as it was never used +; - Rev2.0 Added measurement of pwm frequency and support for 1kHz, 2kHz, 4kHz and 8kHz +; Optimized pwm on and off routines +; Improved mosfet switching in beep routines, to reduce current draw +; Added support for ICP1 interrupt pin input +; Added ADC measurement of supply voltage, with limiting of main motor power for low voltage +; Miscellaneous other changes +; - Rev2.1 Rewritten INT0 routine to be similar to ICP +; Reduced validation threshold (RCP_VALIDATE) +; Removed requirement for RCP to go to zero again in tail arming sequence +; Removed PPM support +; - Rev2.2 Added support for HC 5A 1S ESC with Atmega48V MPU +; Increased governor proportional gain by 2x +; - Rev3.0 Added functionality for programming from TX +; Added low voltage limit scaling for 2S and 3S +; - Rev11.2 Copied over from the SiLabs version and adapted to Atmel +; Now requiring a 16MHz capable MCU for fullspec performance +; - Rev12.0 Added programmable main spoolup time +; Added programmable temperature protection enable +; Bidirectional mode stop/start improved. Motor is now stopped before starting +; Power is limited for very low rpms (when BEMF is low), in order to avoid sync loss +; Damped light mode is made more smooth and quiet, particularly at low and high rpms +; Comparator signal qualification scheme is changed +; Demag compensation scheme is significantly changed +; Increased jitter tolerance for PPM frequency measurement +; Fully damped mode removed, and damped light only supported on damped capable ESCs +; Default tail mode changed to damped light +; Miscellaneous other changes +; - Rev12.1 Fixed bug in tail code +; Improved startup for Atmel +; Added support for multiple high BEC voltages +; Added support for RPM output +; - Rev12.2 Improved running smoothness, particularly for damped light +; Avoiding lockup at full throttle when input signal is noisy +; Avoiding detection of 1-wire programming signal as valid throttle signal +; - Rev13.0 Removed throttle change rate and damping force parameters +; Temperature protection default set to off +; Added support for OneShot125 +; Improved commutation timing accuracy +; - Rev13.1 Removed startup ramp for MULTI +; Improved startup for some odd ESCs +; - Rev13.2 Still tweaking startup to make it more reliable and faster for all ESC/motor combos +; Increased deadband for bidirectional operation +; Relaxed signal detection criteria +; Miscellaneous other changes +; - Rev14.0 Improved running at high RPMs and increased max RPM limit +; Improved reliability of 3D (bidirectional) mode and startup +; Avoid being locked in bootloader (implemented in Suite 13202) +; Smoother running and greatly reduced step to full power in damped light mode +; Removed low voltage limiting for MULTI +; Added pwm dither parameter +; Added setting for enable/disable of low RPM power protection +; Added setting for enable/disable of PWM input +; Better AFW and damping for some ESCs (that have a slow high side driver) +; Miscellaneous other changes +; - Rev14.1 Fixed max throttle calibration bug (for non-oneshot) +; Fixed some closed loop mode bugs +; Relaxed signal jitter requirement for looptimes below 1000 +; Added skipping of damping fet switching near max power, for improved high end throttle linearity, using the concept of SimonK +; Improved sync hold at high rpms +; - Rev14.2 Improved quality of comparator reading, giving better bemf detection (for improved startup amongst others) +; Removed mechanism where some ESCs could reset upon starting motor (due to ADC being read) +; Added stalled motor shutoff after about 10 seconds (for tail and multi code with PPM input) +; Greatly increased maximum rpm limit, and added rpm limiting at 250k erpm +; Improved bidirectional operation +; - Rev14.3 Moved reset vector to be just before the settings segment, in order to better recover from partially failed flashing operation +; Shortened stall detect time to about 5sec, and prevented going into tx programming after a stall +; Optimizations of software timing and running reliability +; - Rev14.4 Improved startup, particularly for larger motors +; Improved running at very high rpms +; Made damped light default for MULTI on ESCs that support it +; Miscellaneous other changes +; - Rev14.5 Longer between beacon beeps (to reduce motor heating), and now again beeping on two motor phases +; Implemented programmable brake on zero throttle +; Slightly modified throttle calibration +; Improved startup, particularly for small motors +; Improved smoothness +; - Rev14.6 Fixed bug that caused tail motor not to stop +; Fixed bug that caused brake not to work for low side pwm ESCs +; Fixed bug where noisy input signal could cause loss of sync +; Made low rpm power limiting programmable through the startup power parameter +; - Rev14.7 Beeps can be turned off by programming beep strength to 1 +; Throttle cal difference is checked to be above required minimum before storing. Throttle cal max is not stored until successful min throttle cal +; In order to have a good code for fixed wing planes, that has low voltage limiting, a main code spoolup time setting of 0 is made fast +; Some small changes for improved sync hold +; - Rev14.8 No change, just created to stay in sync with SiLabs code +; - Rev14.9 Improved bidirectional mode for high input signal rates +; +; +;**** **** **** **** **** +; 8K Bytes of In-System Self-Programmable Flash +; 1K Bytes Internal SRAM +; 512 Bytes Internal EEPROM +; 16MHz clock +; +;**** **** **** **** **** +; Timer 0 (500ns counts) always counts up and is used for +; - RC pulse timeout and skip counts +; Timer 1 (500ns counts) always counts up and is used for +; - RC pulse measurement (via external interrupt 0 or input capture pin) +; - Commutation timing (via output compare register A interrupt) +; Timer 2 (500ns counts) always counts up and is used for +; - PWM generation +; +;**** **** **** **** **** +; Interrupt handling +; The Atmega8 disables all interrupts when entering an interrupt routine, +; The code reenables interrupts in some interrupt routines, in order to nest pwm 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: +; There is a startup phase and an initial run phase, before normal bemf commutation run begins. +; +;**** **** **** **** **** +; Select the ESC and mode to use (or unselect all for use with external batch compile file); +;#define BLUESERIES_12A_MAIN +;#define BLUESERIES_12A_TAIL +;#define BLUESERIES_12A_MULTI +;#define BLUESERIES_20A_MAIN +;#define BLUESERIES_20A_TAIL +;#define BLUESERIES_20A_MULTI +;#define BLUESERIES_30A_MAIN +;#define BLUESERIES_30A_TAIL +;#define BLUESERIES_30A_MULTI +;#define BLUESERIES_40A_MAIN +;#define BLUESERIES_40A_TAIL +;#define BLUESERIES_40A_MULTI +;#define BLUESERIES_60A_MAIN +;#define BLUESERIES_60A_TAIL +;#define BLUESERIES_60A_MULTI +;#define BLUESERIES_70A_MAIN +;#define BLUESERIES_70A_TAIL +;#define BLUESERIES_70A_MULTI +;#define FC_45A_HV_MAIN +;#define FC_45A_HV_TAIL +;#define FC_45A_HV_MULTI +;#define HK_UBEC_6A_MAIN +;#define HK_UBEC_6A_TAIL +;#define HK_UBEC_6A_MULTI +;#define HK_UBEC_10A_MAIN +;#define HK_UBEC_10A_TAIL +;#define HK_UBEC_10A_MULTI +;#define HK_UBEC_20A_MAIN +;#define HK_UBEC_20A_TAIL +;#define HK_UBEC_20A_MULTI +;#define HK_UBEC_30A_MAIN +;#define HK_UBEC_30A_TAIL +;#define HK_UBEC_30A_MULTI +;#define HK_UBEC_40A_MAIN +;#define HK_UBEC_40A_TAIL +;#define HK_UBEC_40A_MULTI +;#define SUPERSIMPLE_18A_MAIN +;#define SUPERSIMPLE_18A_TAIL +;#define SUPERSIMPLE_18A_MULTI +;#define SUPERSIMPLE_20A_MAIN +;#define SUPERSIMPLE_20A_TAIL +;#define SUPERSIMPLE_20A_MULTI +;#define SUPERSIMPLE_30A_MAIN +;#define SUPERSIMPLE_30A_TAIL +;#define SUPERSIMPLE_30A_MULTI +;#define SUPERSIMPLE_40A_MAIN +;#define SUPERSIMPLE_40A_TAIL +;#define SUPERSIMPLE_40A_MULTI +;#define MULTISTAR_10Av2_MAIN +;#define MULTISTAR_10Av2_TAIL +;#define MULTISTAR_10Av2_MULTI +;#define MULTISTAR_15A_MAIN ; Inverted input +;#define MULTISTAR_15A_TAIL +;#define MULTISTAR_15A_MULTI +;#define MULTISTAR_20A_MAIN ; Inverted input +;#define MULTISTAR_20A_TAIL +;#define MULTISTAR_20A_MULTI +;#define MULTISTAR_20A_NFET_MAIN ; Inverted input +;#define MULTISTAR_20A_NFET_TAIL +;#define MULTISTAR_20A_NFET_MULTI +;#define MULTISTAR_20Av2_MAIN +;#define MULTISTAR_20Av2_TAIL +;#define MULTISTAR_20Av2_MULTI +;#define MULTISTAR_30A_MAIN ; Inverted input +;#define MULTISTAR_30A_TAIL +;#define MULTISTAR_30A_MULTI +;#define MULTISTAR_40Av2_MAIN +;#define MULTISTAR_40Av2_TAIL +;#define MULTISTAR_40Av2_MULTI +;#define MULTISTAR_45A_MAIN ; Inverted input +;#define MULTISTAR_45A_TAIL +;#define MULTISTAR_45A_MULTI +;#define MYSTERY_12A_MAIN +;#define MYSTERY_12A_TAIL +;#define MYSTERY_12A_MULTI +;#define MYSTERY_30A_MAIN +;#define MYSTERY_30A_TAIL +;#define MYSTERY_30A_MULTI +;#define MYSTERY_40A_MAIN +;#define MYSTERY_40A_TAIL +;#define MYSTERY_40A_MULTI +;#define SUNRISE_HIMULTI_20A_MAIN ; Inverted input +;#define SUNRISE_HIMULTI_20A_TAIL +;#define SUNRISE_HIMULTI_20A_MULTI +;#define SUNRISE_HIMULTI_30A_MAIN ; Inverted input +;#define SUNRISE_HIMULTI_30A_TAIL +;#define SUNRISE_HIMULTI_30A_MULTI +;#define SUNRISE_HIMULTI_40A_MAIN ; Inverted input +;#define SUNRISE_HIMULTI_40A_TAIL +;#define SUNRISE_HIMULTI_40A_MULTI +;#define RCTIMER_40A_MAIN +;#define RCTIMER_40A_TAIL +;#define RCTIMER_40A_MULTI +;#define RCTIMER_NFS_30A_MAIN ; ICP1 as input +;#define RCTIMER_NFS_30A_TAIL +;#define RCTIMER_NFS_30A_MULTI +;#define YEP_7A_MAIN +;#define YEP_7A_TAIL +;#define YEP_7A_MULTI +;#define AFRO_12A_MAIN ; ICP1 as input +;#define AFRO_12A_TAIL +;#define AFRO_12A_MULTI +;#define AFRO_20A_MAIN ; ICP1 as input +;#define AFRO_20A_TAIL +;#define AFRO_20A_MULTI +;#define AFRO_20A_HV_MAIN ; ICP1 as input +;#define AFRO_20A_HV_TAIL +;#define AFRO_20A_HV_MULTI +;#define AFRO_30A_MAIN ; ICP1 as input +;#define AFRO_30A_TAIL +;#define AFRO_30A_MULTI +;#define SUNRISE_BLHELI_SLIM_20A_MAIN +;#define SUNRISE_BLHELI_SLIM_20A_TAIL +;#define SUNRISE_BLHELI_SLIM_20A_MULTI +;#define SUNRISE_BLHELI_SLIM_30A_MAIN +;#define SUNRISE_BLHELI_SLIM_30A_TAIL +;#define SUNRISE_BLHELI_SLIM_30A_MULTI +;#define DYS_SN20A_MAIN ; ICP1 as input +;#define DYS_SN20A_TAIL +;#define DYS_SN20A_MULTI +;#define TBS_CUBE_20A_MAIN ; ICP1 as input +;#define TBS_CUBE_20A_TAIL +;#define TBS_CUBE_20A_MULTI +;#define ZTW_SPIDER_LITE_18Av2_MAIN +;#define ZTW_SPIDER_LITE_18Av2_TAIL +;#define ZTW_SPIDER_LITE_18Av2_MULTI +;#define HTIRC_DRAGONFLY_6A_MAIN +;#define HTIRC_DRAGONFLY_6A_TAIL +;#define HTIRC_DRAGONFLY_6A_MULTI +;#define HTIRC_DRAGONFLY_12A_MAIN +;#define HTIRC_DRAGONFLY_12A_TAIL +;#define HTIRC_DRAGONFLY_12A_MULTI +;#define HTIRC_DRAGONFLY_20A_MAIN +;#define HTIRC_DRAGONFLY_20A_TAIL +;#define HTIRC_DRAGONFLY_20A_MULTI +;#define HTIRC_DRAGONFLY_30A_MAIN +;#define HTIRC_DRAGONFLY_30A_TAIL +;#define HTIRC_DRAGONFLY_30A_MULTI +;#define HTIRC_DRAGONFLY_40A_MAIN +;#define HTIRC_DRAGONFLY_40A_TAIL +;#define HTIRC_DRAGONFLY_40A_MULTI +;#define TBS_BULLETPROOF_4A_MAIN ; ICP1 as input +;#define TBS_BULLETPROOF_4A_TAIL +;#define TBS_BULLETPROOF_4A_MULTI +;#define TBS_BULLETPROOF_30A_MAIN ; ICP1 as input +;#define TBS_BULLETPROOF_30A_TAIL +;#define TBS_BULLETPROOF_30A_MULTI + + + +;**** **** **** **** **** +; ESC selection statements +#if defined(BLUESERIES_12A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "BlueSeries_12A.inc" ; Select BlueSeries 12A pinout +#endif + +#if defined(BLUESERIES_12A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "BlueSeries_12A.inc" ; Select BlueSeries 12A pinout +#endif + +#if defined(BLUESERIES_12A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "BlueSeries_12A.inc" ; Select BlueSeries 12A pinout +#endif + +#if defined(BLUESERIES_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "BlueSeries_20A.inc" ; Select BlueSeries 20A pinout +#endif + +#if defined(BLUESERIES_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "BlueSeries_20A.inc" ; Select BlueSeries 20A pinout +#endif + +#if defined(BLUESERIES_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "BlueSeries_20A.inc" ; Select BlueSeries 20A pinout +#endif + +#if defined(BLUESERIES_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "BlueSeries_30A.inc" ; Select BlueSeries 30A pinout +#endif + +#if defined(BLUESERIES_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "BlueSeries_30A.inc" ; Select BlueSeries 30A pinout +#endif + +#if defined(BLUESERIES_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "BlueSeries_30A.inc" ; Select BlueSeries 30A pinout +#endif + +#if defined(BLUESERIES_40A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "BlueSeries_40A.inc" ; Select BlueSeries 40A pinout +#endif + +#if defined(BLUESERIES_40A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "BlueSeries_40A.inc" ; Select BlueSeries 40A pinout +#endif + +#if defined(BLUESERIES_40A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "BlueSeries_40A.inc" ; Select BlueSeries 40A pinout +#endif + +#if defined(BLUESERIES_60A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "BlueSeries_60A.inc" ; Select BlueSeries 60A pinout +#endif + +#if defined(BLUESERIES_60A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "BlueSeries_60A.inc" ; Select BlueSeries 60A pinout +#endif + +#if defined(BLUESERIES_60A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "BlueSeries_60A.inc" ; Select BlueSeries 60A pinout +#endif + +#if defined(BLUESERIES_70A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "BlueSeries_70A.inc" ; Select BlueSeries 70A pinout +#endif + +#if defined(BLUESERIES_70A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "BlueSeries_70A.inc" ; Select BlueSeries 70A pinout +#endif + +#if defined(BLUESERIES_70A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "BlueSeries_70A.inc" ; Select BlueSeries 70A pinout +#endif + +#if defined(FC_45A_HV_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Flycolor_45A_HV.inc" ; Select Flycolor 45A HV pinout +#endif + +#if defined(FC_45A_HV_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Flycolor_45A_HV.inc" ; Select Flycolor 45A HV pinout +#endif + +#if defined(FC_45A_HV_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Flycolor_45A_HV.inc" ; Select Flycolor 45A HV pinout +#endif + +#if defined(HK_UBEC_6A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "HK_UBEC_6A.inc" ; Select Hobbyking UBEC 6A pinout +#endif + +#if defined(HK_UBEC_6A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "HK_UBEC_6A.inc" ; Select Hobbyking UBEC 6A pinout +#endif + +#if defined(HK_UBEC_6A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "HK_UBEC_6A.inc" ; Select Hobbyking UBEC 6A pinout +#endif + +#if defined(HK_UBEC_10A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "HK_UBEC_10A.inc" ; Select Hobbyking UBEC 10A pinout +#endif + +#if defined(HK_UBEC_10A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "HK_UBEC_10A.inc" ; Select Hobbyking UBEC 10A pinout +#endif + +#if defined(HK_UBEC_10A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "HK_UBEC_10A.inc" ; Select Hobbyking UBEC 10A pinout +#endif + +#if defined(HK_UBEC_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "HK_UBEC_20A.inc" ; Select Hobbyking UBEC 20A pinout +#endif + +#if defined(HK_UBEC_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "HK_UBEC_20A.inc" ; Select Hobbyking UBEC 20A pinout +#endif + +#if defined(HK_UBEC_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "HK_UBEC_20A.inc" ; Select Hobbyking UBEC 20A pinout +#endif + +#if defined(HK_UBEC_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "HK_UBEC_30A.inc" ; Select Hobbyking UBEC 30A pinout +#endif + +#if defined(HK_UBEC_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "HK_UBEC_30A.inc" ; Select Hobbyking UBEC 30A pinout +#endif + +#if defined(HK_UBEC_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "HK_UBEC_30A.inc" ; Select Hobbyking UBEC 30A pinout +#endif + +#if defined(HK_UBEC_40A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "HK_UBEC_40A.inc" ; Select Hobbyking UBEC 40A pinout +#endif + +#if defined(HK_UBEC_40A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "HK_UBEC_40A.inc" ; Select Hobbyking UBEC 40A pinout +#endif + +#if defined(HK_UBEC_40A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "HK_UBEC_40A.inc" ; Select Hobbyking UBEC 40A pinout +#endif + +#if defined(SUPERSIMPLE_18A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "SuperSimple_18A.inc" ; Select SuperSimple 18A pinout +#endif + +#if defined(SUPERSIMPLE_18A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "SuperSimple_18A.inc" ; Select SuperSimple 18A pinout +#endif + +#if defined(SUPERSIMPLE_18A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "SuperSimple_18A.inc" ; Select SuperSimple 18A pinout +#endif + +#if defined(SUPERSIMPLE_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "SuperSimple_20A.inc" ; Select SuperSimple 20A pinout +#endif + +#if defined(SUPERSIMPLE_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "SuperSimple_20A.inc" ; Select SuperSimple 20A pinout +#endif + +#if defined(SUPERSIMPLE_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "SuperSimple_20A.inc" ; Select SuperSimple 20A pinout +#endif + +#if defined(SUPERSIMPLE_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "SuperSimple_30A.inc" ; Select SuperSimple 30A pinout +#endif + +#if defined(SUPERSIMPLE_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "SuperSimple_30A.inc" ; Select SuperSimple 30A pinout +#endif + +#if defined(SUPERSIMPLE_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "SuperSimple_30A.inc" ; Select SuperSimple 30A pinout +#endif + +#if defined(SUPERSIMPLE_40A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "SuperSimple_40A.inc" ; Select SuperSimple 40A pinout +#endif + +#if defined(SUPERSIMPLE_40A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "SuperSimple_40A.inc" ; Select SuperSimple 40A pinout +#endif + +#if defined(SUPERSIMPLE_40A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "SuperSimple_40A.inc" ; Select SuperSimple 40A pinout +#endif + +#if defined(MULTISTAR_10Av2_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_10Av2.inc" ; Select Multistar 10A v2 pinout +#endif + +#if defined(MULTISTAR_10Av2_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_10Av2.inc" ; Select Multistar 10A v2 pinout +#endif + +#if defined(MULTISTAR_10Av2_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_10Av2.inc" ; Select Multistar 10A v2 pinout +#endif + +#if defined(MULTISTAR_15A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_15A.inc" ; Select Multistar 15A pinout +#endif + +#if defined(MULTISTAR_15A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_15A.inc" ; Select Multistar 15A pinout +#endif + +#if defined(MULTISTAR_15A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_15A.inc" ; Select Multistar 15A pinout +#endif + +#if defined(MULTISTAR_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_20A.inc" ; Select Multistar 20A pinout +#endif + +#if defined(MULTISTAR_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_20A.inc" ; Select Multistar 20A pinout +#endif + +#if defined(MULTISTAR_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_20A.inc" ; Select Multistar 20A pinout +#endif + +#if defined(MULTISTAR_20A_NFET_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_20A_NFET.inc" ; Select Multistar 20A NFET pinout +#endif + +#if defined(MULTISTAR_20A_NFET_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_20A_NFET.inc" ; Select Multistar 20A NFET pinout +#endif + +#if defined(MULTISTAR_20A_NFET_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_20A_NFET.inc" ; Select Multistar 20A NFET pinout +#endif + +#if defined(MULTISTAR_20Av2_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_20Av2.inc" ; Select Multistar 20A v2 pinout +#endif + +#if defined(MULTISTAR_20Av2_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_20Av2.inc" ; Select Multistar 20A v2 pinout +#endif + +#if defined(MULTISTAR_20Av2_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_20Av2.inc" ; Select Multistar 20A v2 pinout +#endif + +#if defined(MULTISTAR_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_30A.inc" ; Select Multistar 30A pinout +#endif + +#if defined(MULTISTAR_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_30A.inc" ; Select Multistar 30A pinout +#endif + +#if defined(MULTISTAR_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_30A.inc" ; Select Multistar 30A pinout +#endif + +#if defined(MULTISTAR_40Av2_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_40Av2.inc" ; Select Multistar 40A v2 pinout +#endif + +#if defined(MULTISTAR_40Av2_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_40Av2.inc" ; Select Multistar 40A v2 pinout +#endif + +#if defined(MULTISTAR_40Av2_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_40Av2.inc" ; Select Multistar 40A v2 pinout +#endif + +#if defined(MULTISTAR_45A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Multistar_45A.inc" ; Select Multistar 45A pinout +#endif + +#if defined(MULTISTAR_45A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Multistar_45A.inc" ; Select Multistar 45A pinout +#endif + +#if defined(MULTISTAR_45A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Multistar_45A.inc" ; Select Multistar 45A pinout +#endif + +#if defined(MYSTERY_12A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Mystery_12A.inc" ; Select Mystery 12A pinout +#endif + +#if defined(MYSTERY_12A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Mystery_12A.inc" ; Select Mystery 12A pinout +#endif + +#if defined(MYSTERY_12A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Mystery_12A.inc" ; Select Mystery 12A pinout +#endif + +#if defined(MYSTERY_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Mystery_30A.inc" ; Select Mystery 30A pinout +#endif + +#if defined(MYSTERY_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Mystery_30A.inc" ; Select Mystery 30A pinout +#endif + +#if defined(MYSTERY_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Mystery_30A.inc" ; Select Mystery 30A pinout +#endif + +#if defined(MYSTERY_40A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Mystery_40A.inc" ; Select Mystery 40A pinout +#endif + +#if defined(MYSTERY_40A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Mystery_40A.inc" ; Select Mystery 40A pinout +#endif + +#if defined(MYSTERY_40A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Mystery_40A.inc" ; Select Mystery 40A pinout +#endif + +#if defined(SUNRISE_HIMULTI_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Sunrise_HiMulti_20A.inc" ; Select Sunrise HiMulti 20A pinout +#endif + +#if defined(SUNRISE_HIMULTI_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Sunrise_HiMulti_20A.inc" ; Select Sunrise HiMulti 20A pinout +#endif + +#if defined(SUNRISE_HIMULTI_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Sunrise_HiMulti_20A.inc" ; Select Sunrise HiMulti 20A pinout +#endif + +#if defined(SUNRISE_HIMULTI_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Sunrise_HiMulti_30A.inc" ; Select Sunrise HiMulti 30A pinout +#endif + +#if defined(SUNRISE_HIMULTI_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Sunrise_HiMulti_30A.inc" ; Select Sunrise HiMulti 30A pinout +#endif + +#if defined(SUNRISE_HIMULTI_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Sunrise_HiMulti_30A.inc" ; Select Sunrise HiMulti 30A pinout +#endif + +#if defined(SUNRISE_HIMULTI_40A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Sunrise_HiMulti_40A.inc" ; Select Sunrise HiMulti 40A pinout +#endif + +#if defined(SUNRISE_HIMULTI_40A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Sunrise_HiMulti_40A.inc" ; Select Sunrise HiMulti 40A pinout +#endif + +#if defined(SUNRISE_HIMULTI_40A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Sunrise_HiMulti_40A.inc" ; Select Sunrise HiMulti 40A pinout +#endif + +#if defined(RCTIMER_40A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "RCTimer_40A.inc" ; Select RCTimer 40A pinout +#endif + +#if defined(RCTIMER_40A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "RCTimer_40A.inc" ; Select RCTimer 40A pinout +#endif + +#if defined(RCTIMER_40A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "RCTimer_40A.inc" ; Select RCTimer 40A pinout +#endif + +#if defined(RCTIMER_NFS_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "RCTimer_NFS_30A.inc" ; Select RCTimer NFS 30A pinout +#endif + +#if defined(RCTIMER_NFS_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "RCTimer_NFS_30A.inc" ; Select RCTimer NFS 30A pinout +#endif + +#if defined(RCTIMER_NFS_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "RCTimer_NFS_30A.inc" ; Select RCTimer NFS 30A pinout +#endif + +#if defined(YEP_7A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "YEP_7A.inc" ; Select YEP 7A pinout +#endif + +#if defined(YEP_7A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "YEP_7A.inc" ; Select YEP 7A pinout +#endif + +#if defined(YEP_7A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "YEP_7A.inc" ; Select YEP 7A pinout +#endif + +#if defined(AFRO_12A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "AFRO_12A.inc" ; Select AFRO 12A pinout +#endif + +#if defined(AFRO_12A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "AFRO_12A.inc" ; Select AFRO 12A pinout +#endif + +#if defined(AFRO_12A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "AFRO_12A.inc" ; Select AFRO 12A pinout +#endif + +#if defined(AFRO_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "AFRO_20A.inc" ; Select AFRO 20A pinout +#endif + +#if defined(AFRO_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "AFRO_20A.inc" ; Select AFRO 20A pinout +#endif + +#if defined(AFRO_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "AFRO_20A.inc" ; Select AFRO 20A pinout +#endif + +#if defined(AFRO_20A_HV_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "AFRO_20A_HV.inc" ; Select AFRO 20A HV pinout +#endif + +#if defined(AFRO_20A_HV_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "AFRO_20A_HV.inc" ; Select AFRO 20A HV pinout +#endif + +#if defined(AFRO_20A_HV_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "AFRO_20A_HV.inc" ; Select AFRO 20A HV pinout +#endif + +#if defined(AFRO_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "AFRO_30A.inc" ; Select AFRO 30A pinout +#endif + +#if defined(AFRO_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "AFRO_30A.inc" ; Select AFRO 30A pinout +#endif + +#if defined(AFRO_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "AFRO_30A.inc" ; Select AFRO 30A pinout +#endif + +#if defined(SUNRISE_BLHELI_SLIM_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Sunrise_BLHeli_Slim_20A.inc" ; Select Sunrise BLHeli slim 20A pinout +#endif + +#if defined(SUNRISE_BLHELI_SLIM_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Sunrise_BLHeli_Slim_20A.inc" ; Select Sunrise BLHeli slim 20A pinout +#endif + +#if defined(SUNRISE_BLHELI_SLIM_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Sunrise_BLHeli_Slim_20A.inc" ; Select Sunrise BLHeli slim 20A pinout +#endif + +#if defined(SUNRISE_BLHELI_SLIM_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Sunrise_BLHeli_Slim_30A.inc" ; Select Sunrise BLHeli slim 30A pinout +#endif + +#if defined(SUNRISE_BLHELI_SLIM_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Sunrise_BLHeli_Slim_30A.inc" ; Select Sunrise BLHeli slim 30A pinout +#endif + +#if defined(SUNRISE_BLHELI_SLIM_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Sunrise_BLHeli_Slim_30A.inc" ; Select Sunrise BLHeli slim 30A pinout +#endif + +#if defined(DYS_SN20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "DYS_SN20A.inc" ; Select DYS SN20A pinout +#endif + +#if defined(DYS_SN20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "DYS_SN20A.inc" ; Select DYS SN20A pinout +#endif + +#if defined(DYS_SN20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "DYS_SN20A.inc" ; Select DYS SN20A pinout +#endif + +#if defined(TBS_CUBE_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "TBS_CUBE_20A.inc" ; Select TBS CUBE 20A pinout +#endif + +#if defined(TBS_CUBE_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "TBS_CUBE_20A.inc" ; Select TBS CUBE 20A pinout +#endif + +#if defined(TBS_CUBE_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "TBS_CUBE_20A.inc" ; Select TBS CUBE 20A pinout +#endif + +#if defined(ZTW_SPIDER_LITE_18Av2_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "ZTW_Spider_Lite_18Av2.inc" ; Select ZTW Spider Lite 18Av2 pinout +#endif + +#if defined(ZTW_SPIDER_LITE_18Av2_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "ZTW_Spider_Lite_18Av2.inc" ; Select ZTW Spider Lite 18Av2 pinout +#endif + +#if defined(ZTW_SPIDER_LITE_18Av2_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "ZTW_Spider_Lite_18Av2.inc" ; Select ZTW Spider Lite 18Av2 pinout +#endif + +#if defined(HTIRC_DRAGONFLY_6A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Htirc_Dragonfly_6A.inc" ; Select HTIRC Dragonfly 6A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_6A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Htirc_Dragonfly_6A.inc" ; Select HTIRC Dragonfly 6A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_6A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Htirc_Dragonfly_6A.inc" ; Select HTIRC Dragonfly 6A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_12A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Htirc_Dragonfly_12A.inc" ; Select HTIRC Dragonfly 12A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_12A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Htirc_Dragonfly_12A.inc" ; Select HTIRC Dragonfly 12A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_12A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Htirc_Dragonfly_12A.inc" ; Select HTIRC Dragonfly 12A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_20A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Htirc_Dragonfly_20A.inc" ; Select HTIRC Dragonfly 20A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_20A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Htirc_Dragonfly_20A.inc" ; Select HTIRC Dragonfly 20A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_20A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Htirc_Dragonfly_20A.inc" ; Select HTIRC Dragonfly 20A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Htirc_Dragonfly_30A.inc" ; Select HTIRC Dragonfly 30A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Htirc_Dragonfly_30A.inc" ; Select HTIRC Dragonfly 30A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Htirc_Dragonfly_30A.inc" ; Select HTIRC Dragonfly 30A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_40A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "Htirc_Dragonfly_40A.inc" ; Select HTIRC Dragonfly 40A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_40A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "Htirc_Dragonfly_40A.inc" ; Select HTIRC Dragonfly 40A pinout +#endif + +#if defined(HTIRC_DRAGONFLY_40A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "Htirc_Dragonfly_40A.inc" ; Select HTIRC Dragonfly 40A pinout +#endif + +#if defined(TBS_BULLETPROOF_4A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "TBS_BULLETPROOF_4A.inc" ; Select TBS BULLETPROOF 4A pinout +#endif + +#if defined(TBS_BULLETPROOF_4A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "TBS_BULLETPROOF_4A.inc" ; Select TBS BULLETPROOF 4A pinout +#endif + +#if defined(TBS_BULLETPROOF_4A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "TBS_BULLETPROOF_4A.inc" ; Select TBS BULLETPROOF 4A pinout +#endif + +#if defined(TBS_BULLETPROOF_30A_MAIN) +.EQU MODE = 0 ; Choose mode. Set to 0 for main motor +.INCLUDE "TBS_BULLETPROOF_30A.inc" ; Select TBS BULLETPROOF 30A pinout +#endif + +#if defined(TBS_BULLETPROOF_30A_TAIL) +.EQU MODE = 1 ; Choose mode. Set to 1 for tail motor +.INCLUDE "TBS_BULLETPROOF_30A.inc" ; Select TBS BULLETPROOF 30A pinout +#endif + +#if defined(TBS_BULLETPROOF_30A_MULTI) +.EQU MODE = 2 ; Choose mode. Set to 2 for multirotor +.INCLUDE "TBS_BULLETPROOF_30A.inc" ; Select TBS BULLETPROOF 30A 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) +; +; Main +.EQU DEFAULT_PGM_MAIN_P_GAIN = 7 ; 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 +.EQU DEFAULT_PGM_MAIN_I_GAIN = 7 ; 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 +.EQU DEFAULT_PGM_MAIN_GOVERNOR_MODE = 1 ; 1=Tx 2=Arm 3=Setup 4=Off +.EQU DEFAULT_PGM_MAIN_GOVERNOR_RANGE = 1 ; 1=High 2=Middle 3=Low +.EQU DEFAULT_PGM_MAIN_LOW_VOLTAGE_LIM = 4 ; 1=Off 2=3.0V/c 3=3.1V/c 4=3.2V/c 5=3.3V/c 6=3.4V/c +.EQU DEFAULT_PGM_MAIN_COMM_TIMING = 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +.IF DAMPED_MODE_ENABLE == 1 +.EQU DEFAULT_PGM_MAIN_PWM_FREQ = 2 ; 1=High 2=Low 3=DampedLight +.ELSE +.EQU DEFAULT_PGM_MAIN_PWM_FREQ = 2 ; 1=High 2=Low +.ENDIF +.EQU DEFAULT_PGM_MAIN_DEMAG_COMP = 1 ; 1=Disabled 2=Low 3=High +.EQU DEFAULT_PGM_MAIN_DIRECTION = 1 ; 1=Normal 2=Reversed +.EQU DEFAULT_PGM_MAIN_RCP_PWM_POL = 1 ; 1=Positive 2=Negative +.EQU DEFAULT_PGM_MAIN_GOV_SETUP_TARGET = 180; Target for governor in setup mode. Corresponds to 70% throttle +.EQU DEFAULT_PGM_MAIN_REARM_START = 0 ; 1=Enabled 0=Disabled +.EQU DEFAULT_PGM_MAIN_BEEP_STRENGTH = 120; Beep strength +.EQU DEFAULT_PGM_MAIN_BEACON_STRENGTH = 200; Beacon strength +.EQU DEFAULT_PGM_MAIN_BEACON_DELAY = 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite + +; Tail +.EQU DEFAULT_PGM_TAIL_GAIN = 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25 +.EQU DEFAULT_PGM_TAIL_IDLE_SPEED = 4 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +.EQU DEFAULT_PGM_TAIL_COMM_TIMING = 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +.IF DAMPED_MODE_ENABLE == 1 +.EQU DEFAULT_PGM_TAIL_PWM_FREQ = 3 ; 1=High 2=Low 3=DampedLight +.ELSE +.EQU DEFAULT_PGM_TAIL_PWM_FREQ = 1 ; 1=High 2=Low +.ENDIF +.EQU DEFAULT_PGM_TAIL_DEMAG_COMP = 1 ; 1=Disabled 2=Low 3=High +.EQU DEFAULT_PGM_TAIL_DIRECTION = 1 ; 1=Normal 2=Reversed 3=Bidirectional +.EQU DEFAULT_PGM_TAIL_RCP_PWM_POL = 1 ; 1=Positive 2=Negative +.EQU DEFAULT_PGM_TAIL_BEEP_STRENGTH = 250; Beep strength +.EQU DEFAULT_PGM_TAIL_BEACON_STRENGTH = 250; Beacon strength +.EQU DEFAULT_PGM_TAIL_BEACON_DELAY = 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite +.EQU DEFAULT_PGM_TAIL_PWM_DITHER = 3 ; 1=Off 2=3 3=7 4=15 5=31 + +; Multi +.EQU DEFAULT_PGM_MULTI_P_GAIN = 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 +.EQU DEFAULT_PGM_MULTI_I_GAIN = 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 +.EQU DEFAULT_PGM_MULTI_GOVERNOR_MODE = 4 ; 1=HiRange 2=MidRange 3=LoRange 4=Off +.EQU DEFAULT_PGM_MULTI_GAIN = 3 ; 1=0.75 2=0.88 3=1.00 4=1.12 5=1.25 +.EQU DEFAULT_PGM_MULTI_COMM_TIMING = 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High +.IF DAMPED_MODE_ENABLE == 1 +.EQU DEFAULT_PGM_MULTI_PWM_FREQ = 3 ; 1=High 2=Low 3=DampedLight +.ELSE +.EQU DEFAULT_PGM_MULTI_PWM_FREQ = 1 ; 1=High 2=Low +.ENDIF +.EQU DEFAULT_PGM_MULTI_DEMAG_COMP = 2 ; 1=Disabled 2=Low 3=High +.EQU DEFAULT_PGM_MULTI_DIRECTION = 1 ; 1=Normal 2=Reversed 3=Bidirectional +.EQU DEFAULT_PGM_MULTI_RCP_PWM_POL = 1 ; 1=Positive 2=Negative +.EQU DEFAULT_PGM_MULTI_BEEP_STRENGTH = 40 ; Beep strength +.EQU DEFAULT_PGM_MULTI_BEACON_STRENGTH = 80 ; Beacon strength +.EQU DEFAULT_PGM_MULTI_BEACON_DELAY = 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite +.EQU DEFAULT_PGM_MULTI_PWM_DITHER = 3 ; 1=Off 2=3 3=7 4=15 5=31 + +; Common +.EQU DEFAULT_PGM_ENABLE_TX_PROGRAM = 1 ; 1=Enabled 0=Disabled +.EQU DEFAULT_PGM_PPM_MIN_THROTTLE = 37 ; 4*37+1000=1148 +.EQU DEFAULT_PGM_PPM_MAX_THROTTLE = 208; 4*208+1000=1832 +.EQU DEFAULT_PGM_PPM_CENTER_THROTTLE = 122; 4*122+1000=1488 (used in bidirectional mode) +.EQU DEFAULT_PGM_BEC_VOLTAGE_HIGH = 0 ; 0=Low 1= High +.EQU DEFAULT_PGM_ENABLE_TEMP_PROT = 0 ; 1=Enabled 0=Disabled +.EQU DEFAULT_PGM_ENABLE_POWER_PROT = 1 ; 1=Enabled 0=Disabled +.EQU DEFAULT_PGM_ENABLE_PWM_INPUT = 0 ; 1=Enabled 0=Disabled +.EQU DEFAULT_PGM_BRAKE_ON_STOP = 0 ; 1=Enabled 0=Disabled + +;**** **** **** **** **** +; Constant definitions for main +.IF MODE == 0 + +.EQU GOV_SPOOLRATE = 2 ; Number of steps for governor requested pwm per 32ms + +.EQU RCP_TIMEOUT_PPM = 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost +.EQU RCP_TIMEOUT = 64 ; Number of timer2L overflows (about 128us) before considering rc pulse lost +.EQU RCP_SKIP_RATE = 32 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection +.EQU RCP_MIN = 0 ; This is minimum RC pulse length +.EQU RCP_MAX = 255 ; This is maximum RC pulse length +.EQU RCP_VALIDATE = 2 ; Require minimum this pulse length to validate RC pulse +.EQU RCP_STOP = 1 ; Stop motor at or below this pulse length +.EQU RCP_STOP_LIMIT = 250 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit + +.EQU PWM_START = 50 ; PWM used as max power during start + +.EQU COMM_TIME_MIN = 1 ; Minimum time (in us) for commutation wait + +.EQU TEMP_CHECK_RATE = 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 + +.EQU GOV_SPOOLRATE = 1 ; Number of steps for governor requested pwm per 32ms +.EQU RCP_TIMEOUT_PPM = 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost +.EQU RCP_TIMEOUT = 24 ; Number of timer2L overflows (about 128us) before considering rc pulse lost +.EQU RCP_SKIP_RATE = 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection +.EQU RCP_MIN = 0 ; This is minimum RC pulse length +.EQU RCP_MAX = 255 ; This is maximum RC pulse length +.EQU RCP_VALIDATE = 2 ; Require minimum this pulse length to validate RC pulse +.EQU RCP_STOP = 1 ; Stop motor at or below this pulse length +.EQU RCP_STOP_LIMIT = 130 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit + +.EQU PWM_START = 50 ; PWM used as max power during start + +.EQU COMM_TIME_MIN = 1 ; Minimum time (in us) for commutation wait + +.EQU TEMP_CHECK_RATE = 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 + +.EQU GOV_SPOOLRATE = 1 ; Number of steps for governor requested pwm per 32ms + +.EQU RCP_TIMEOUT_PPM = 10 ; Number of timer2H overflows (about 32ms) before considering rc pulse lost +.EQU RCP_TIMEOUT = 24 ; Number of timer2L overflows (about 128us) before considering rc pulse lost +.EQU RCP_SKIP_RATE = 6 ; Number of timer2L overflows (about 128us) before reenabling rc pulse detection +.EQU RCP_MIN = 0 ; This is minimum RC pulse length +.EQU RCP_MAX = 255 ; This is maximum RC pulse length +.EQU RCP_VALIDATE = 2 ; Require minimum this pulse length to validate RC pulse +.EQU RCP_STOP = 1 ; Stop motor at or below this pulse length +.EQU RCP_STOP_LIMIT = 250 ; Stop motor if this many timer2H overflows (~32ms) are below stop limit + +.EQU PWM_START = 50 ; PWM used as max power during start + +.EQU COMM_TIME_MIN = 1 ; Minimum time (in us) for commutation wait + +.EQU TEMP_CHECK_RATE = 8 ; Number of adc conversions for each check of temperature (the other conversions are used for voltage) + +.ENDIF + +;**** **** **** **** **** +; Register definitions +.DEF Mul_Res_L = R0 ; Reserved for mul instruction +.DEF Mul_Res_H = R1 ; Reserved for mul instruction +.DEF Zero = R2 ; Register variable initialized to 0, always at 0 +.DEF I_Sreg = R3 ; Status register saved in interrupts +.DEF II_Sreg = R4 ; Status register saved in nested interrupts (pwm interrupts from timer2) +.DEF Current_Pwm_Limited = R5 ; Current_Pwm_Limited is allocated to a register for fast access +.DEF Next_Wt_L = R14 ; Next wait value (lo byte) +.DEF Next_Wt_H = R15 ; Next wait value (hi byte) + +.DEF Temp1 = R16 ; Main temporary +.DEF Temp2 = R17 ; Main temporary (Temp1/2 must be two consecutive registers) +.DEF Temp3 = R18 ; Main temporary +.DEF Temp4 = R19 ; Main temporary +.DEF Temp5 = R6 ; Main temporary (limited operations) +.DEF Temp6 = R7 ; Main temporary (limited operations) +.DEF Temp7 = R8 ; Main temporary (limited operations) +.DEF Temp8 = R9 ; Main temporary (limited operations) + +.DEF I_Temp1 = R20 ; Interrupt temporary +.DEF I_Temp2 = R21 ; Interrupt temporary +.DEF I_Temp3 = R10 ; Interrupt temporary (limited operations) +.DEF I_Temp4 = R11 ; Interrupt temporary (limited operations) +.DEF I_Temp5 = R12 ; Interrupt temporary (limited operations) +.DEF I_Temp6 = R13 ; Interrupt temporary (limited operations) + +.DEF Flags0 = R22 ; State flags. Reset upon init_start +.EQU OC1A_PENDING = 0 ; Timer1 output compare pending flag +.EQU RCP_MEAS_PWM_FREQ = 1 ; Measure RC pulse pwm frequency +.EQU PWM_ON = 2 ; Set in on part of pwm cycle +.EQU DEMAG_DETECTED = 3 ; Set when excessive demag time is detected +.EQU DEMAG_CUT_POWER = 4 ; Set when demag compensation cuts power +.EQU GOV_ACTIVE = 5 ; Set when governor is active +.EQU DIR_CHANGE_BRAKE = 6 ; Set when braking before direction change +; = 7 + +.DEF Flags1 = R23 ; State flags. Reset upon init_start +.EQU MOTOR_SPINNING = 0 ; Set when in motor is spinning +.EQU STARTUP_PHASE = 1 ; Set when in startup phase +.EQU INITIAL_RUN_PHASE = 2 ; Set when in initial run phase, before synchronized run is achieved +.EQU MOTOR_STARTED = 3 ; Set when motor is started +.EQU ADC_READ_TEMP = 4 ; Set when ADC input shall be set to read temperature +.EQU COMP_TIMED_OUT = 5 ; Set when comparator reading timed out +.EQU SKIP_DAMP_ON = 6 ; Set when turning damping fet on is skipped +.EQU HIGH_RPM = 7 ; Set when motor rpm is high (Comm_Period4x_H less than 2) + +.DEF Flags2 = R24 ; State flags. NOT reset upon init_start +.EQU RCP_UPDATED = 0 ; New RC pulse length value available +.EQU RCP_EDGE_NO = 1 ; RC pulse edge no. 0=rising, 1=falling +.EQU PGM_PWMOFF_DAMPED = 2 ; Programmed pwm off damped mode +.EQU PGM_PWM_HIGH_FREQ = 3 ; Progremmed pwm high frequency +.EQU RCP_INT_NESTED_ENABLED = 4 ; Set when RC pulse interrupt is enabled around nested interrupts +.EQU RCP_PPM = 5 ; RC pulse ppm type input (set also when oneshot is set) +.EQU RCP_PPM_ONESHOT125 = 6 ; RC pulse ppm type input is OneShot125 +.EQU RCP_DIR_REV = 7 ; RC pulse direction in bidirectional mode + +.DEF Flags3 = R25 ; State flags. NOT reset upon init_start +.EQU RCP_PWM_FREQ_1KHZ = 0 ; RC pulse pwm frequency is 1kHz +.EQU RCP_PWM_FREQ_2KHZ = 1 ; RC pulse pwm frequency is 2kHz +.EQU RCP_PWM_FREQ_4KHZ = 2 ; RC pulse pwm frequency is 4kHz +.EQU RCP_PWM_FREQ_8KHZ = 3 ; RC pulse pwm frequency is 8kHz +.EQU RCP_PWM_FREQ_12KHZ = 4 ; RC pulse pwm frequency is 12kHz +.EQU PGM_DIR_REV = 5 ; Programmed direction. 0=normal, 1=reversed +.EQU PGM_RCP_PWM_POL = 6 ; Programmed RC pulse pwm polarity. 0=positive, 1=negative +.EQU FULL_THROTTLE_RANGE = 7 ; When set full throttle range is used (1000-2000us) and stored calibration values are ignored + + +; Here the general temporary register XYZ are placed (R26-R31) + +; XH: General temporary used by main routines +; XL: General temporary used by interrupt routines +; Y: General temporary used by timer2 pwm interrupt routine +; Z: Address of current PWM FET ON routine (eg: pwm_afet_on) + +;**** **** **** **** **** +; RAM definitions +.DSEG ; Data segment +.ORG SRAM_START +Timer0_Int_Cnt: .BYTE 1 ; Timer0 interrupt counter + +Requested_Pwm: .BYTE 1 ; Requested pwm (from RC pulse value) +Governor_Req_Pwm: .BYTE 1 ; Governor requested pwm (sets governor target) +Current_Pwm: .BYTE 1 ; Current pwm +Current_Pwm_Lim_Dith: .BYTE 1 ; Current pwm that is limited and dithered (applied to the motor output) +Rcp_Prev_Edge_L: .BYTE 1 ; RC pulse previous edge timer3 timestamp (lo byte) +Rcp_Prev_Edge_H: .BYTE 1 ; RC pulse previous edge timer3 timestamp (hi byte) +Rcp_Outside_Range_Cnt: .BYTE 1 ; RC pulse outside range counter (incrementing) +Rcp_Timeout_Cntd: .BYTE 1 ; RC pulse timeout counter (decrementing) +Rcp_Skip_Cntd: .BYTE 1 ; RC pulse skip counter (decrementing) + +Initial_Arm: .BYTE 1 ; Variable that is set during the first arm sequence after power on + +Power_On_Wait_Cnt_L: .BYTE 1 ; Power on wait counter (lo byte) +Power_On_Wait_Cnt_H: .BYTE 1 ; Power on wait counter (hi byte) + +Startup_Cnt: .BYTE 1 ; Startup phase commutations counter (incrementing) +Startup_Zc_Timeout_Cntd: .BYTE 1 ; Startup zero cross timeout counter (decrementing) +Initial_Run_Rot_Cntd: .BYTE 1 ; Initial run rotations counter (decrementing) +Stall_Cnt: .BYTE 1 ; Counts start/run attempts that resulted in stall. Reset upon a proper stop +Demag_Detected_Metric: .BYTE 1 ; Metric used to gauge demag event frequency +Demag_Pwr_Off_Thresh: .BYTE 1 ; Metric threshold above which power is cut +Low_Rpm_Pwr_Slope: .BYTE 1 ; Sets the slope of power increase for low rpms + +Timer2_X: .BYTE 1 ; Timer 2 extended byte +Prev_Comm_L: .BYTE 1 ; Previous commutation timer timestamp (lo byte) +Prev_Comm_H: .BYTE 1 ; Previous commutation timer timestamp (hi byte) +Prev_Comm_X: .BYTE 1 ; Previous commutation timer3 timestamp (ext byte) +Prev_Prev_Comm_L: .BYTE 1 ; Pre-previous commutation timer timestamp (lo byte) +Prev_Prev_Comm_H: .BYTE 1 ; Pre-previous commutation timer timestamp (hi byte) +Comm_Period4x_L: .BYTE 1 ; Timer3 counts between the last 4 commutations (lo byte) +Comm_Period4x_H: .BYTE 1 ; Timer3 counts between the last 4 commutations (hi byte) +Comm_Phase: .BYTE 1 ; Current commutation phase +Comparator_Read_Cnt: .BYTE 1 ; Number of comparator reads done + +Gov_Target_L: .BYTE 1 ; Governor target (lo byte) +Gov_Target_H: .BYTE 1 ; Governor target (hi byte) +Gov_Integral_L: .BYTE 1 ; Governor integral error (lo byte) +Gov_Integral_H: .BYTE 1 ; Governor integral error (hi byte) +Gov_Integral_X: .BYTE 1 ; Governor integral error (ex byte) +Gov_Proportional_L: .BYTE 1 ; Governor proportional error (lo byte) +Gov_Proportional_H: .BYTE 1 ; Governor proportional error (hi byte) +Gov_Prop_Pwm: .BYTE 1 ; Governor calculated new pwm based upon proportional error +Gov_Arm_Target: .BYTE 1 ; Governor arm target value + +Wt_Advance_L: .BYTE 1 ; Timer3 counts for commutation advance timing (lo byte) +Wt_Advance_H: .BYTE 1 ; Timer3 counts for commutation advance timing (hi byte) +Wt_Zc_Scan_L: .BYTE 1 ; Timer3 counts from commutation to zero cross scan (lo byte) +Wt_Zc_Scan_H: .BYTE 1 ; Timer3 counts from commutation to zero cross scan (hi byte) +Wt_Zc_Timeout_L: .BYTE 1 ; Timer3 counts for zero cross scan timeout (lo byte) +Wt_Zc_Timeout_H: .BYTE 1 ; Timer3 counts for zero cross scan timeout (hi byte) +Wt_Comm_L: .BYTE 1 ; Timer3 counts from zero cross to commutation (lo byte) +Wt_Comm_H: .BYTE 1 ; Timer3 counts from zero cross to commutation (hi byte) + +Rcp_PrePrev_Edge_L: .BYTE 1 ; RC pulse pre previous edge pca timestamp (lo byte) +Rcp_PrePrev_Edge_H: .BYTE 1 ; RC pulse pre previous edge pca timestamp (hi byte) +Rcp_Edge_L: .BYTE 1 ; RC pulse edge pca timestamp (lo byte) +Rcp_Edge_H: .BYTE 1 ; RC pulse edge pca timestamp (hi byte) +Rcp_Prev_Period_L: .BYTE 1 ; RC pulse previous period (lo byte) +Rcp_Prev_Period_H: .BYTE 1 ; RC pulse previous period (hi byte) +Rcp_Period_Diff_Accepted: .BYTE 1 ; RC pulse period difference acceptable +New_Rcp: .BYTE 1 ; New RC pulse value in pca counts +Prev_Rcp_Pwm_Freq: .BYTE 1 ; Previous RC pulse pwm frequency (used during pwm frequency measurement) +Curr_Rcp_Pwm_Freq: .BYTE 1 ; Current RC pulse pwm frequency (used during pwm frequency measurement) +Rcp_Stop_Cnt: .BYTE 1 ; Counter for RC pulses below stop value (lo byte) +Auto_Bailout_Armed: .BYTE 1 ; Set when auto rotation bailout is armed + +Pwm_Limit: .BYTE 1 ; Maximum allowed pwm +Pwm_Limit_Spoolup: .BYTE 1 ; Maximum allowed pwm during spoolup of main +Pwm_Limit_By_Rpm: .BYTE 1 ; Maximum allowed pwm for low or high rpms +Pwm_Spoolup_Beg: .BYTE 1 ; Pwm to begin main spoolup with +Pwm_Motor_Idle: .BYTE 1 ; Motor idle speed pwm +Pwm_Dither_Decoded: .BYTE 1 ; Decoded pwm dither value +Pwm_Dither_Excess_Power: .BYTE 1 ; Excess power (above max) from pwm dither +Random: .BYTE 1 ; Random number from LFSR + +Spoolup_Limit_Cnt: .BYTE 1 ; Interrupt count for spoolup limit +Spoolup_Limit_Skip: .BYTE 1 ; Interrupt skips for spoolup limit increment (1=no skips, 2=skip one etc) +Main_Spoolup_Time_3x: .BYTE 1 ; Main spoolup time x3 +Main_Spoolup_Time_10x: .BYTE 1 ; Main spoolup time x10 +Main_Spoolup_Time_15x: .BYTE 1 ; Main spoolup time x15 + +Lipo_Adc_Limit_L: .BYTE 1 ; Low voltage limit adc value (lo byte) +Lipo_Adc_Limit_H: .BYTE 1 ; Low voltage limit adc value (hi byte) +Adc_Conversion_Cnt: .BYTE 1 ; Adc conversion counter + +Current_Average_Temp_Adc: .BYTE 1 ; Current average temp ADC reading (lo byte of ADC, assuming hi byte is 0) + +Ppm_Throttle_Gain: .BYTE 1 ; Gain to be applied to RCP value for PPM input +Beep_Strength: .BYTE 1 ; Strength of beeps + +Tx_Pgm_Func_No: .BYTE 1 ; Function number when doing programming by tx +Tx_Pgm_Paraval_No: .BYTE 1 ; Parameter value number when doing programming by tx +Tx_Pgm_Beep_No: .BYTE 1 ; Beep number when doing programming by tx +DampingFET: .BYTE 1 ; Port position of fet used for damping + +; The variables below must be in this sequence +Pgm_Gov_P_Gain: .BYTE 1 ; Programmed governor P gain +Pgm_Gov_I_Gain: .BYTE 1 ; Programmed governor I gain +Pgm_Gov_Mode: .BYTE 1 ; Programmed governor mode +Pgm_Low_Voltage_Lim: .BYTE 1 ; Programmed low voltage limit +Pgm_Motor_Gain: .BYTE 1 ; Programmed motor gain +Pgm_Motor_Idle: .BYTE 1 ; Programmed motor idle speed +Pgm_Startup_Pwr: .BYTE 1 ; Programmed startup power +Pgm_Pwm_Freq: .BYTE 1 ; Programmed pwm frequency +Pgm_Direction: .BYTE 1 ; Programmed rotation direction +Pgm_Input_Pol: .BYTE 1 ; Programmed input pwm polarity +Initialized_L_Dummy: .BYTE 1 ; Place holder +Initialized_H_Dummy: .BYTE 1 ; Place holder +Pgm_Enable_TX_Program: .BYTE 1 ; Programmed enable/disable value for TX programming +Pgm_Main_Rearm_Start: .BYTE 1 ; Programmed enable/disable re-arming main every start +Pgm_Gov_Setup_Target: .BYTE 1 ; Programmed main governor setup target +_Pgm_Startup_Rpm: .BYTE 1 ; Programmed startup rpm (unused - place holder) +_Pgm_Startup_Accel: .BYTE 1 ; Programmed startup acceleration (unused - place holder) +_Pgm_Volt_Comp: .BYTE 1 ; Place holder +Pgm_Comm_Timing: .BYTE 1 ; Programmed commutation timing +_Pgm_Damping_Force: .BYTE 1 ; Programmed damping force (unused - place holder) +Pgm_Gov_Range: .BYTE 1 ; Programmed governor range +Pgm_Startup_Method: .BYTE 1 ; Programmed startup method +Pgm_Ppm_Min_Throttle: .BYTE 1 ; Programmed throttle minimum +Pgm_Ppm_Max_Throttle: .BYTE 1 ; Programmed throttle maximum +Pgm_Beep_Strength: .BYTE 1 ; Programmed beep strength +Pgm_Beacon_Strength: .BYTE 1 ; Programmed beacon strength +Pgm_Beacon_Delay: .BYTE 1 ; Programmed beacon delay +_Pgm_Throttle_Rate: .BYTE 1 ; Programmed throttle rate (unused - place holder) +Pgm_Demag_Comp: .BYTE 1 ; Programmed demag compensation +Pgm_BEC_Voltage_High: .BYTE 1 ; Programmed BEC voltage +Pgm_Ppm_Center_Throttle: .BYTE 1 ; Programmed throttle center (in bidirectional mode) +Pgm_Main_Spoolup_Time: .BYTE 1 ; Programmed main spoolup time +Pgm_Enable_Temp_Prot: .BYTE 1 ; Programmed temperature protection enable +Pgm_Enable_Power_Prot: .BYTE 1 ; Programmed low rpm power protection enable +Pgm_Enable_Pwm_Input: .BYTE 1 ; Programmed PWM input signal enable +Pgm_Pwm_Dither: .BYTE 1 ; Programmed output PWM dither +Pgm_Brake_On_Stop: .BYTE 1 ; Programmed braking when throttle is zero + +; The sequence of the variables below is no longer of importance +Pgm_Gov_P_Gain_Decoded: .BYTE 1 ; Programmed governor decoded P gain +Pgm_Gov_I_Gain_Decoded: .BYTE 1 ; Programmed governor decoded I gain +Pgm_Startup_Pwr_Decoded: .BYTE 1 ; Programmed startup power decoded + + +.EQU SRAM_BYTES = 255 ; Bytes used in SRAM. Used for number of bytes to reset + +;**** **** **** **** **** +.ESEG ; Eeprom segment +.ORG 0 + +.EQU EEPROM_FW_MAIN_REVISION = 14 ; Main revision of the firmware +.EQU EEPROM_FW_SUB_REVISION = 9 ; Sub revision of the firmware +.EQU EEPROM_LAYOUT_REVISION = 21 ; 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 0xFF +_Eep_Pgm_Motor_Idle: .DB 0xFF +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: .DB DEFAULT_PGM_MAIN_DIRECTION ; 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 0xA5 ; EEPROM initialized signature low byte +Eep_Initialized_H: .DB 0x5A ; 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 0xFF +_Eep_Pgm_Startup_Accel: .DB 0xFF +_Eep_Pgm_Volt_Comp: .DB 0xFF +Eep_Pgm_Comm_Timing: .DB DEFAULT_PGM_MAIN_COMM_TIMING ; EEPROM copy of programmed commutation timing +_Eep_Pgm_Damping_Force: .DB 0xFF +Eep_Pgm_Gov_Range: .DB DEFAULT_PGM_MAIN_GOVERNOR_RANGE ; EEPROM copy of programmed governor range +_Eep_Pgm_Startup_Method: .DB 0xFF +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 0xFF +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 +_Eep_Pgm_Ppm_Center_Throttle: .DB 0xFF +Eep_Pgm_Main_Spoolup_Time: .DB DEFAULT_PGM_MAIN_SPOOLUP_TIME ; EEPROM copy of programmed main spoolup time +Eep_Pgm_Temp_Prot_Enable: .DB DEFAULT_PGM_ENABLE_TEMP_PROT ; EEPROM copy of programmed temperature protection enable +Eep_Pgm_Enable_Power_Prot: .DB DEFAULT_PGM_ENABLE_POWER_PROT ; EEPROM copy of programmed low rpm power protection enable +Eep_Pgm_Enable_Pwm_Input: .DB DEFAULT_PGM_ENABLE_PWM_INPUT ; EEPROM copy of programmed PWM input signal enable +_Eep_Pgm_Pwm_Dither: .DB 0xFF +Eep_Pgm_Brake_On_Stop: .DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero +.ENDIF + +.IF MODE == 1 +_Eep_Pgm_Gov_P_Gain: .DB 0xFF +_Eep_Pgm_Gov_I_Gain: .DB 0xFF +_Eep_Pgm_Gov_Mode: .DB 0xFF +_Eep_Pgm_Low_Voltage_Lim: .DB 0xFF +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: .DB DEFAULT_PGM_TAIL_DIRECTION ; 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 0x5A ; EEPROM initialized signature low byte +Eep_Initialized_H: .DB 0xA5 ; EEPROM initialized signature high byte +Eep_Enable_TX_Program: .DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable +_Eep_Main_Rearm_Start: .DB 0xFF +_Eep_Pgm_Gov_Setup_Target: .DB 0xFF +_Eep_Pgm_Startup_Rpm: .DB 0xFF +_Eep_Pgm_Startup_Accel: .DB 0xFF +_Eep_Pgm_Volt_Comp: .DB 0xFF +Eep_Pgm_Comm_Timing: .DB DEFAULT_PGM_TAIL_COMM_TIMING ; EEPROM copy of programmed commutation timing +_Eep_Pgm_Damping_Force: .DB 0xFF +_Eep_Pgm_Gov_Range: .DB 0xFF +_Eep_Pgm_Startup_Method: .DB 0xFF +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 0xFF +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 +Eep_Pgm_Ppm_Center_Throttle: .DB DEFAULT_PGM_PPM_CENTER_THROTTLE ; EEPROM copy of programmed center throttle (final value is 4x+1000=1488) +_Eep_Pgm_Main_Spoolup_Time: .DB 0xFF +Eep_Pgm_Temp_Prot_Enable: .DB DEFAULT_PGM_ENABLE_TEMP_PROT ; EEPROM copy of programmed temperature protection enable +Eep_Pgm_Enable_Power_Prot: .DB DEFAULT_PGM_ENABLE_POWER_PROT ; EEPROM copy of programmed low rpm power protection enable +Eep_Pgm_Enable_Pwm_Input: .DB DEFAULT_PGM_ENABLE_PWM_INPUT ; EEPROM copy of programmed PWM input signal enable +Eep_Pgm_Pwm_Dither: .DB DEFAULT_PGM_TAIL_PWM_DITHER ; EEPROM copy of programmed output PWM dither +Eep_Pgm_Brake_On_Stop: .DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero +.ENDIF + +.IF MODE == 2 +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 0xFF +Eep_Pgm_Motor_Gain: .DB DEFAULT_PGM_MULTI_GAIN ; EEPROM copy of programmed tail gain +_Eep_Pgm_Motor_Idle: .DB 0xFF ; 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: .DB DEFAULT_PGM_MULTI_DIRECTION ; 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 0x55 ; EEPROM initialized signature low byte +Eep_Initialized_H: .DB 0xAA ; EEPROM initialized signature high byte +Eep_Enable_TX_Program: .DB DEFAULT_PGM_ENABLE_TX_PROGRAM ; EEPROM TX programming enable +_Eep_Main_Rearm_Start: .DB 0xFF +_Eep_Pgm_Gov_Setup_Target: .DB 0xFF +_Eep_Pgm_Startup_Rpm: .DB 0xFF +_Eep_Pgm_Startup_Accel: .DB 0xFF +_Eep_Pgm_Volt_Comp: .DB 0xFF +Eep_Pgm_Comm_Timing: .DB DEFAULT_PGM_MULTI_COMM_TIMING ; EEPROM copy of programmed commutation timing +_Eep_Pgm_Damping_Force: .DB 0xFF +_Eep_Pgm_Gov_Range: .DB 0xFF +_Eep_Pgm_Startup_Method: .DB 0xFF +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 0xFF +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 +Eep_Pgm_Ppm_Center_Throttle: .DB DEFAULT_PGM_PPM_CENTER_THROTTLE ; EEPROM copy of programmed center throttle (final value is 4x+1000=1488) +_Eep_Pgm_Main_Spoolup_Time: .DB 0xFF +Eep_Pgm_Temp_Prot_Enable: .DB DEFAULT_PGM_ENABLE_TEMP_PROT ; EEPROM copy of programmed temperature protection enable +Eep_Pgm_Enable_Power_Prot: .DB DEFAULT_PGM_ENABLE_POWER_PROT ; EEPROM copy of programmed low rpm power protection enable +Eep_Pgm_Enable_Pwm_Input: .DB DEFAULT_PGM_ENABLE_PWM_INPUT ; EEPROM copy of programmed PWM input signal enable +Eep_Pgm_Pwm_Dither: .DB DEFAULT_PGM_MULTI_PWM_DITHER ; EEPROM copy of programmed output PWM dither +Eep_Pgm_Brake_On_Stop: .DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero +.ENDIF + + +Eep_Dummy: .DB 0xFF ; EEPROM address for safety reason + +.ORG 0x60 +Eep_Name: .DB " " ; Name tag (16 Bytes) + +;**** **** **** **** **** +.CSEG ; Code segment +.ORG 0 + +Interrupt_Table_Definition ; ATmega interrupts + +;**** **** **** **** **** + +; Table definitions +GOV_GAIN_TABLE: .DB 0x02, 0x03, 0x04, 0x06, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40, 0x60, 0x80, 0 ; Padded zero for an even number +STARTUP_POWER_TABLE: .DB 0x04, 0x06, 0x08, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0 ; Padded zero for an even number +PWM_DITHER_TABLE: .DB 0x00, 0x03, 0x07, 0x0F, 0x1F, 0 ; Padded zero for an even number +.IF MODE == 0 + .IF DAMPED_MODE_ENABLE == 1 +TX_PGM_PARAMS_MAIN: .DB 13, 13, 4, 3, 6, 13, 5, 3, 3, 2, 2, 0 ; Padded zero for an even number + .ENDIF + .IF DAMPED_MODE_ENABLE == 0 +TX_PGM_PARAMS_MAIN: .DB 13, 13, 4, 3, 6, 13, 5, 2, 3, 2, 2, 0 ; Padded zero for an even number + .ENDIF +.ENDIF +.IF MODE == 1 + .IF DAMPED_MODE_ENABLE == 1 +TX_PGM_PARAMS_TAIL: .DB 5, 5, 13, 5, 3, 5, 3, 3, 2, 0 ; Padded zero for an even number + .ENDIF + .IF DAMPED_MODE_ENABLE == 0 +TX_PGM_PARAMS_TAIL: .DB 5, 5, 13, 5, 2, 5, 3, 3, 2, 0 ; Padded zero for an even number + .ENDIF +.ENDIF +.IF MODE == 2 + .IF DAMPED_MODE_ENABLE == 1 +TX_PGM_PARAMS_MULTI: .DB 13, 13, 4, 5, 13, 5, 3, 5, 3, 3, 2, 0 ; Padded zero for an even number + .ENDIF + .IF DAMPED_MODE_ENABLE == 0 +TX_PGM_PARAMS_MULTI: .DB 13, 13, 4, 5, 13, 5, 2, 5, 3, 3, 2, 0 ; Padded zero for an even number + .ENDIF +.ENDIF + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Timer2 interrupt routine +; +; Assumptions: Z register must be set to desired pwm_nfet_on label +; Requirements: I_Temp variables can NOT be used +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +t2_int: ; Used for pwm control + in II_Sreg, SREG + ; Check if pwm is on + sbrc Flags0, PWM_ON ; Is pwm on? + rjmp t2_int_pwm_off + + ; Pwm on cycle + tst Current_Pwm_Limited + breq t2_int_pwm_on_ret + + ijmp ; Jump to pwm on routines. Z should be set to one of the pwm_nfet_on labels + +t2_int_pwm_on_exit: + ; Set timer for coming on cycle length + mov YL, Current_Pwm_Limited ; Load current pwm + com YL ; com is 255-x + sec + sbrc Flags2, PGM_PWM_HIGH_FREQ ; Use half the time when pwm frequency is high + ror YL + Set_TCNT2 YL ; Write start point for timer + ; Set other variables + sbr Flags0, (1<= 128 ; "Negative", 1's complement + sbrc Flags1, SKIP_DAMP_ON + rjmp t2_int_pwm_off_damp_done + sbrc Flags0, DEMAG_CUT_POWER + rjmp t2_int_pwm_off_damp_done + Damping_FET_on YL ; Damping fet on + ldi YL, PFETON_DELAY + com YL + dec YL + brne PC-1 +t2_int_pwm_off_damp_done: + All_nFETs_Off ; Switch off all nfets +.ENDIF +t2_int_pwm_off_exit: + out SREG, II_Sreg + reti + +t2_int_pwm_off_fullpower_exit: + Set_TCNT2 Zero ; Write start point for timer + T2_Clear_Int_Flag YL ; Clear interrupt flag + sbr Flags0, (1<= 1 ; Tail or multi + ; Boost pwm during direct start + mov XL, Flags1 + andi XL, ((1<= 1 ; Tail or multi + ; Set current_pwm_limited + lds I_Temp1, Current_Pwm ; Default not limited + lds XL, Pwm_Limit ; Check against limit + cp I_Temp1, XL + brcs PC+2 ; If current pwm below limit - branch + + mov I_Temp1, XL ; Limit pwm + +.IF MODE == 2 ; Multi + ; Limit pwm for low rpms + lds XL, Pwm_Limit_By_Rpm ; Check against limit + cp I_Temp1, XL + brcs PC+2 ; If current pwm below limit - branch + + mov I_Temp1, XL ; Limit pwm +.ENDIF + + mov Current_Pwm_Limited, I_Temp1 + ; Dither + lds XL, Pwm_Dither_Decoded ; Load pwm dither + tst XL + brne PC+2 ; If active - branch + rjmp t0_int_current_pwm_no_dither + + mov I_Temp2, I_Temp1 + sub I_Temp2, XL ; Calculate pwm minus dither value + brcc t0_int_current_pwm_full_dither; If pwm more than dither value, then do full dither + + mov XL, I_Temp1 ; Set dither level to current pwm + ldi I_Temp2, 0 ; Set pwm minus dither + +t0_int_current_pwm_full_dither: + mov I_Temp4, XL ; Store dither value in I_Temp4 + clc + rol XL ; Shift left once + mov I_Temp3, XL + lds XL, Random ; Load random number + com XL ; Invert to create proper DC bias in random code + and I_Temp3, XL ; And with double dither value + add I_Temp3, I_Temp2 ; Add pwm minus dither + brcs t0_int_current_pwm_dither_max_excess_power ; If dither cause power above max - branch and increase excess + + lds XL, Pwm_Dither_Excess_Power ; Get excess power + cp XL, Zero ; Decrement excess power + breq PC+2 + dec XL + add I_Temp3, XL ; Add excess power from previous cycles + sts Pwm_Dither_Excess_Power, XL + brcs t0_int_current_pwm_dither_max_power; If dither cause power above max - branch + + mov I_Temp1, I_Temp3 + rjmp t0_int_current_pwm_no_dither + +t0_int_current_pwm_dither_max_excess_power: + lds XL, Pwm_Dither_Excess_Power + cp I_Temp4, XL ; Limit excess power to one above in order to always reach max power + brcs PC+2 + inc XL + sts Pwm_Dither_Excess_Power, XL + +t0_int_current_pwm_dither_max_power: + ldi I_Temp1, 255 ; Set power to max + +t0_int_current_pwm_no_dither: + sts Current_Pwm_Lim_Dith, I_Temp1 +.IF DAMPED_MODE_ENABLE == 1 + ; Skip damping fet switching for high throttle + cbr Flags1, (1<= 1 ; Tail or multi + cpi I_Temp2, 3 + brne PC+3 ; No - branch + + lds I_Temp3, Pgm_Ppm_Center_Throttle ; Center throttle value is in 4us units + +.ENDIF +rcp_int_ppm_calculate: + ldi XL, 250 ; Add 1000us to minimum + add I_Temp3, XL + mov XL, Zero + adc XL, Zero + sub I_Temp5, I_Temp3 ; Subtract minimum + sbc I_Temp6, XL + in I_Temp1, SREG + andi I_Temp1, (1<= 1 ; Tail or multi + cpi I_Temp2, 3 ; Check if bidirectional operation + brne rcp_int_ppm_bidir_dir_set ; No - branch + + tst I_Temp1 + breq rcp_int_ppm_bidir_fwd ; If result is positive - branch + + sbrc Flags2, RCP_DIR_REV + rjmp rcp_int_ppm_bidir_dir_set ; If same direction - branch + + sbr Flags2, (1<= 1 ; Tail or multi + cpi I_Temp2, 3 ; Check if bidirectional operation + brne rcp_int_ppm_unidir_neg ; No - branch + + ldi XL, 0xFF ; Change sign - invert and subtract minus one + com I_Temp5 + com I_Temp6 + sub I_Temp5, XL + sbc I_Temp6, XL + rjmp rcp_int_ppm_neg_checked + +rcp_int_ppm_unidir_neg: +.ENDIF + ldi I_Temp1, RCP_MIN ; Yes - set to minimum + ldi I_Temp2, 0 + rjmp rcp_int_pwm_divide_done + +rcp_int_ppm_neg_checked: +.IF MODE >= 1 ; Tail or multi + cpi I_Temp2, 3 ; Check if bidirectional operation + brne rcp_int_ppm_bidir_done ; No - branch + + lsl I_Temp5 ; Multiply value by 2 + rol I_Temp6 + ldi XL, 10 ; Subtract deadband + sub I_Temp5, XL + sbc I_Temp6, Zero + brcc rcp_int_ppm_bidir_done + + ldi XL, RCP_MIN + mov I_Temp5, XL + mov I_Temp6, Zero + +rcp_int_ppm_bidir_done: +.ENDIF + ldi XL, RCP_MAX ; Check that RC pulse is within legal range (max 255) + cp I_Temp5, XL + cpc I_Temp6, Zero + brcs rcp_int_ppm_max_checked + + ldi I_Temp1, RCP_MAX + ldi I_Temp2, 0 + rjmp rcp_int_pwm_divide_done + +rcp_int_ppm_max_checked: + lds XL, Ppm_Throttle_Gain ; Multiply throttle value by gain + mul I_Temp5, XL + mov I_Temp1, Mul_Res_H ; Transfer result + lsl Mul_Res_L ; Multiply result by 2 (unity gain is 128) + rol I_Temp1 + ldi I_Temp2, 0 + brcs rcp_int_ppm_limit_after_mult + + rjmp rcp_int_limited + +rcp_int_ppm_limit_after_mult: + ldi I_Temp1, RCP_MAX + ldi I_Temp2, 0 + rjmp rcp_int_limited + +rcp_int_pwm_divide: + lsr I_Temp2 ; Divide by 2 + ror I_Temp1 + +rcp_int_pwm_divide_done: + sbrs Flags3, RCP_PWM_FREQ_12KHZ ; Is RC input pwm frequency 12kHz? + rjmp rcp_int_check_legal_range + + tst I_Temp2 ; Yes - check that value is not more than 255 + breq PC+2 + + ldi I_Temp1, RCP_MAX + + mov XL, I_Temp1 ; Multiply by 1.5 + lsr XL + add I_Temp1, XL + adc I_Temp2, Zero + +rcp_int_check_legal_range: + ; Check that RC pulse is within legal range + cpi I_Temp1, RCP_MAX + cpc I_Temp2, Zero + brcs rcp_int_limited + + ldi I_Temp1, RCP_MAX + +rcp_int_limited: + ; RC pulse value accepted + sts New_Rcp, I_Temp1 ; Store new pulse length + sbr Flags2, (1<= 1 ; Tail or multi + ; If not supported, then exit + rjmp measure_lipo_exit +.ENDIF +.IF MODE == 0 ; Main + ; Set commutation to BpFET on + xcall comm5comm6 + ; Start adc + Start_Adc XH + ; Wait for ADC reference to settle, and then start again + xcall wait1ms + Start_Adc XH + ; Wait for ADC conversion to complete +measure_lipo_wait_adc: + Get_Adc_Status XH + sbrc XH, ADSC + rjmp measure_lipo_wait_adc + ; Read ADC result + Read_Adc_Result Temp1, Temp2 + ; Stop ADC + Stop_Adc XH + ; Switch power off + xcall switch_power_off + ; Set limit step + ldi Temp3, ADC_LIMIT_L + sts Lipo_Adc_Limit_L, Temp3 + tst Temp3 + brne PC+2 + rjmp measure_lipo_exit ; Exit if disabled + + ldi Temp4, ADC_LIMIT_H + sts Lipo_Adc_Limit_H, Temp4 + mov Temp6, Temp4 ; Divide 3.0V value by 2 + lsr Temp6 + mov Temp5, Temp3 + lsr Temp5 + add Temp5, Temp3 ; Calculate 1.5*3.0V=4.5V value + adc Temp6, Temp4 + mov Temp3, Temp5 ; Copy step + mov Temp4, Temp6 +measure_lipo_cell_loop: + ; Check voltage against xS lower limit + cp Temp1, Temp3 ; Voltage above limit? + cpc Temp2, Temp4 + brcs measure_lipo_adjust ; No - branch + + ; Set xS voltage limit + lds Temp7, Lipo_Adc_Limit_L + ldi XH, ADC_LIMIT_L + add XH, Temp7 + sts Lipo_Adc_Limit_L, XH + lds Temp7, Lipo_Adc_Limit_H + ldi XH, ADC_LIMIT_H + adc XH, Temp7 + sts Lipo_Adc_Limit_H, XH + ; Set (x+1)S lower limit + add Temp3, Temp5 ; Add step + adc Temp4, Temp6 + rjmp measure_lipo_cell_loop ; Check for one more battery cell + +measure_lipo_adjust: + lds Temp7, Lipo_Adc_Limit_L + lds Temp8, Lipo_Adc_Limit_H + ; Calculate 3.125% + lds Temp2, Lipo_Adc_Limit_H + lsr Temp2 + lds Temp1, Lipo_Adc_Limit_L + ror Temp1 ; After this 50% + lsr Temp2 + ror Temp1 ; After this 25% + ; Divide three times to get to 3.125% + ldi Temp3, 3 +measure_lipo_divide_loop: + lsr Temp2 + ror Temp1 + dec Temp3 + brne measure_lipo_divide_loop + + ; Add the programmed number of 0.1V (or 3.125% increments) + lds Temp3, Pgm_Low_Voltage_Lim ; Load programmed limit + dec Temp3 + brne measure_lipo_limit_on ; Is low voltage limiting on? + + sts Lipo_Adc_Limit_L, Zero ; No - set limit to zero + sts Lipo_Adc_Limit_H, Zero + rjmp measure_lipo_exit + +measure_lipo_limit_on: + dec Temp3 + breq measure_lipo_update + +measure_lipo_add_loop: + add Temp7, Temp1 ; Add 3.125% + adc Temp8, Temp2 + dec Temp3 + brne measure_lipo_add_loop + +measure_lipo_update: + ; Set ADC limit + sts Lipo_Adc_Limit_L, Temp7 + sts Lipo_Adc_Limit_H, Temp8 +.ENDIF +measure_lipo_exit: + 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 + lds Temp3, Pgm_Low_Voltage_Lim ; Store in Temp3 + ; Wait for ADC conversion to complete + Get_Adc_Status XH + sbrc XH, ADSC + rjmp check_temp_voltage_and_limit_power + ; Read ADC result + Read_Adc_Result Temp1, Temp2 + ; Stop ADC + Stop_Adc XH + lds XH, Adc_Conversion_Cnt ; Increment conversion counter + inc XH + sts Adc_Conversion_Cnt, XH + cpi XH, TEMP_CHECK_RATE ; Is conversion count equal to temp rate? + brcs check_voltage_start ; No - check voltage + + sts Adc_Conversion_Cnt, Zero ; Yes - temperature check. Reset counter + lds XH, Pgm_Enable_Temp_Prot ; Is temp protection enabled? + tst XH + breq temp_check_exit ; No - branch + + tst Temp2 ; Is temperature ADC reading below 256? + breq temp_average_inc_dec ; Yes - proceed + + lds XH, Current_Average_Temp_Adc ; No - increment average + cpi XH, 0xFF + breq temp_average_updated ; Already max - no change + rjmp temp_average_inc ; Increment + +temp_average_inc_dec: + lds XH, Current_Average_Temp_Adc ; Check if current temp ADC is above or below average + cp Temp1, XH + breq temp_average_updated ; Equal - no change + + brcc temp_average_inc ; Above - increment average + + tst XH ; Below - decrement average if average is not already zero + breq temp_average_updated +temp_average_dec: + dec XH ; Decrement average + rjmp temp_average_updated + +temp_average_inc: + inc XH ; Increment average + breq temp_average_dec + +temp_average_updated: + lds Temp1, Pwm_Limit + sts Current_Average_Temp_Adc, XH + cpi XH, TEMP_LIMIT ; Is temp ADC above first limit? + brcc temp_check_set_limit ; Yes - exit + + ldi Temp1, 192 ; No - limit pwm + + cpi XH, (TEMP_LIMIT-TEMP_LIMIT_STEP) ; Is temp ADC above second limit + brcc temp_check_set_limit ; Yes - exit + + ldi Temp1, 128 ; No - limit pwm + + cpi XH, (TEMP_LIMIT-2*TEMP_LIMIT_STEP) ; Is temp ADC above third limit + brcc temp_check_set_limit ; Yes - exit + + ldi Temp1, 64 ; No - limit pwm + + cpi XH, (TEMP_LIMIT-3*TEMP_LIMIT_STEP) ; Is temp ADC above final limit + brcc temp_check_set_limit ; Yes - exit + + ldi Temp1, 0 ; No - limit pwm + +temp_check_set_limit: + sts Pwm_Limit, Temp1 ; Set pwm limit +temp_check_exit: + Set_Adc_Ip_Volt ; Select adc input for next conversion + ret + +check_voltage_start: +.IF MODE == 0 ; Main + ; Check if low voltage limiting is enabled + cpi Temp3, 1 ; Is low voltage limit disabled? + breq check_voltage_good ; Yes - voltage declared good + + ; Check if ADC is saturated + cpi Temp1, 0xFF + ldi XH, 3 + cpc Temp2, XH + brcc check_voltage_good ; ADC saturated, can not make judgement + + ldi XH, ADC_LIMIT_L ; Is low voltage limit zero (ESC does not support it)? + tst XH + breq check_voltage_good ; Yes - voltage declared good + + ; Check voltage against limit + lds XH, Lipo_Adc_Limit_L + cp Temp1, XH + lds XH, Lipo_Adc_Limit_H + cpc Temp2, XH + brcc check_voltage_good ; If voltage above limit - branch + + ; Decrease pwm limit + lds XH, Pwm_Limit + tst XH + breq check_voltage_lim ; If limit zero - branch + + dec XH ; Decrement limit + sts Pwm_Limit, XH + rjmp check_voltage_lim + +check_voltage_good: + ; Increase pwm limit + lds XH, Pwm_Limit + cpi XH, 0xFF + breq check_voltage_lim ; If limit max - branch + + inc XH ; Increment limit + sts Pwm_Limit, XH + +check_voltage_lim: + lds Temp1, Pwm_Limit ; Set limit + lds XH, Current_Pwm + sub XH, Temp1 + brcc check_voltage_spoolup_lim ; If current pwm above limit - branch and limit + + lds Temp1, Current_Pwm ; Set current pwm (no limiting) + +check_voltage_spoolup_lim: + ; Slow spoolup + lds XH, Pwm_Limit_Spoolup + cp Temp1, XH + brcs check_voltage_exit ; If current pwm below limit - branch + + lds Temp1, Pwm_Limit_Spoolup + lds XH, Pwm_Limit_Spoolup ; Check if spoolup limit is max + cpi XH, 0xFF + breq check_voltage_exit ; If max - branch + + lds XH, Pwm_Limit_Spoolup ; Set pwm limit to spoolup limit during ramp (to avoid governor integral buildup) + sts Pwm_Limit, XH + +check_voltage_exit: + mov Current_Pwm_Limited, Temp1 + sts Current_Pwm_Lim_Dith, Temp1 +.ENDIF +.IF MODE == 1 ; Tail + ; Increase pwm limit + lds XH, Pwm_Limit + inc XH + breq check_voltage_lim ; If limit max - branch + + sts Pwm_Limit, XH ; Increment limit + +check_voltage_lim: +.ENDIF +.IF MODE == 2 ; Multi + ; Increase pwm limit + lds Temp2, Pwm_Limit + ldi XH, 16 + add Temp2, XH + brcc PC+2 ; If not max - branch + + ldi Temp2, 255 + + sts Pwm_Limit, Temp2 ; Increment limit + ; Set current pwm limited if closed loop mode + lds XH, Pgm_Gov_Mode ; Governor mode? + cpi XH, 4 + breq check_voltage_pwm_done ; No - branch + + lds Temp1, Pwm_Limit ; Set limit + lds XH, Current_Pwm + sub XH, Temp1 + brcc check_voltage_low_rpm ; If current pwm above limit - branch and limit + + lds Temp1, Current_Pwm ; Set current pwm (no limiting) + +check_voltage_low_rpm: + ; Limit pwm for low rpms + lds XH, Pwm_Limit_By_Rpm ; Check against limit + cp Temp1, XH + brcs PC+2 ; If current pwm below limit - branch + + mov Temp1, XH ; Limit pwm + + mov Current_Pwm_Limited, Temp1 + sts Current_Pwm_Lim_Dith, Temp1 +check_voltage_pwm_done: +.ENDIF + ; Set adc mux for next conversion + lds XH, Adc_Conversion_Cnt ; Is next conversion for temperature? + cpi XH, (TEMP_CHECK_RATE-1) + brne check_voltage_ret + + Set_Adc_Ip_Temp ; Select temp sensor for next conversion + +check_voltage_ret: + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Set startup PWM routine +; +; No assumptions +; +; Used for pwm control during startup +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +set_startup_pwm: + ; Adjust startup power + ldi Temp1, PWM_START ; Set power + cli ; Disable interrupts in order to avoid interference with mul ops in interrupt routines + lds XH, Pgm_Startup_Pwr_Decoded ; Multiply startup power by programmed value + mul Temp1, XH + mov Temp1, Mul_Res_H ; Transfer result + lsl Mul_Res_L ; Multiply result by 2 (unity gain is 128) + rol Temp1 + sei + lds XH, Pwm_Limit ; Check against limit + cp Temp1, XH + brcs startup_pwm_set_pwm ; If pwm below limit - branch + + lds Temp1, Pwm_Limit ; Limit pwm + +startup_pwm_set_pwm: + ; Set pwm variables + sts Requested_Pwm, Temp1 ; Update requested pwm + sts Current_Pwm, Temp1 ; Update current pwm + mov Current_Pwm_Limited, Temp1 ; Update limited version of current pwm + sts Current_Pwm_Lim_Dith, Temp1 + sts Pwm_Spoolup_Beg, Temp1 ; Update spoolup beginning pwm + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Initialize timing routine +; +; No assumptions +; +; Part of initialization before motor start +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +initialize_timing: + sts Comm_Period4x_L, Zero ; Set commutation period registers + ldi XH, 0xF0 + sts Comm_Period4x_H, XH + ret + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Calculate next commutation timing routine +; +; No assumptions +; +; Called immediately after each commutation +; Also sets up timer 1 to wait advance timing +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +calc_next_comm_timing: ; Entry point for run phase + ; Read commutation time + cli ; Disable interrupts while reading timer 1 + Read_TCNT1L Temp1 + Read_TCNT1H Temp2 + lds Temp3, Timer2_X + sei + ; Calculate this commutation time + lds Temp4, Prev_Comm_L + lds Temp5, Prev_Comm_H + sts Prev_Comm_L, Temp1 ; Store timestamp as previous commutation + sts Prev_Comm_H, Temp2 + sub Temp1, Temp4 ; Calculate the new commutation time + sbc Temp2, Temp5 + sbrc Flags1, STARTUP_PHASE + rjmp calc_next_comm_startup + + sbrc Flags1, HIGH_RPM ; Branch if high rpm + rjmp calc_next_comm_timing_fast + + rjmp calc_next_comm_normal + +calc_next_comm_startup: + lds Temp6, Prev_Comm_X + sts Prev_Comm_X, Temp3 ; Store extended timestamp as previous commutation + sbc Temp3, Temp6 ; Calculate the new extended commutation time + tst Temp3 + breq calc_next_comm_startup_no_X + + ldi Temp1, 0xFF + ldi Temp2, 0xFF +rjmp calc_next_comm_startup_average + +calc_next_comm_startup_no_X: + lds Temp7, Prev_Prev_Comm_L + lds Temp8, Prev_Prev_Comm_H + sts Prev_Prev_Comm_L, Temp4 + sts Prev_Prev_Comm_H, Temp5 + lds Temp1, Prev_Comm_L ; Reload this commutation time + lds Temp2, Prev_Comm_H + sub Temp1, Temp7 ; Calculate the new commutation time based upon the two last commutations (to reduce sensitivity to offset) + sbc Temp2, Temp8 + +calc_next_comm_startup_average: + lds Temp3, Comm_Period4x_L ; Average with previous and save + lds Temp4, Comm_Period4x_H + lsr Temp4 + ror Temp3 + add Temp1, Temp3 + adc Temp2, Temp4 + brcc PC+3 + + ldi Temp1, 0xFF + ldi Temp2, 0xFF + + sts Comm_Period4x_L, Temp1 + sts Comm_Period4x_H, Temp2 + rjmp calc_new_wait_times_setup + +calc_next_comm_normal: + ; Calculate new commutation time + lds Temp3, Comm_Period4x_L ; Comm_Period4x(-l-h) holds the time of 4 commutations + lds Temp4, Comm_Period4x_H + movw Temp5, Temp3 ; Copy variables + ldi XH, 4 ; Divide Comm_Period4x 4 times as default + mov Temp7, XH + ldi XH, 2 ; Divide new commutation time 2 times as default + mov Temp8, XH + cpi Temp4, 0x04 + brcs calc_next_comm_avg_period_div + + dec Temp7 ; Reduce averaging time constant for low speeds + dec Temp8 + + cpi Temp4, 0x08 + brcs calc_next_comm_avg_period_div + + sbrc Flags1, INITIAL_RUN_PHASE + rjmp calc_next_comm_avg_period_div ; Do not average very fast during initial run + + dec Temp7 ; Reduce averaging time constant more for even lower speeds + dec Temp8 + +calc_next_comm_avg_period_div: + lsr Temp6 ; Divide by 2 + ror Temp5 + dec Temp7 + brne calc_next_comm_avg_period_div + + sub Temp3, Temp5 ; Subtract a fraction + sbc Temp4, Temp6 + + tst Temp8 ; Divide new time + breq calc_next_comm_new_period_div_done + +calc_next_comm_new_period_div: + lsr Temp2 ; Divide by 2 + ror Temp1 + dec Temp8 + brne calc_next_comm_new_period_div + +calc_next_comm_new_period_div_done: + add Temp3, Temp1 ; Add the divided new time + adc Temp4, Temp2 + sts Comm_Period4x_L, Temp3 ; Store Comm_Period4x_X + sts Comm_Period4x_H, Temp4 + brcc calc_new_wait_times_setup; If period larger than 0xffff - go to slow case + + ldi Temp4, 0xFF + sts Comm_Period4x_L, Temp4 ; Set commutation period registers to very slow timing (0xffff) + sts Comm_Period4x_H, Temp4 + +calc_new_wait_times_setup: + ; Set high rpm bit (if above 156k erpm) + cpi Temp4, 2 + brcc PC+2 + + sbr Flags1, (1<35) causes the RCT4215 630 to run rough on full throttle + lds Temp1, Comm_Period4x_H ; Set number of readings higher for lower speeds + lsr Temp1 + brne PC+2 + inc Temp1 + cpi Temp1, 15 + brcs PC+2 + + ldi Temp1, 15 + + sbrs Flags1, STARTUP_PHASE ; Branch if not startup + rjmp comp_check_timeout + + ldi Temp1, 20 ; Set many samples during startup, approximately one pwm period + ldi Temp2, 20 + +comp_check_timeout: + sbrc Flags0, OC1A_PENDING ; Has zero cross scan timeout elapsed? + rjmp comp_check_timeout_not_timed_out + + lds XH, Comparator_Read_Cnt ; Check that comparator has been read + tst XH + breq comp_check_timeout_not_timed_out ; If not read - branch + + sbrs Flags1, STARTUP_PHASE ; Extend timeout during startup + rjmp comp_check_timeout_timeout_extended + + lds XH, Startup_Zc_Timeout_Cntd + dec XH + sts Startup_Zc_Timeout_Cntd, XH + brne comp_check_timeout_extend_timeout + +comp_check_timeout_timeout_extended: + sbr Flags1, (1<= 1 ; Tail or multi + cpi XH, 3 + breq decode_params_dir_set +.ENDIF + + cbr Flags3, (1<= 1 ; Tail or multi + lds XH, Pgm_Direction ; Check if bidirectional operation + cpi XH, 3 + brne PC+2 + + rjmp program_by_tx_checked ; Disable tx programming if bidirectional operation +.ENDIF + + xcall wait3ms + lds XH, Pgm_Enable_TX_Program; Start programming mode entry if enabled + cpi XH, 1 ; Is TX programming enabled? + brcc arming_initial_arm_check ; Yes - proceed + + rjmp program_by_tx_checked ; No - branch + +arming_initial_arm_check: + lds XH, Initial_Arm ; Yes - check if it is initial arm sequence + cpi XH, 1 ; Is it the initial arm sequence? + brcc arming_ppm_check ; Yes - proceed + + rjmp program_by_tx_checked ; No - branch + +arming_ppm_check: + sbrc Flags2, RCP_PPM + rjmp throttle_high_cal_start ; If flag is set (PPM) - branch + + ; PWM tx program entry + lds XH, New_Rcp ; Load new RC pulse value + cpi XH, RCP_MAX ; Is RC pulse max? + brcc program_by_tx_entry_pwm ; Yes - proceed + + rjmp program_by_tx_checked ; No - branch + +program_by_tx_entry_pwm: + cli ; Disable all interrupts + xcall beep_f4 + sei ; Enable all interrupts + xcall wait100ms + lds XH, New_Rcp ; Load new RC pulse value + cpi XH, RCP_STOP ; Below stop? + brcc program_by_tx_entry_pwm ; No - start over + +program_by_tx_entry_wait_pwm: + cli ; Disable all interrupts + xcall beep_f1 + xcall wait10ms + xcall beep_f1 + sei ; Enable all interrupts + xcall wait100ms + lds XH, New_Rcp ; Load new RC pulse value + cpi XH, RCP_MAX ; At or above max? + brcs program_by_tx_entry_wait_pwm ; No - start over + + rjmp program_by_tx ; Yes - enter programming mode + + ; PPM throttle calibration and tx program entry +throttle_high_cal_start: +.IF MODE <= 1 ; Main or tail + ldi XH, 8 ; Set 3 seconds wait time +.ELSE + ldi XH, 3 ; Set 1 second wait time +.ENDIF + mov Temp8, XH +throttle_high_cal: + sbr Flags3, (1<= 1 ; Tail or multi + lds XH, Pgm_Direction ; Check if bidirectional operation + subi XH, 3 + breq wait_for_power_on_check_timeout ; Do not wait if bidirectional operation +.ENDIF + + xcall wait100ms ; Wait to see if start pulse was only a glitch + +wait_for_power_on_check_timeout: + lds XH, Rcp_Timeout_Cntd ; Load RC pulse timeout counter value + tst XH + brne PC+2 ; If it is not zero - proceed + + rjmp init_no_signal ; If it is zero (pulses missing) - go back to detect input signal + + + +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Start entry point +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +init_start: + cli + xcall switch_power_off + sts Requested_Pwm, Zero ; Set requested pwm to zero + sts Governor_Req_Pwm, Zero ; Set governor requested pwm to zero + sts Current_Pwm, Zero ; Set current pwm to zero + mov Current_Pwm_Limited, Zero; Set limited current pwm to zero + sts Current_Pwm_Lim_Dith, Zero + sts Pwm_Dither_Excess_Power, Zero + sei + lds XH, Pgm_Motor_Idle ; Set idle pwm to programmed value + lsl XH + sts Pwm_Motor_Idle, XH + sts Gov_Target_L, Zero ; Set target to zero + sts Gov_Target_H, Zero + sts Gov_Integral_L, Zero ; Set integral to zero + sts Gov_Integral_H, Zero + sts Gov_Integral_X, Zero + sts Adc_Conversion_Cnt, Zero + ldi Flags0, 0 ; Clear flags0 + ldi Flags1, 0 ; Clear flags1 + sts Demag_Detected_Metric, Zero ; Clear demag metric + ;**** **** **** **** **** + ; Motor start beginning + ;**** **** **** **** **** + ldi XH, TEMP_CHECK_RATE ; Make sure a temp reading is done + sts Adc_Conversion_Cnt, XH + Set_Adc_Ip_Temp + xcall wait1ms + Start_Adc XH +read_initial_temp: + Get_Adc_Status XH + sbrc XH, ADSC + rjmp read_initial_temp + Read_Adc_Result Temp1, Temp2 ; Read initial temperature + Stop_Adc XH + tst Temp2 + breq PC+2 ; Is reading below 256? + + ldi Temp1, 0xFF ; No - set average temperature value to 255 + + sts Current_Average_Temp_Adc, Temp1 ; Set initial average temp ADC reading + xcall check_temp_voltage_and_limit_power + ldi XH, TEMP_CHECK_RATE ; Make sure a temp reading is done next time + sts Adc_Conversion_Cnt, XH + Set_Adc_Ip_Temp + ; Set up start operating conditions + xcall decode_parameters ; (Decode_parameters uses Temp1 and Temp8) + ; Set max allowed power + cli ; Disable interrupts to avoid that Requested_Pwm is overwritten + ldi XH, 0xFF ; Set pwm limit to max + sts Pwm_Limit, XH + xcall set_startup_pwm + lds XH, Requested_Pwm + sts Pwm_Limit, XH + sts Pwm_Limit_Spoolup, XH + sts Pwm_Limit_By_Rpm, XH + sei + ldi XH, 1 ; Set low pwm again after calling set_startup_pwm + sts Requested_Pwm, XH + sts Current_Pwm, XH + mov Current_Pwm_Limited, XH + sts Current_Pwm_Lim_Dith, XH + sts Spoolup_Limit_Skip, XH + lds XH, Auto_Bailout_Armed + sts Spoolup_Limit_Cnt, XH + ; Begin startup sequence + lds XH, Pgm_Direction ; Check if bidirectional operation + cpi XH, 3 + brne init_start_bidir_done + + cbr Flags3, (1<= 1 ; Tail or multi + lds XH, Pgm_Direction ; Check if bidirectional operation + cpi XH, 3 + brne run6_check_speed + + sbrc Flags3, PGM_DIR_REV ; Check if actual rotation direction + rjmp run6_check_dir_rev + sbrc Flags2, RCP_DIR_REV ; Matches force direction + rjmp run6_check_dir_change + rjmp run6_check_speed + +run6_check_dir_rev: + sbrs Flags2, RCP_DIR_REV + rjmp run6_check_dir_change + rjmp run6_check_speed + +run6_check_dir_change: + sbrc Flags0, DIR_CHANGE_BRAKE + rjmp run6_check_speed + + sbr Flags0, (1<= 1 ; Tail or multi + sbrs Flags0, DIR_CHANGE_BRAKE ; If it is not a direction change - stop + rjmp run_to_wait_for_power_on + + cbr Flags0, (1<= 1 ; Tail or multi + sbrs Flags2, RCP_PPM + rjmp jmp_wait_for_power_on ; If flag is not set (PWM) - branch + + lds XH, Stall_Cnt + cpi XH, 4 + brcs jmp_wait_for_power_on + rjmp init_no_signal + +jmp_wait_for_power_on: + rjmp wait_for_power_on ; Go back to wait for power on +.ENDIF + +;**** **** **** **** **** **** **** **** **** **** **** **** **** + +.INCLUDE "BLHeliTxPgm.inc" ; Include source code for programming the ESC with the TX + +;**** **** **** **** **** **** **** **** **** **** **** **** **** + + +reset: +rjmp pgm_start + + + + +.EXIT diff --git a/Atmel/Flycolor_45A_HV.inc b/Atmel/Flycolor_45A_HV.inc new file mode 100644 index 00000000..40f3016e --- /dev/null +++ b/Atmel/Flycolor_45A_HV.inc @@ -0,0 +1,411 @@ +;**** **** **** **** **** +; +; BLHeli program for controlling brushless motors in helicopters and multirotors +; +; 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 . +; +;**** **** **** **** **** +; +; Flycolor 45A HV hardware definition file +; +;**** **** **** **** **** + + +;********************* +; Device Atmega8A +;********************* +.INCLUDE "m8Adef.inc" + +;**** **** **** **** **** +; Fuses must be set to external oscillator = 16Mhz +;**** **** **** **** **** + +;**** **** **** **** **** +; Constant definitions +;**** **** **** **** **** +.ESEG ; EEprom segment +.ORG 0x40 +Eep_ESC_Layout: .DB "#FC_45A_HV# " ; ESC layout tag +.ORG 0x50 +Eep_ESC_MCU: .DB "#BLHELI#Am8A# " ; Project and MCU tag (16 Bytes) + +.EQU HIGH_BEC_VOLTAGE = 0 ; Set to 1 or more if high BEC voltage is supported +.EQU DAMPED_MODE_ENABLE = 1 ; Set to 1 if fully damped mode is supported +.EQU NFETON_DELAY = 7 ; Wait delay from pfets off to nfets on +.EQU PFETON_DELAY = 9 ; Wait delay from nfets off to pfets on +.EQU ADC_LIMIT_L = 112 ; 22k/220k divider. Power supply measurement ADC value for which motor power is limited (low byte) +.EQU ADC_LIMIT_H = 0 ; 22k/220k divider. Power supply measurement ADC value for which motor power is limited (2 MSBs) +.EQU TEMP_LIMIT = 188 ; 1k5/10kNTC. Temperature measurement ADC value for which main motor power is limited +.EQU TEMP_LIMIT_STEP = 14 ; 1k5/10kNTC. Temperature measurement ADC value increment for which main motor power is further limited + +;**** **** **** **** **** +; ESC specific defaults +;**** **** **** **** **** +.EQU DEFAULT_PGM_MAIN_SPOOLUP_TIME = 10 ; Main motor spoolup time +.EQU DEFAULT_PGM_MAIN_STARTUP_PWR = 9 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50 +.EQU DEFAULT_PGM_TAIL_STARTUP_PWR = 9 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50 +.EQU DEFAULT_PGM_MULTI_STARTUP_PWR = 9 ; 1=0.031 2=0.047 3=0.063 4=0.094 5=0.125 6=0.188 7=0.25 8=0.38 9=0.50 10=0.75 11=1.00 12=1.25 13=1.50 + + +;********************* +; PORT D definitions * +;********************* +;.EQU = 7 ;i +;.EQU = 6 ;i +.EQU AnFET = 5 ;o +.EQU ApFET = 4 ;o +;.EQU = 3 ;i +.EQU Rcp_In = 2 ;i +;.EQU = 1 ;i +;.EQU = 0 ;i + +.equ INIT_PD = 0x00 +.equ DIR_PD = (1<