;**** **** **** **** **** ; ; 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