Fork from bluejay at github and modified for my custom ESC. I need to modify it because some mistake design on my ESC hardware.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3863 lines
102 KiB

  1. $NOMOD51
  2. ;**** **** **** **** ****
  3. ;
  4. ; Bluejay digital ESC firmware for controlling brushless motors in multirotors
  5. ;
  6. ; Copyright 2020 Mathias Rasmussen
  7. ; Copyright 2011, 2012 Steffen Skaug
  8. ;
  9. ; This file is part of Bluejay.
  10. ;
  11. ; Bluejay is free software: you can redistribute it and/or modify
  12. ; it under the terms of the GNU General Public License as published by
  13. ; the Free Software Foundation, either version 3 of the License, or
  14. ; (at your option) any later version.
  15. ;
  16. ; Bluejay is distributed in the hope that it will be useful,
  17. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. ; GNU General Public License for more details.
  20. ;
  21. ; You should have received a copy of the GNU General Public License
  22. ; along with Bluejay. If not, see <http://www.gnu.org/licenses/>.
  23. ;
  24. ;**** **** **** **** ****
  25. ;
  26. ; Bluejay is a fork of BLHeli_S <https://github.com/bitdump/BLHeli> by Steffen Skaug.
  27. ;
  28. ; The input signal can be DShot with rates: DShot150, DShot300 and DShot600.
  29. ;
  30. ; This file is best viewed with tab width set to 5.
  31. ;
  32. ;**** **** **** **** ****
  33. ; Master clock is internal 24MHz oscillator (or 48MHz, for which the times below are halved)
  34. ; Although 24/48 are used in the code, the exact clock frequencies are 24.5MHz or 49.0 MHz
  35. ; Timer 0 (41.67ns counts) always counts up and is used for
  36. ; - RC pulse measurement
  37. ; - DShot telemetry signal
  38. ; Timer 1 (41.67ns counts) always counts up and is used for
  39. ; - DShot frame sync detection
  40. ; Timer 2 (500ns counts) always counts up and is used for
  41. ; - RC pulse timeout counts and commutation times
  42. ; Timer 3 (500ns counts) always counts up and is used for
  43. ; - Commutation timeouts
  44. ; PCA0 (41.67ns counts) always counts up and is used for
  45. ; - Hardware PWM generation
  46. ;
  47. ;**** **** **** **** ****
  48. ; Motor control:
  49. ; - Brushless motor control with 6 states for each electrical 360 degrees
  50. ; - An advance timing of 0deg has zero cross 30deg after one commutation and 30deg before the next
  51. ; - Timing advance in this implementation is set to 15deg nominally
  52. ; - Motor pwm is always damped light (aka complementary pwm, regenerative braking)
  53. ; Motor sequence starting from zero crossing:
  54. ; - Timer wait: Wt_Comm 15deg ; Time to wait from zero cross to actual commutation
  55. ; - Timer wait: Wt_Advance 15deg ; Time to wait for timing advance. Nominal commutation point is after this
  56. ; - Timer wait: Wt_Zc_Scan 7.5deg ; Time to wait before looking for zero cross
  57. ; - Scan for zero cross 22.5deg ; Nominal, with some motor variations
  58. ;
  59. ; Motor startup:
  60. ; There is a startup phase and an initial run phase, before normal bemf commutation run begins.
  61. ;
  62. ;**** **** **** **** ****
  63. ; List of enumerated supported ESCs
  64. A_ EQU 1 ; X X RC X MC MB MA CC X X Cc Cp Bc Bp Ac Ap
  65. B_ EQU 2 ; X X RC X MC MB MA CC X X Ap Ac Bp Bc Cp Cc
  66. C_ EQU 3 ; Ac Ap MC MB MA CC X RC X X X X Cc Cp Bc Bp
  67. D_ EQU 4 ; X X RC X CC MA MC MB X X Cc Cp Bc Bp Ac Ap Com fets inverted
  68. E_ EQU 5 ; L1 L0 RC X MC MB MA CC X L2 Cc Cp Bc Bp Ac Ap A with LEDs
  69. F_ EQU 6 ; X X RC X MA MB MC CC X X Cc Cp Bc Bp Ac Ap
  70. G_ EQU 7 ; X X RC X CC MA MC MB X X Cc Cp Bc Bp Ac Ap Like D, but noninverted com fets
  71. H_ EQU 8 ; RC X X X MA MB CC MC X Ap Bp Cp X Ac Bc Cc
  72. I_ EQU 9 ; X X RC X MC MB MA CC X X Ac Bc Cc Ap Bp Cp
  73. J_ EQU 10 ; L2 L1 L0 RC CC MB MC MA X X Cc Bc Ac Cp Bp Ap LEDs
  74. K_ EQU 11 ; X X MC X MB CC MA RC X X Ap Bp Cp Cc Bc Ac Com fets inverted
  75. L_ EQU 12 ; X X RC X CC MA MB MC X X Ac Bc Cc Ap Bp Cp
  76. M_ EQU 13 ; MA MC CC MB RC L0 X X X Cc Bc Ac Cp Bp Ap X LED
  77. N_ EQU 14 ; X X RC X MC MB MA CC X X Cp Cc Bp Bc Ap Ac
  78. O_ EQU 15 ; X X RC X CC MA MC MB X X Cc Cp Bc Bp Ac Ap Like D, but low side pwm
  79. P_ EQU 16 ; X X RC MA CC MB MC X X Cc Bc Ac Cp Bp Ap X
  80. Q_ EQU 17 ; Cp Bp Ap L1 L0 X RC X X MA MB MC CC Cc Bc Ac LEDs
  81. R_ EQU 18 ; X X RC X MC MB MA CC X X Ac Bc Cc Ap Bp Cp
  82. S_ EQU 19 ; X X RC X CC MA MC MB X X Cc Cp Bc Bp Ac Ap Like O, but com fets inverted
  83. T_ EQU 20 ; RC X MA X MB CC MC X X X Cp Bp Ap Ac Bc Cc
  84. U_ EQU 21 ; MA MC CC MB RC L0 L1 L2 X Cc Bc Ac Cp Bp Ap X Like M, but with 3 LEDs
  85. V_ EQU 22 ; Cc X RC X MC CC MB MA X Ap Ac Bp X X Bc Cp
  86. W_ EQU 23 ; RC MC MB X CC MA X X X Ap Bp Cp X X X X Tristate gate driver
  87. ;**** **** **** **** ****
  88. ; Select the port mapping to use (or unselect all for use with external batch compile file)
  89. ;ESCNO EQU A_
  90. ;**** **** **** **** ****
  91. ; Select the MCU type (or unselect for use with external batch compile file)
  92. ;MCU_48MHZ EQU 0
  93. ;**** **** **** **** ****
  94. ; Select the fet deadtime (or unselect for use with external batch compile file)
  95. ;FETON_DELAY EQU 15 ; 20.4ns per step
  96. ;**** **** **** **** ****
  97. ; Select the pwm frequency (or unselect for use with external batch compile file)
  98. ;PWM_FREQ EQU 0 ; 0=24, 1=48, 2=96 kHz
  99. $include (Common.inc) ; Include common source code for EFM8BBx based ESCs
  100. ;**** **** **** **** ****
  101. ; Programming defaults
  102. ;
  103. DEFAULT_PGM_STARTUP_PWR EQU 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
  104. DEFAULT_PGM_COMM_TIMING EQU 3 ; 1=Low 2=MediumLow 3=Medium 4=MediumHigh 5=High
  105. DEFAULT_PGM_DEMAG_COMP EQU 2 ; 1=Disabled 2=Low 3=High
  106. DEFAULT_PGM_DIRECTION EQU 1 ; 1=Normal 2=Reversed 3=Bidir 4=Bidir rev
  107. DEFAULT_PGM_BEEP_STRENGTH EQU 40 ; Beep strength
  108. DEFAULT_PGM_BEACON_STRENGTH EQU 80 ; Beacon strength
  109. DEFAULT_PGM_BEACON_DELAY EQU 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite
  110. ; COMMON
  111. DEFAULT_PGM_ENABLE_TEMP_PROT EQU 7 ; 0=Disabled 1=80C 2=90C 3=100C 4=110C 5=120C 6=130C 7=140C
  112. DEFAULT_PGM_ENABLE_POWER_PROT EQU 1 ; 1=Enabled 0=Disabled
  113. DEFAULT_PGM_BRAKE_ON_STOP EQU 0 ; 1=Enabled 0=Disabled
  114. DEFAULT_PGM_LED_CONTROL EQU 0 ; Byte for LED control. 2bits per LED, 0=Off, 1=On
  115. ;**** **** **** **** ****
  116. ; Temporary register definitions
  117. Temp1 EQU R0
  118. Temp2 EQU R1
  119. Temp3 EQU R2
  120. Temp4 EQU R3
  121. Temp5 EQU R4
  122. Temp6 EQU R5
  123. Temp7 EQU R6
  124. Temp8 EQU R7
  125. ;**** **** **** **** ****
  126. ; RAM definitions
  127. DSEG AT 20h ; Ram data segment, bit-addressable
  128. Bit_Access: DS 1 ; MUST BE AT THIS ADDRESS. Variable at bit accessible address (for non interrupt routines)
  129. Bit_Access_Int: DS 1 ; Variable at bit accessible address (for interrupts)
  130. Rcp_Outside_Range_Cnt: DS 1 ; RC pulse outside range counter (incrementing)
  131. Rcp_Timeout_Cntd: DS 1 ; RC pulse timeout counter (decrementing)
  132. Flags0: DS 1 ; State flags. Reset upon init_start
  133. Flag_T3_PENDING BIT Flags0.0 ; Timer 3 pending flag
  134. Flag_DEMAG_DETECTED BIT Flags0.1 ; Set when excessive demag time is detected
  135. Flag_COMP_TIMED_OUT BIT Flags0.2 ; Set when comparator reading timed out
  136. Flag_PACKET_PENDING BIT Flags0.4 ; DShot telemetry data packet is ready to be sent
  137. Flags1: DS 1 ; State flags. Reset upon init_start
  138. Flag_MOTOR_STARTED BIT Flags1.2 ; Set when motor is started
  139. Flag_DIR_CHANGE_BRAKE BIT Flags1.3 ; Set when braking before direction change
  140. Flag_HIGH_RPM BIT Flags1.4 ; Set when motor rpm is high (Comm_Period4x_H less than 2)
  141. Flag_LOW_PWM_POWER BIT Flags1.5 ; Set when pwm duty cycle is below 50%
  142. Flags_Startup: DS 1 ; State flags. Reset upon init_start
  143. Flag_STARTUP_PHASE BIT Flags_Startup.0 ; Set when in startup phase
  144. Flag_INITIAL_RUN_PHASE BIT Flags_Startup.1 ; Set when in initial run phase, before synchronized run is achieved
  145. ; Remaining bits must be cleared
  146. Flags2: DS 1 ; State flags. NOT reset upon init_start
  147. Flag_RCP_DIR_REV BIT Flags2.5 ; RC pulse direction in bidirectional mode
  148. Flag_RCP_DSHOT_INVERTED BIT Flags2.7 ; DShot RC pulse input is inverted (and supports telemetry)
  149. Flags3: DS 1 ; State flags. NOT reset upon init_start
  150. Flag_PGM_DIR_REV BIT Flags3.0 ; Programmed direction. 0=normal, 1=reversed
  151. Flag_PGM_BIDIR_REV BIT Flags3.1 ; Programmed bidirectional direction. 0=normal, 1=reversed
  152. Flag_PGM_BIDIR BIT Flags3.2 ; Programmed bidirectional operation. 0=normal, 1=bidirectional
  153. Flag_SKIP_T2_INT BIT Flags3.3 ; Set for 48MHz MCUs when timer 2 interrupt shall be ignored
  154. Flag_CLOCK_SET_AT_48MHZ BIT Flags3.4 ; Set if 48MHz MCUs run at 48MHz
  155. Flag_RCP_STOP BIT Flags3.5 ; Set if the RC pulse value is zero
  156. Tlm_Data_L: DS 1 ; DShot telemetry data low byte
  157. Tlm_Data_H: DS 1 ; DShot telemetry data high byte
  158. Tmp_B: DS 1
  159. DSEG AT 30h ; Ram data segment, direct addressing
  160. Power_On_Wait_Cnt_L: DS 1 ; Power on wait counter (lo byte)
  161. Power_On_Wait_Cnt_H: DS 1 ; Power on wait counter (hi byte)
  162. Startup_Cnt: DS 1 ; Startup phase commutations counter (incrementing)
  163. Startup_Zc_Timeout_Cntd: DS 1 ; Startup zero cross timeout counter (decrementing)
  164. Initial_Run_Rot_Cntd: DS 1 ; Initial run rotations counter (decrementing)
  165. Stall_Cnt: DS 1 ; Counts start/run attempts that resulted in stall. Reset upon a proper stop
  166. Demag_Detected_Metric: DS 1 ; Metric used to gauge demag event frequency
  167. Demag_Pwr_Off_Thresh: DS 1 ; Metric threshold above which power is cut
  168. Low_Rpm_Pwr_Slope: DS 1 ; Sets the slope of power increase for low rpms
  169. Timer2_X: DS 1 ; Timer 2 extended byte
  170. Prev_Comm_L: DS 1 ; Previous commutation timer 3 timestamp (lo byte)
  171. Prev_Comm_H: DS 1 ; Previous commutation timer 3 timestamp (hi byte)
  172. Prev_Comm_X: DS 1 ; Previous commutation timer 3 timestamp (ext byte)
  173. Prev_Prev_Comm_L: DS 1 ; Pre-previous commutation timer 3 timestamp (lo byte)
  174. Prev_Prev_Comm_H: DS 1 ; Pre-previous commutation timer 3 timestamp (hi byte)
  175. Comm_Period4x_L: DS 1 ; Timer 3 counts between the last 4 commutations (lo byte)
  176. Comm_Period4x_H: DS 1 ; Timer 3 counts between the last 4 commutations (hi byte)
  177. Comparator_Read_Cnt: DS 1 ; Number of comparator reads done
  178. Wt_Adv_Start_L: DS 1 ; Timer 3 start point for commutation advance timing (lo byte)
  179. Wt_Adv_Start_H: DS 1 ; Timer 3 start point for commutation advance timing (hi byte)
  180. Wt_Zc_Scan_Start_L: DS 1 ; Timer 3 start point from commutation to zero cross scan (lo byte)
  181. Wt_Zc_Scan_Start_H: DS 1 ; Timer 3 start point from commutation to zero cross scan (hi byte)
  182. Wt_Zc_Tout_Start_L: DS 1 ; Timer 3 start point for zero cross scan timeout (lo byte)
  183. Wt_Zc_Tout_Start_H: DS 1 ; Timer 3 start point for zero cross scan timeout (hi byte)
  184. Wt_Comm_Start_L: DS 1 ; Timer 3 start point from zero cross to commutation (lo byte)
  185. Wt_Comm_Start_H: DS 1 ; Timer 3 start point from zero cross to commutation (hi byte)
  186. Dshot_Cmd: DS 1 ; DShot command
  187. Dshot_Cmd_Cnt: DS 1 ; DShot command count
  188. Rcp_Stop_Cnt: DS 1 ; Counter for RC pulses below stop value
  189. Power_Pwm_Reg_L: DS 1 ; Power pwm register setting (lo byte)
  190. Power_Pwm_Reg_H: DS 1 ; Power pwm register setting (hi byte). 0x3F is minimum power
  191. Damp_Pwm_Reg_L: DS 1 ; Damping pwm register setting (lo byte)
  192. Damp_Pwm_Reg_H: DS 1 ; Damping pwm register setting (hi byte)
  193. Pwm_Limit: DS 1 ; Maximum allowed pwm
  194. Pwm_Limit_By_Rpm: DS 1 ; Maximum allowed pwm for low or high rpms
  195. Pwm_Limit_Beg: DS 1 ; Initial pwm limit
  196. Adc_Conversion_Cnt: DS 1 ; Adc conversion counter
  197. Current_Average_Temp: DS 1 ; Current average temperature (lo byte ADC reading, assuming hi byte is 1)
  198. Beep_Strength: DS 1 ; Strength of beeps
  199. Flash_Key_1: DS 1 ; Flash key one
  200. Flash_Key_2: DS 1 ; Flash key two
  201. Temp_Prot_Limit: DS 1 ; Temperature protection limit
  202. DShot_Pwm_Thr: DS 1 ; DShot pulse width threshold value
  203. DShot_Timer_Preset: DS 1 ; DShot timer preset for frame sync detection
  204. DShot_Frame_Start_L: DS 1 ; DShot frame start timestamp (lo byte)
  205. DShot_Frame_Start_H: DS 1 ; DShot frame start timestamp (hi byte)
  206. DShot_Frame_Length_Thr: DS 1 ; DShot frame length criteria (in units of 4 timer 2 ticks)
  207. ; Pulse durations for GCR encoding DShot telemetry data
  208. DShot_GCR_Pulse_Time_1: DS 1 ; Encodes binary: 1
  209. DShot_GCR_Pulse_Time_2: DS 1 ; Encodes binary: 01
  210. DShot_GCR_Pulse_Time_3: DS 1 ; Encodes binary: 001
  211. DShot_GCR_Pulse_Time_1_Tmp: DS 1
  212. DShot_GCR_Pulse_Time_2_Tmp: DS 1
  213. DShot_GCR_Pulse_Time_3_Tmp: DS 1
  214. DShot_GCR_Start_Delay: DS 1
  215. ; Indirect addressing data segment. The variables below must be in this sequence
  216. ISEG AT 080h
  217. _Pgm_Gov_P_Gain: DS 1 ; Governor P gain
  218. _Pgm_Gov_I_Gain: DS 1 ; Governor I gain
  219. _Pgm_Gov_Mode: DS 1 ; Governor mode
  220. _Pgm_Low_Voltage_Lim: DS 1 ; Low voltage limit
  221. _Pgm_Motor_Gain: DS 1 ; Motor gain
  222. _Pgm_Motor_Idle: DS 1 ; Motor idle speed
  223. Pgm_Startup_Pwr: DS 1 ; Startup power
  224. _Pgm_Pwm_Freq: DS 1 ; PWM frequency
  225. Pgm_Direction: DS 1 ; Rotation direction
  226. _Pgm_Input_Pol: DS 1 ; Input PWM polarity
  227. Initialized_L_Dummy: DS 1 ; Place holder
  228. Initialized_H_Dummy: DS 1 ; Place holder
  229. _Pgm_Enable_TX_Program: DS 1 ; Enable/disable value for TX programming
  230. _Pgm_Main_Rearm_Start: DS 1 ; Enable/disable re-arming main every start
  231. _Pgm_Gov_Setup_Target: DS 1 ; Main governor setup target
  232. _Pgm_Startup_Rpm: DS 1 ; Startup RPM
  233. _Pgm_Startup_Accel: DS 1 ; Startup acceleration
  234. _Pgm_Volt_Comp: DS 1 ; Voltage comp
  235. Pgm_Comm_Timing: DS 1 ; Commutation timing
  236. _Pgm_Damping_Force: DS 1 ; Damping force
  237. _Pgm_Gov_Range: DS 1 ; Governor range
  238. _Pgm_Startup_Method: DS 1 ; Startup method
  239. _Pgm_Min_Throttle: DS 1 ; Minimum throttle
  240. _Pgm_Max_Throttle: DS 1 ; Maximum throttle
  241. Pgm_Beep_Strength: DS 1 ; Beep strength
  242. Pgm_Beacon_Strength: DS 1 ; Beacon strength
  243. Pgm_Beacon_Delay: DS 1 ; Beacon delay
  244. _Pgm_Throttle_Rate: DS 1 ; Throttle rate
  245. Pgm_Demag_Comp: DS 1 ; Demag compensation
  246. _Pgm_BEC_Voltage_High: DS 1 ; BEC voltage
  247. _Pgm_Center_Throttle: DS 1 ; Center throttle (in bidirectional mode)
  248. _Pgm_Main_Spoolup_Time: DS 1 ; Main spoolup time
  249. Pgm_Enable_Temp_Prot: DS 1 ; Temperature protection enable
  250. Pgm_Enable_Power_Prot: DS 1 ; Low RPM power protection enable
  251. _Pgm_Enable_Pwm_Input: DS 1 ; Enable PWM input signal
  252. _Pgm_Pwm_Dither: DS 1 ; Output PWM dither
  253. Pgm_Brake_On_Stop: DS 1 ; Braking when throttle is zero
  254. Pgm_LED_Control: DS 1 ; LED control
  255. ; The sequence of the variables below is no longer of importance
  256. Pgm_Startup_Pwr_Decoded: DS 1 ; Programmed startup power decoded
  257. ; Indirect addressing data segments
  258. ISEG AT 0B0h
  259. Stack: DS 16 ; Reserved stack space
  260. ISEG AT 0C0h
  261. Dithering_Patterns: DS 16
  262. ISEG AT 0D0h
  263. Temp_Storage: DS 48 ; Temporary storage
  264. ;**** **** **** **** ****
  265. CSEG AT 1A00h ; "Eeprom" segment
  266. EEPROM_FW_MAIN_REVISION EQU 0 ; Main revision of the firmware
  267. EEPROM_FW_SUB_REVISION EQU 40 ; Sub revision of the firmware
  268. EEPROM_LAYOUT_REVISION EQU 33 ; Revision of the EEPROM layout
  269. Eep_FW_Main_Revision: DB EEPROM_FW_MAIN_REVISION ; EEPROM firmware main revision number
  270. Eep_FW_Sub_Revision: DB EEPROM_FW_SUB_REVISION ; EEPROM firmware sub revision number
  271. Eep_Layout_Revision: DB EEPROM_LAYOUT_REVISION ; EEPROM layout revision number
  272. _Eep_Pgm_Gov_P_Gain: DB 0FFh
  273. _Eep_Pgm_Gov_I_Gain: DB 0FFh
  274. _Eep_Pgm_Gov_Mode: DB 0FFh
  275. _Eep_Pgm_Low_Voltage_Lim: DB 0FFh
  276. _Eep_Pgm_Motor_Gain: DB 0FFh
  277. _Eep_Pgm_Motor_Idle: DB 0FFh
  278. Eep_Pgm_Startup_Pwr: DB DEFAULT_PGM_STARTUP_PWR ; EEPROM copy of programmed startup power
  279. _Eep_Pgm_Pwm_Freq: DB 0FFh
  280. Eep_Pgm_Direction: DB DEFAULT_PGM_DIRECTION ; EEPROM copy of programmed rotation direction
  281. _Eep__Pgm_Input_Pol: DB 0FFh
  282. Eep_Initialized_L: DB 055h ; EEPROM initialized signature low byte
  283. Eep_Initialized_H: DB 0AAh ; EEPROM initialized signature high byte
  284. _Eep_Enable_TX_Program: DB 0FFh ; EEPROM TX programming enable
  285. _Eep_Main_Rearm_Start: DB 0FFh
  286. _Eep_Pgm_Gov_Setup_Target: DB 0FFh
  287. _Eep_Pgm_Startup_Rpm: DB 0FFh
  288. _Eep_Pgm_Startup_Accel: DB 0FFh
  289. _Eep_Pgm_Volt_Comp: DB 0FFh
  290. Eep_Pgm_Comm_Timing: DB DEFAULT_PGM_COMM_TIMING ; EEPROM copy of programmed commutation timing
  291. _Eep_Pgm_Damping_Force: DB 0FFh
  292. _Eep_Pgm_Gov_Range: DB 0FFh
  293. _Eep_Pgm_Startup_Method: DB 0FFh
  294. _Eep_Pgm_Min_Throttle: DB 0FFh ; EEPROM copy of programmed minimum throttle
  295. _Eep_Pgm_Max_Throttle: DB 0FFh ; EEPROM copy of programmed minimum throttle
  296. Eep_Pgm_Beep_Strength: DB DEFAULT_PGM_BEEP_STRENGTH ; EEPROM copy of programmed beep strength
  297. Eep_Pgm_Beacon_Strength: DB DEFAULT_PGM_BEACON_STRENGTH ; EEPROM copy of programmed beacon strength
  298. Eep_Pgm_Beacon_Delay: DB DEFAULT_PGM_BEACON_DELAY ; EEPROM copy of programmed beacon delay
  299. _Eep_Pgm_Throttle_Rate: DB 0FFh
  300. Eep_Pgm_Demag_Comp: DB DEFAULT_PGM_DEMAG_COMP ; EEPROM copy of programmed demag compensation
  301. _Eep_Pgm_BEC_Voltage_High: DB 0FFh
  302. _Eep_Pgm_Center_Throttle: DB 0FFh ; EEPROM copy of programmed center throttle
  303. _Eep_Pgm_Main_Spoolup_Time: DB 0FFh
  304. Eep_Pgm_Temp_Prot_Enable: DB DEFAULT_PGM_ENABLE_TEMP_PROT ; EEPROM copy of programmed temperature protection enable
  305. Eep_Pgm_Enable_Power_Prot: DB DEFAULT_PGM_ENABLE_POWER_PROT ; EEPROM copy of programmed low rpm power protection enable
  306. _Eep_Pgm_Enable_Pwm_Input: DB 0FFh
  307. _Eep_Pgm_Pwm_Dither: DB 0FFh
  308. Eep_Pgm_Brake_On_Stop: DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero
  309. Eep_Pgm_LED_Control: DB DEFAULT_PGM_LED_CONTROL ; EEPROM copy of programmed LED control
  310. Eep_Dummy: DB 0FFh ; EEPROM address for safety reason
  311. CSEG AT 1A60h
  312. Eep_Name: DB "Bluejay (BETA) " ; Name tag (16 Bytes)
  313. ;**** **** **** **** ****
  314. ; DShot Telemetry Macros
  315. DSHOT_TLM_CLOCK EQU 24500000 ; 24.5MHz
  316. DSHOT_TLM_START_DELAY EQU -1 ; Start telemetry after 1 tick (~30us after receiving DShot cmd)
  317. DSHOT_TLM_PREDELAY EQU 6 ; 6 timer 0 ticks inherent delay
  318. IF MCU_48MHZ == 1
  319. DSHOT_TLM_CLOCK_48 EQU 49000000 ; 49MHz
  320. DSHOT_TLM_START_DELAY_48 EQU -(14 * 49 / 4) ; Start telemetry after 14us (~30us after receiving DShot cmd)
  321. DSHOT_TLM_PREDELAY_48 EQU 8 ; 8 timer 0 ticks inherent delay
  322. ENDIF
  323. Set_DShot_Tlm_Bitrate MACRO rate
  324. mov DShot_GCR_Pulse_Time_1, #(DSHOT_TLM_PREDELAY - (1 * DSHOT_TLM_CLOCK / 4 / rate))
  325. mov DShot_GCR_Pulse_Time_2, #(DSHOT_TLM_PREDELAY - (2 * DSHOT_TLM_CLOCK / 4 / rate))
  326. mov DShot_GCR_Pulse_Time_3, #(DSHOT_TLM_PREDELAY - (3 * DSHOT_TLM_CLOCK / 4 / rate))
  327. mov DShot_GCR_Start_Delay, #DSHOT_TLM_START_DELAY
  328. IF MCU_48MHZ == 1
  329. mov DShot_GCR_Pulse_Time_1_Tmp, #(DSHOT_TLM_PREDELAY_48 - (1 * DSHOT_TLM_CLOCK_48 / 4 / rate))
  330. mov DShot_GCR_Pulse_Time_2_Tmp, #(DSHOT_TLM_PREDELAY_48 - (2 * DSHOT_TLM_CLOCK_48 / 4 / rate))
  331. mov DShot_GCR_Pulse_Time_3_Tmp, #(DSHOT_TLM_PREDELAY_48 - (3 * DSHOT_TLM_CLOCK_48 / 4 / rate))
  332. ENDIF
  333. ENDM
  334. Push_Mem MACRO reg, val
  335. mov @reg, val ;; Write value to memory address pointed to by register
  336. inc reg ;; Increment pointer
  337. ENDM
  338. DShot_GCR_Get_Time MACRO
  339. mov A, DShot_GCR_Pulse_Time_2
  340. cjne A, Tmp_B, ($+5)
  341. mov A, DShot_GCR_Pulse_Time_3
  342. ENDM
  343. ; Prepare telemetry packet while waiting for timer 3 to wrap
  344. Wait_For_Timer3 MACRO
  345. LOCAL wait_for_t3 done_waiting
  346. jb Flag_PACKET_PENDING, wait_for_t3
  347. jnb Flag_T3_PENDING, done_waiting
  348. call dshot_tlm_create_packet
  349. wait_for_t3:
  350. jnb Flag_T3_PENDING, done_waiting
  351. sjmp wait_for_t3
  352. done_waiting:
  353. ENDM
  354. Early_Return_Packet_Stage MACRO num
  355. Early_Return_Packet_Stage_ num, %(num+1)
  356. ENDM
  357. Early_Return_Packet_Stage_ MACRO num next
  358. IF num > 0
  359. inc Temp5 ;; Increment current packet stage
  360. jb Flag_T3_PENDING, dshot_packet_stage_&num ;; Return early if timer 3 has wrapped
  361. pop PSW
  362. ret
  363. dshot_packet_stage_&num:
  364. ENDIF
  365. IF num < 5
  366. cjne Temp5, #(num), dshot_packet_stage_&next ;; If this is not current stage, skip to next
  367. ENDIF
  368. ENDM
  369. IF FETON_DELAY == 0
  370. PWM_CENTERED EQU 0
  371. ELSE
  372. PWM_CENTERED EQU 1
  373. ENDIF
  374. IF MCU_48MHZ < 2 AND PWM_FREQ < 3
  375. ; Number of bits in pwm high byte
  376. PWM_BITS_H EQU (2 + MCU_48MHZ - PWM_CENTERED - PWM_FREQ)
  377. ENDIF
  378. Decode_DShot_2Bit MACRO dest, decode_fail
  379. movx A, @Temp1
  380. mov Temp7, A
  381. clr C
  382. subb A, Temp6 ; Subtract previous timestamp
  383. clr C
  384. subb A, Temp2
  385. jc decode_fail ; Check that bit is longer than minimum
  386. subb A, Temp2 ; Check if bit is zero or one
  387. mov A, dest ; Shift bit into data byte
  388. rlc A
  389. mov dest, A
  390. inc Temp1 ; Next bit
  391. movx A, @Temp1
  392. mov Temp6, A
  393. clr C
  394. subb A, Temp7
  395. clr C
  396. subb A, Temp2
  397. jc decode_fail
  398. subb A, Temp2
  399. mov A, dest
  400. rlc A
  401. mov dest, A
  402. inc Temp1
  403. ENDM
  404. ;**** **** **** **** ****
  405. Interrupt_Table_Definition ; SiLabs interrupts
  406. CSEG AT 80h ; Code segment after interrupt vectors
  407. ;**** **** **** **** ****
  408. ; Table definitions
  409. STARTUP_POWER_TABLE: DB 1, 2, 3, 4, 6, 9, 12, 18, 25, 37, 50, 62, 75
  410. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  411. ;
  412. ; Timer 0 interrupt routine
  413. ;
  414. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  415. t0_int:
  416. push PSW
  417. mov PSW, #10h ; Select register bank 2 for this interrupt
  418. dec Temp1
  419. cjne Temp1, #(Temp_Storage-1), t0_int_dshot_tlm_transition
  420. ; If last pulse is high telemetry is finished
  421. jb RTX_PORT.RTX_PIN, t0_int_dshot_tlm_finish
  422. inc Temp1 ; Otherwise wait for it to return to high
  423. t0_int_dshot_tlm_transition:
  424. cpl RTX_PORT.RTX_PIN ; Invert signal level
  425. mov TL0, @Temp1 ; Schedule next update
  426. pop PSW
  427. reti
  428. t0_int_dshot_tlm_finish:
  429. ; Configure RTX_PIN for digital input
  430. anl RTX_MDOUT, #(NOT (1 SHL RTX_PIN)) ; Set RTX_PIN output mode to open-drain
  431. setb RTX_PORT.RTX_PIN ; Float high
  432. clr IE_ET0 ; Disable timer 0 interrupts
  433. ; todo: dshot150
  434. ;mov CKCON0, Temp2 ; Restore normal DShot timer 0/1 clock settings
  435. mov CKCON0, #0Ch
  436. mov TMOD, #0AAh ; Timer 0/1 gated by INT0/1
  437. clr TCON_IE0 ; Clear int0 pending flag
  438. clr TCON_IE1 ; Clear int1 pending flag
  439. mov TL0, #0 ; Reset timer 0 count
  440. setb IE_EX0 ; Enable int0 interrupts
  441. setb IE_EX1 ; Enable int1 interrupts
  442. Enable_PCA_Interrupt ; Enable pca interrupts
  443. clr Flag_PACKET_PENDING
  444. pop PSW
  445. reti
  446. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  447. ;
  448. ; Timer 1 interrupt routine
  449. ;
  450. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  451. t1_int:
  452. clr IE_EX0 ; Disable int0 interrupts
  453. clr TCON_TR1 ; Stop timer 1
  454. mov TL1, DShot_Timer_Preset ; Reset sync timer
  455. push PSW
  456. mov PSW, #8h ; Select register bank 1 for this interrupt
  457. push ACC
  458. push B
  459. clr TMR2CN0_TR2 ; Timer 2 disabled
  460. mov Temp2, TMR2L ; Read timer value
  461. mov Temp3, TMR2H
  462. setb TMR2CN0_TR2 ; Timer 2 enabled
  463. ; Check frame time length
  464. clr C
  465. mov A, Temp2
  466. subb A, DShot_Frame_Start_L
  467. mov Temp2, A
  468. mov A, Temp3
  469. subb A, DShot_Frame_Start_H
  470. jnz t1_int_frame_fail ; Frame too long
  471. clr C
  472. mov A, Temp2
  473. subb A, DShot_Frame_Length_Thr
  474. jc t1_int_frame_fail ; Frame too short
  475. subb A, DShot_Frame_Length_Thr
  476. jnc t1_int_frame_fail ; Frame too long
  477. ; Check that correct number of pulses is received
  478. cjne Temp1, #16, t1_int_frame_fail ; Read current pointer
  479. ; Decode transmitted data
  480. mov Temp1, #0 ; Set pointer
  481. mov Temp2, DShot_Pwm_Thr ; DShot pulse width criteria
  482. mov Temp6, #0 ; Reset timestamp
  483. ; Decode DShot data Msb. Use more code space to save time (by not using loop)
  484. Decode_DShot_2Bit Temp5, t1_int_frame_fail
  485. Decode_DShot_2Bit Temp5, t1_int_frame_fail
  486. sjmp t1_int_decode_lsb
  487. t1_int_frame_fail:
  488. sjmp t1_int_outside_range
  489. t1_int_decode_lsb:
  490. ; Decode DShot data Lsb
  491. Decode_DShot_2Bit Temp4, t1_int_outside_range
  492. Decode_DShot_2Bit Temp4, t1_int_outside_range
  493. Decode_DShot_2Bit Temp4, t1_int_outside_range
  494. Decode_DShot_2Bit Temp4, t1_int_outside_range
  495. sjmp t1_int_decode_checksum
  496. t1_int_outside_range:
  497. inc Rcp_Outside_Range_Cnt
  498. mov A, Rcp_Outside_Range_Cnt
  499. jnz ($+4)
  500. dec Rcp_Outside_Range_Cnt
  501. clr C
  502. mov A, Rcp_Outside_Range_Cnt
  503. subb A, #50 ; Allow a given number of outside pulses
  504. jc t1_int_exit_timeout ; If outside limits - ignore first pulses
  505. setb Flag_RCP_STOP ; Set pulse length to zero
  506. clr A
  507. mov Dshot_Cmd, A ; Clear DShot command
  508. mov Dshot_Cmd_Cnt, A ; Clear DShot command count
  509. ajmp t1_int_exit_no_tlm ; Exit without reseting timeout
  510. t1_int_exit_timeout:
  511. mov Rcp_Timeout_Cntd, #10 ; Set timeout count
  512. ajmp t1_int_exit_no_tlm
  513. t1_int_decode_checksum:
  514. ; Decode DShot data checksum
  515. Decode_DShot_2Bit Temp3, t1_int_outside_range
  516. Decode_DShot_2Bit Temp3, t1_int_outside_range
  517. ; XOR check (in inverted data, which is ok), only low nibble is considered
  518. mov A, Temp4
  519. swap A
  520. xrl A, Temp4
  521. xrl A, Temp5
  522. xrl A, Temp3
  523. jnb Flag_RCP_DSHOT_INVERTED, ($+4)
  524. cpl A ; Invert checksum if using inverted DShot
  525. anl A, #0Fh
  526. jnz t1_int_outside_range ; XOR check
  527. ; Invert DShot data and subtract 96 (still 12 bits)
  528. clr C
  529. mov A, Temp4
  530. cpl A
  531. mov Temp3, A
  532. subb A, #96
  533. mov Temp4, A
  534. mov A, Temp5
  535. cpl A
  536. anl A, #0Fh
  537. subb A, #0
  538. mov Temp5, A
  539. jnc t1_normal_range
  540. mov A, Temp3 ; Check for 0 or DShot command
  541. mov Temp5, #0
  542. mov Temp4, #0
  543. jz t1_normal_range
  544. mov Temp3, #0
  545. clr C ; We are in the special DShot range
  546. rrc A ; Divide by 2
  547. jnc t1_dshot_set_cmd ; Check for tlm bit set (if not telemetry, Temp3 will be zero and result in invalid command)
  548. mov Temp3, A
  549. cjne A, Dshot_Cmd, t1_dshot_set_cmd
  550. inc Dshot_Cmd_Cnt
  551. sjmp t1_normal_range
  552. t1_dshot_set_cmd:
  553. mov Dshot_Cmd, Temp3
  554. mov Dshot_Cmd_Cnt, #0
  555. t1_normal_range:
  556. ; Check for bidirectional operation (0=stop, 96-2095->fwd, 2096-4095->rev)
  557. jnb Flag_PGM_BIDIR, t1_int_not_bidir ; If not bidirectional operation - branch
  558. ; Subtract 2000 (still 12 bits)
  559. clr C
  560. mov A, Temp4
  561. subb A, #0D0h
  562. mov B, A
  563. mov A, Temp5
  564. subb A, #07h
  565. clr Flag_RCP_DIR_REV
  566. jc t1_int_bidir_rev_chk ; If result is negative - branch
  567. mov Temp4, B
  568. mov Temp5, A
  569. setb Flag_RCP_DIR_REV
  570. t1_int_bidir_rev_chk:
  571. jb Flag_PGM_BIDIR_REV, ($+5)
  572. cpl Flag_RCP_DIR_REV
  573. clr C ; Multiply throttle value by 2
  574. mov A, Temp4
  575. rlc A
  576. mov Temp4, A
  577. mov A, Temp5
  578. rlc A
  579. mov Temp5, A
  580. t1_int_not_bidir:
  581. ; Generate 4/256
  582. mov A, Temp5
  583. add A, Temp5
  584. addc A, Temp5
  585. addc A, Temp5
  586. mov Temp3, A
  587. ; Align to 11 bits
  588. clr C
  589. mov A, Temp5
  590. rrc A
  591. mov Temp5, A
  592. mov A, Temp4
  593. rrc A
  594. mov Temp4, A
  595. ; Scale from 2000 to 2048
  596. mov A, Temp4
  597. add A, Temp3 ; Holds 4/128
  598. mov Temp4, A
  599. mov A, Temp5
  600. addc A, #0
  601. mov Temp5, A
  602. jnb ACC.3, ($+7)
  603. mov Temp4, #0FFh ; Set maximum 11-bit value
  604. mov Temp5, #07h
  605. ; Boost pwm during direct start
  606. mov A, Flags_Startup
  607. jz t1_int_startup_boosted
  608. jb Flag_MOTOR_STARTED, t1_int_startup_boosted ; Do not boost when changing direction in bidirectional mode
  609. ; Add an extra power boost during start
  610. mov Temp6, Stall_Cnt
  611. inc Temp6
  612. mov B, #31
  613. t1_int_startup_boost_stall:
  614. mov A, Temp4
  615. add A, B
  616. mov Temp4, A
  617. mov A, Temp5
  618. addc A, #0
  619. mov Temp5, A
  620. mov A, B
  621. rl A ; Add more boost when stalling
  622. mov B, A
  623. djnz Temp6, t1_int_startup_boost_stall
  624. jnb ACC.3, ($+7)
  625. mov Temp4, #0FFh ; Set maximum 11-bit value
  626. mov Temp5, #07h
  627. t1_int_startup_boosted:
  628. ; Set 8-bit value
  629. mov A, Temp4
  630. anl A, #0F8h
  631. orl A, Temp5 ; Assumes Temp5 to be 3-bit (11-bit rcp)
  632. swap A
  633. rl A
  634. mov Temp2, A
  635. jnz t1_int_rcp_not_zero
  636. mov A, Temp4 ; New_Rcp (Temp2) is only zero if all 11 bits are zero
  637. jnz t1_int_rcp_not_zero
  638. setb Flag_RCP_STOP
  639. sjmp t1_int_zero_rcp_checked
  640. t1_int_rcp_not_zero:
  641. mov Rcp_Stop_Cnt, #0 ; Reset rcp stop counter
  642. clr Flag_RCP_STOP ; Pulse ready
  643. t1_int_zero_rcp_checked:
  644. ; Decrement outside range counter
  645. mov A, Rcp_Outside_Range_Cnt
  646. jz ($+4)
  647. dec Rcp_Outside_Range_Cnt
  648. ; Set pwm limit
  649. clr C
  650. mov A, Pwm_Limit ; Limit to the smallest
  651. mov Temp6, A ; Store limit in Temp6
  652. subb A, Pwm_Limit_By_Rpm
  653. jc ($+4)
  654. mov Temp6, Pwm_Limit_By_Rpm
  655. ; Check against limit
  656. clr C
  657. mov A, Temp6
  658. subb A, Temp2 ; 8-bit rc pulse
  659. jnc t1_int_scale_pwm_resolution
  660. IF PWM_BITS_H == 0 ; 8-bit pwm
  661. mov A, Temp6
  662. mov Temp2, A
  663. ELSE
  664. mov A, Temp6 ; Multiply limit by 8 for 11-bit pwm
  665. mov B, #8
  666. mul AB
  667. mov Temp4, A
  668. mov Temp5, B
  669. ENDIF
  670. t1_int_scale_pwm_resolution:
  671. ; Scale pwm resolution and invert
  672. IF PWM_BITS_H == 3 ; 11-bit pwm
  673. mov A, Temp5
  674. cpl A
  675. anl A, #7
  676. mov Temp3, A
  677. mov A, Temp4
  678. cpl A
  679. mov Temp2, A
  680. ELSEIF PWM_BITS_H == 2 ; 10-bit pwm
  681. clr C
  682. mov A, Temp5
  683. rrc A
  684. cpl A
  685. anl A, #3
  686. mov Temp3, A
  687. mov A, Temp4
  688. rrc A
  689. cpl A
  690. mov Temp2, A
  691. ELSEIF PWM_BITS_H == 1 ; 9-bit pwm
  692. mov B, Temp5
  693. mov A, Temp4
  694. mov C, B.0
  695. rrc A
  696. mov C, B.1
  697. rrc A
  698. cpl A
  699. mov Temp2, A
  700. mov A, Temp5
  701. rr A
  702. rr A
  703. cpl A
  704. anl A, #1
  705. mov Temp3, A
  706. ELSEIF PWM_BITS_H == 0 ; 8-bit pwm
  707. mov A, Temp2 ; Temp2 already 8-bit
  708. cpl A
  709. mov Temp2, A
  710. mov Temp3, #0
  711. ENDIF
  712. ; 10-bit effective dithering of 8/9-bit pwm
  713. IF PWM_BITS_H < 2
  714. mov A, Temp4 ; 11-bit low byte
  715. cpl A
  716. rr A
  717. anl A, #((1 SHL (2-PWM_BITS_H))-1); Get index into dithering pattern table
  718. add A, #Dithering_Patterns
  719. mov Temp1, A ; Reuse DShot pwm pointer since it is not currently in use.
  720. mov A, @Temp1 ; Retrieve pattern
  721. rl A ; Rotate pattern
  722. mov @Temp1, A ; Store pattern
  723. jnb ACC.0, dithering_done
  724. mov A, Temp2
  725. add A, #1
  726. mov Temp2, A
  727. IF PWM_BITS_H != 0
  728. mov A, Temp3
  729. addc A, #0
  730. mov Temp3, A
  731. jnb ACC.PWM_BITS_H, dithering_done
  732. dec Temp2
  733. dec Temp3
  734. ELSE
  735. jnz dithering_done
  736. dec Temp2
  737. ENDIF
  738. dithering_done:
  739. ENDIF
  740. ; Set pwm registers
  741. IF FETON_DELAY != 0
  742. clr C
  743. mov A, Temp2 ; Skew damping fet timing
  744. IF MCU_48MHZ == 0
  745. subb A, #((FETON_DELAY+1) SHR 1)
  746. ELSE
  747. subb A, #(FETON_DELAY)
  748. ENDIF
  749. mov Temp4, A
  750. mov A, Temp3
  751. subb A, #0
  752. mov Temp5, A
  753. jnc t1_int_set_pwm_damp_set
  754. clr A
  755. mov Temp4, A
  756. mov Temp5, A
  757. t1_int_set_pwm_damp_set:
  758. ENDIF
  759. mov Power_Pwm_Reg_L, Temp2
  760. mov Power_Pwm_Reg_H, Temp3
  761. IF FETON_DELAY != 0
  762. mov Damp_Pwm_Reg_L, Temp4
  763. mov Damp_Pwm_Reg_H, Temp5
  764. ENDIF
  765. mov Rcp_Timeout_Cntd, #10 ; Set timeout count
  766. ; Prepare DShot telemetry
  767. jnb Flag_RCP_DSHOT_INVERTED, t1_int_exit_no_tlm ; Only send telemetry for inverted DShot
  768. jnb Flag_PACKET_PENDING, t1_int_exit_no_tlm ; Check if telemetry packet is ready
  769. ; Prepare timer 0 for sending telemetry data
  770. ; todo: dshot150
  771. ;mov Temp2, CKCON0 ; Save value to restore later
  772. mov CKCON0, #01h ; Timer 0 is system clock divided by 4
  773. mov TMOD, #0A2h ; Timer 0 runs free not gated by INT0
  774. mov TL0, DShot_GCR_Start_Delay ; Telemetry will begin after this delay
  775. clr TCON_TF0 ; Clear timer 0 overflow flag
  776. setb IE_ET0 ; Enable timer 0 interrupts
  777. ; Configure RTX_PIN for digital output
  778. setb RTX_PORT.RTX_PIN ; Default to high level
  779. orl RTX_MDOUT, #(1 SHL RTX_PIN) ; Set output mode to push-pull
  780. mov Temp1, #0 ; Set pointer to start
  781. sjmp t1_int_exit_no_int
  782. t1_int_exit_no_tlm:
  783. mov Temp1, #0 ; Set pointer to start
  784. mov TL0, #0 ; Reset timer 0
  785. setb IE_EX0 ; Enable int0 interrupts
  786. setb IE_EX1 ; Enable int1 interrupts
  787. Enable_PCA_Interrupt ; Enable pca interrupts
  788. t1_int_exit_no_int:
  789. pop B ; Restore preserved registers
  790. pop ACC
  791. pop PSW
  792. reti
  793. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  794. ;
  795. ; Timer 2 interrupt routine
  796. ;
  797. ; Requirements: Temp variables can NOT be used since PSW.x is not set
  798. ;
  799. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  800. t2_int: ; Happens every 32ms
  801. push ACC
  802. clr TMR2CN0_TF2H ; Clear interrupt flag
  803. inc Timer2_X
  804. IF MCU_48MHZ == 1
  805. jnb Flag_CLOCK_SET_AT_48MHZ, t2_int_start
  806. ; Check skip variable
  807. jbc Flag_SKIP_T2_INT, t2_int_exit ; Skip this interrupt
  808. t2_int_start:
  809. setb Flag_SKIP_T2_INT ; Skip next interrupt
  810. ENDIF
  811. ; Update RC pulse timeout counter
  812. mov A, Rcp_Timeout_Cntd ; RC pulse timeout count zero?
  813. jz ($+4) ; Yes - do not decrement
  814. dec Rcp_Timeout_Cntd ; No decrement
  815. jnb Flag_RCP_STOP, t2_int_exit ; Exit if pulse is above stop value
  816. inc Rcp_Stop_Cnt ; Otherwise, increment stop counter
  817. mov A, Rcp_Stop_Cnt
  818. jnz ($+4) ; Branch if counter has not wrapped
  819. dec Rcp_Stop_Cnt ; Set stop counter to max
  820. t2_int_exit:
  821. pop ACC ; Restore preserved registers
  822. reti
  823. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  824. ;
  825. ; Timer 3 interrupt routine
  826. ;
  827. ; Requirements: Temp variables can NOT be used since PSW.x is not set
  828. ; ACC can not be used, as it is not pushed to stack
  829. ;
  830. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  831. t3_int: ; Used for commutation timing
  832. clr IE_EA ; Disable all interrupts
  833. anl EIE1, #7Fh ; Disable timer 3 interrupts
  834. anl TMR3CN0, #07Fh ; Clear timer 3 interrupt flag
  835. mov TMR3RLL, #0FAh ; Set a short delay before next interrupt
  836. mov TMR3RLH, #0FFh
  837. clr Flag_T3_PENDING ; Flag that timer has wrapped
  838. setb IE_EA ; Enable all interrupts
  839. reti
  840. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  841. ;
  842. ; Int0 interrupt routine
  843. ;
  844. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  845. int0_int: ; Used for RC pulse timing
  846. push ACC
  847. mov A, TL0 ; Read pwm for DShot immediately
  848. mov TL1, DShot_Timer_Preset ; Reset sync timer
  849. ; Temp1 in register bank 1 points to pwm timings
  850. push PSW
  851. mov PSW, #8h
  852. movx @Temp1, A ; Store pwm
  853. inc Temp1
  854. pop PSW
  855. pop ACC
  856. reti
  857. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  858. ;
  859. ; Int1 interrupt routine
  860. ;
  861. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  862. int1_int: ; Used for RC pulse timing
  863. clr IE_EX1 ; Disable int1 interrupts
  864. setb TCON_TR1 ; Start timer 1
  865. clr TMR2CN0_TR2 ; Timer 2 disabled
  866. mov DShot_Frame_Start_L, TMR2L ; Read timer value
  867. mov DShot_Frame_Start_H, TMR2H
  868. setb TMR2CN0_TR2 ; Timer 2 enabled
  869. reti
  870. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  871. ;
  872. ; PCA interrupt routine
  873. ;
  874. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  875. pca_int: ; Used for setting pwm registers
  876. clr IE_EA
  877. push ACC
  878. IF FETON_DELAY != 0 ; HI/LO enable style drivers
  879. mov A, PCA0L ; Read low byte first, to transfer high byte to holding register
  880. mov A, PCA0H
  881. jnb Flag_LOW_PWM_POWER, pca_int_hi_pwm
  882. ; Power below 50%, update pca in the 0x00-0x0F range
  883. jb ACC.PWM_BITS_H, pca_int_exit ; PWM edge selection bit (continue if up edge)
  884. sjmp pca_int_set_pwm
  885. pca_int_hi_pwm:
  886. ; Power above 50%, update pca in the 0x20-0x2F range
  887. jnb ACC.PWM_BITS_H, pca_int_exit ; PWM edge selection bit (continue if down edge)
  888. pca_int_set_pwm:
  889. IF PWM_BITS_H != 0
  890. jb ACC.(PWM_BITS_H-1), pca_int_exit
  891. ELSE
  892. mov A, PCA0L
  893. jb ACC.7, pca_int_exit
  894. ENDIF
  895. ENDIF
  896. ; Set power pwm auto-reload registers
  897. IF PWM_BITS_H != 0
  898. mov PCA0_POWER_L, Power_Pwm_Reg_L
  899. mov PCA0_POWER_H, Power_Pwm_Reg_H
  900. ELSE
  901. mov PCA0_POWER_H, Power_Pwm_Reg_L
  902. ENDIF
  903. IF FETON_DELAY != 0
  904. ; Set damp pwm auto-reload registers
  905. IF PWM_BITS_H != 0
  906. mov PCA0_DAMP_L, Damp_Pwm_Reg_L
  907. mov PCA0_DAMP_H, Damp_Pwm_Reg_H
  908. ELSE
  909. mov PCA0_DAMP_H, Damp_Pwm_Reg_L
  910. ENDIF
  911. ENDIF
  912. setb Flag_LOW_PWM_POWER
  913. IF PWM_BITS_H != 0
  914. mov A, Power_Pwm_Reg_H
  915. jb ACC.(PWM_BITS_H-1), ($+5)
  916. ELSE
  917. mov A, Power_Pwm_Reg_L
  918. jb ACC.7, ($+5)
  919. ENDIF
  920. clr Flag_LOW_PWM_POWER
  921. Disable_COVF_Interrupt
  922. IF FETON_DELAY == 0 ; EN/PWM style drivers
  923. Disable_CCF_Interrupt
  924. ENDIF
  925. anl EIE1, #0EFh ; Pwm updated, disable pca interrupts
  926. pca_int_exit:
  927. Clear_COVF_Interrupt
  928. IF FETON_DELAY == 0
  929. Clear_CCF_Interrupt
  930. ENDIF
  931. pop ACC ; Restore preserved registers
  932. setb IE_EA
  933. reti
  934. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  935. ;
  936. ; DShot GCR encode
  937. ;
  938. ; GCR encode e-period data for DShot telemetry
  939. ;
  940. ; Input
  941. ; - Temp1: Data pointer for storing pulse timings
  942. ; - A: 4-bit value to GCR encode
  943. ; - B: Time that must be added to transition
  944. ; Output
  945. ; - B: Time remaining to be added to next transition
  946. ;
  947. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  948. dshot_gcr_encode:
  949. anl A, #0Fh
  950. rl A ; Multiply by 2 to match jump offsets
  951. mov DPTR, #dshot_gcr_encode_jump_table
  952. jmp @A+DPTR
  953. dshot_gcr_encode_jump_table:
  954. ajmp dshot_gcr_encode_0_11001
  955. ajmp dshot_gcr_encode_1_11011
  956. ajmp dshot_gcr_encode_2_10010
  957. ajmp dshot_gcr_encode_3_10011
  958. ajmp dshot_gcr_encode_4_11101
  959. ajmp dshot_gcr_encode_5_10101
  960. ajmp dshot_gcr_encode_6_10110
  961. ajmp dshot_gcr_encode_7_10111
  962. ajmp dshot_gcr_encode_8_11010
  963. ajmp dshot_gcr_encode_9_01001
  964. ajmp dshot_gcr_encode_A_01010
  965. ajmp dshot_gcr_encode_B_01011
  966. ajmp dshot_gcr_encode_C_11110
  967. ajmp dshot_gcr_encode_D_01101
  968. ajmp dshot_gcr_encode_E_01110
  969. ajmp dshot_gcr_encode_F_01111
  970. ; GCR encoding is ordered by least significant bit first,
  971. ; and represented as pulse durations.
  972. dshot_gcr_encode_0_11001:
  973. Push_Mem Temp1, Tmp_B
  974. Push_Mem Temp1, DShot_GCR_Pulse_Time_3
  975. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  976. mov Tmp_B, DShot_GCR_Pulse_Time_1
  977. ret
  978. dshot_gcr_encode_1_11011:
  979. Push_Mem Temp1, Tmp_B
  980. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  981. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  982. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  983. mov Tmp_B, DShot_GCR_Pulse_Time_1
  984. ret
  985. dshot_gcr_encode_2_10010:
  986. DShot_GCR_Get_Time
  987. Push_Mem Temp1, A
  988. Push_Mem Temp1, DShot_GCR_Pulse_Time_3
  989. mov Tmp_B, DShot_GCR_Pulse_Time_1
  990. ret
  991. dshot_gcr_encode_3_10011:
  992. Push_Mem Temp1, Tmp_B
  993. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  994. Push_Mem Temp1, DShot_GCR_Pulse_Time_3
  995. mov Tmp_B, DShot_GCR_Pulse_Time_1
  996. ret
  997. dshot_gcr_encode_4_11101:
  998. Push_Mem Temp1, Tmp_B
  999. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1000. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1001. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1002. mov Tmp_B, DShot_GCR_Pulse_Time_1
  1003. ret
  1004. dshot_gcr_encode_5_10101:
  1005. Push_Mem Temp1, Tmp_B
  1006. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1007. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1008. mov Tmp_B, DShot_GCR_Pulse_Time_1
  1009. ret
  1010. dshot_gcr_encode_6_10110:
  1011. DShot_GCR_Get_Time
  1012. Push_Mem Temp1, A
  1013. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1014. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1015. mov Tmp_B, DShot_GCR_Pulse_Time_1
  1016. ret
  1017. dshot_gcr_encode_7_10111:
  1018. Push_Mem Temp1, Tmp_B
  1019. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1020. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1021. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1022. mov Tmp_B, DShot_GCR_Pulse_Time_1
  1023. ret
  1024. dshot_gcr_encode_8_11010:
  1025. DShot_GCR_Get_Time
  1026. Push_Mem Temp1, A
  1027. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1028. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1029. mov Tmp_B, DShot_GCR_Pulse_Time_1
  1030. ret
  1031. dshot_gcr_encode_9_01001:
  1032. Push_Mem Temp1, Tmp_B
  1033. Push_Mem Temp1, DShot_GCR_Pulse_Time_3
  1034. mov Tmp_B, DShot_GCR_Pulse_Time_2
  1035. ret
  1036. dshot_gcr_encode_A_01010:
  1037. DShot_GCR_Get_Time
  1038. Push_Mem Temp1, A
  1039. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1040. mov Tmp_B, DShot_GCR_Pulse_Time_2
  1041. ret
  1042. dshot_gcr_encode_B_01011:
  1043. Push_Mem Temp1, Tmp_B
  1044. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1045. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1046. mov Tmp_B, DShot_GCR_Pulse_Time_2
  1047. ret
  1048. dshot_gcr_encode_C_11110:
  1049. DShot_GCR_Get_Time
  1050. Push_Mem Temp1, A
  1051. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1052. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1053. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1054. mov Tmp_B, DShot_GCR_Pulse_Time_1
  1055. ret
  1056. dshot_gcr_encode_D_01101:
  1057. Push_Mem Temp1, Tmp_B
  1058. Push_Mem Temp1, DShot_GCR_Pulse_Time_2
  1059. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1060. mov Tmp_B, DShot_GCR_Pulse_Time_2
  1061. ret
  1062. dshot_gcr_encode_E_01110:
  1063. DShot_GCR_Get_Time
  1064. Push_Mem Temp1, A
  1065. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1066. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1067. mov Tmp_B, DShot_GCR_Pulse_Time_2
  1068. ret
  1069. dshot_gcr_encode_F_01111:
  1070. Push_Mem Temp1, Tmp_B
  1071. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1072. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1073. Push_Mem Temp1, DShot_GCR_Pulse_Time_1
  1074. mov Tmp_B, DShot_GCR_Pulse_Time_2
  1075. ret
  1076. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1077. ;
  1078. ; DShot 12-bit encode
  1079. ;
  1080. ; Encodes 16-bit e-period as a 12-bit value of the form:
  1081. ; <e e e m m m m m m m m m> where M SHL E ~ e-period [us]
  1082. ;
  1083. ; Note: Not callable to improve performance
  1084. ;
  1085. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1086. dshot_12bit_7:
  1087. ;mov A, Tlm_Data_H
  1088. mov C, Tlm_Data_L.7
  1089. rlc A
  1090. mov Tlm_Data_L, A
  1091. mov Tlm_Data_H, #0fh
  1092. ajmp dshot_tlm_12bit_encoded
  1093. dshot_12bit_6:
  1094. ;mov A, Tlm_Data_H
  1095. mov C, Tlm_Data_L.7
  1096. rlc A
  1097. mov C, Tlm_Data_L.6
  1098. rlc A
  1099. mov Tlm_Data_L, A
  1100. mov Tlm_Data_H, #0dh
  1101. ajmp dshot_tlm_12bit_encoded
  1102. dshot_12bit_5:
  1103. ;mov A, Tlm_Data_H
  1104. mov C, Tlm_Data_L.7
  1105. rlc A
  1106. mov C, Tlm_Data_L.6
  1107. rlc A
  1108. mov C, Tlm_Data_L.5
  1109. rlc A
  1110. mov Tlm_Data_L, A
  1111. mov Tlm_Data_H, #0bh
  1112. ajmp dshot_tlm_12bit_encoded
  1113. dshot_12bit_4:
  1114. mov A, Tlm_Data_L
  1115. anl A, #0f0h
  1116. clr Tlm_Data_H.4
  1117. orl A, Tlm_Data_H
  1118. swap A
  1119. mov Tlm_Data_L, A
  1120. mov Tlm_Data_H, #09h
  1121. ajmp dshot_tlm_12bit_encoded
  1122. dshot_12bit_3:
  1123. mov A, Tlm_Data_L
  1124. mov C, Tlm_Data_H.0
  1125. rrc A
  1126. mov C, Tlm_Data_H.1
  1127. rrc A
  1128. mov C, Tlm_Data_H.2
  1129. rrc A
  1130. mov Tlm_Data_L, A
  1131. mov Tlm_Data_H, #07h
  1132. ajmp dshot_tlm_12bit_encoded
  1133. dshot_12bit_2:
  1134. mov A, Tlm_Data_L
  1135. mov C, Tlm_Data_H.0
  1136. rrc A
  1137. mov C, Tlm_Data_H.1
  1138. rrc A
  1139. mov Tlm_Data_L, A
  1140. mov Tlm_Data_H, #05h
  1141. ajmp dshot_tlm_12bit_encoded
  1142. dshot_12bit_1:
  1143. mov A, Tlm_Data_L
  1144. mov C, Tlm_Data_H.0
  1145. rrc A
  1146. mov Tlm_Data_L, A
  1147. mov Tlm_Data_H, #03h
  1148. ajmp dshot_tlm_12bit_encoded
  1149. dshot_12bit_encode:
  1150. ; Encode 16-bit e-period as a 12-bit value
  1151. jb ACC.7, dshot_12bit_7 ; ACC = Tlm_Data_H
  1152. jb ACC.6, dshot_12bit_6
  1153. jb ACC.5, dshot_12bit_5
  1154. jb ACC.4, dshot_12bit_4
  1155. jb ACC.3, dshot_12bit_3
  1156. jb ACC.2, dshot_12bit_2
  1157. jb ACC.1, dshot_12bit_1
  1158. mov A, Tlm_Data_L ; Already 12-bit (E=0)
  1159. ajmp dshot_tlm_12bit_encoded
  1160. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1161. ;
  1162. ; DShot telemetry create packet
  1163. ;
  1164. ; Create DShot telemetry packet and prepare it for being sent
  1165. ; The routine is divided into 6 sections that can return early
  1166. ; in order to reduce commutation interference
  1167. ;
  1168. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1169. dshot_tlm_create_packet:
  1170. push PSW
  1171. mov PSW, #10h ; Select register bank 2
  1172. Early_Return_Packet_Stage 0
  1173. ; Read commutation period
  1174. clr IE_EA
  1175. mov Tlm_Data_L, Comm_Period4x_L
  1176. mov Tlm_Data_H, Comm_Period4x_H
  1177. setb IE_EA
  1178. ; Multiply period by 3/4 (1/2 + 1/4)
  1179. mov A, Tlm_Data_L
  1180. mov C, Tlm_Data_H.0
  1181. rrc A
  1182. mov Temp2, A
  1183. mov C, Tlm_Data_H.1
  1184. rrc A
  1185. add A, Temp2
  1186. mov Tlm_Data_L, A
  1187. mov A, Tlm_Data_H
  1188. rr A
  1189. clr ACC.7
  1190. mov Temp2, A
  1191. rr A
  1192. clr ACC.7
  1193. addc A, Temp2
  1194. mov Tlm_Data_H, A
  1195. Early_Return_Packet_Stage 1
  1196. mov A, Tlm_Data_H
  1197. ; 12-bit encode telemetry data
  1198. jnz dshot_12bit_encode
  1199. mov A, Tlm_Data_L ; Already 12-bit
  1200. jnz dshot_tlm_12bit_encoded
  1201. ; If period is zero then reset to FFFFh (FFFh for 12-bit)
  1202. mov Tlm_Data_H, #0Fh
  1203. mov Tlm_Data_L, #0FFh
  1204. dshot_tlm_12bit_encoded:
  1205. Early_Return_Packet_Stage 2
  1206. mov A, Tlm_Data_L
  1207. ; Compute inverted xor checksum (4-bit)
  1208. swap A
  1209. xrl A, Tlm_Data_L
  1210. xrl A, Tlm_Data_H
  1211. cpl A
  1212. ; GCR encode the telemetry data (16-bit)
  1213. mov Temp1, #Temp_Storage ; Store pulse timings in Temp_Storage
  1214. mov Tmp_B, DShot_GCR_Pulse_Time_1 ; Final transition time
  1215. call dshot_gcr_encode ; GCR encode lowest 4-bit of A (store through Temp1)
  1216. Early_Return_Packet_Stage 3
  1217. mov A, Tlm_Data_L
  1218. call dshot_gcr_encode
  1219. Early_Return_Packet_Stage 4
  1220. mov A, Tlm_Data_L
  1221. swap A
  1222. call dshot_gcr_encode
  1223. Early_Return_Packet_Stage 5
  1224. mov A, Tlm_Data_H
  1225. call dshot_gcr_encode
  1226. Push_Mem Temp1, Tmp_B ; Initial transition time
  1227. mov Temp5, #0
  1228. setb Flag_PACKET_PENDING
  1229. pop PSW
  1230. ret
  1231. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1232. ;
  1233. ; Wait xms ~(x*4*250) (Different entry points)
  1234. ;
  1235. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1236. wait1ms:
  1237. mov Temp2, #1
  1238. sjmp waitxms_o
  1239. wait3ms:
  1240. mov Temp2, #3
  1241. sjmp waitxms_o
  1242. wait10ms:
  1243. mov Temp2, #10
  1244. sjmp waitxms_o
  1245. wait30ms:
  1246. mov Temp2, #30
  1247. sjmp waitxms_o
  1248. wait100ms:
  1249. mov Temp2, #100
  1250. sjmp waitxms_o
  1251. wait200ms:
  1252. mov Temp2, #200
  1253. sjmp waitxms_o
  1254. waitxms_o: ; Outer loop
  1255. mov Temp1, #23
  1256. waitxms_m: ; Middle loop
  1257. clr A
  1258. djnz ACC, $ ; Inner loop (42.7us - 1024 cycles)
  1259. djnz Temp1, waitxms_m
  1260. djnz Temp2, waitxms_o
  1261. ret
  1262. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1263. ;
  1264. ; Set pwm limit low rpm
  1265. ;
  1266. ; Sets power limit for low rpms and disables demag for low rpms
  1267. ;
  1268. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1269. set_pwm_limit:
  1270. jb Flag_HIGH_RPM, set_pwm_limit_high_rpm ; If high rpm, limit pwm by rpm instead
  1271. ;set_pwm_limit_low_rpm:
  1272. ; Set pwm limit
  1273. mov Temp1, #0FFh ; Default full power
  1274. jb Flag_STARTUP_PHASE, set_pwm_limit_low_rpm_exit ; Exit if startup phase set
  1275. mov Temp2, #Pgm_Enable_Power_Prot ; Check if low RPM power protection is enabled
  1276. mov A, @Temp2
  1277. jz set_pwm_limit_low_rpm_exit ; Exit if disabled
  1278. mov A, Comm_Period4x_H
  1279. jz set_pwm_limit_low_rpm_exit ; Avoid divide by zero
  1280. mov A, #255 ; Divide 255 by Comm_Period4x_H
  1281. mov B, Comm_Period4x_H
  1282. div AB
  1283. mov B, Low_Rpm_Pwr_Slope ; Multiply by slope
  1284. jnb Flag_INITIAL_RUN_PHASE, ($+6) ; More protection for initial run phase
  1285. mov B, #5
  1286. mul AB
  1287. mov Temp1, A ; Set new limit
  1288. xch A, B
  1289. jz ($+4) ; Limit to max
  1290. mov Temp1, #0FFh
  1291. clr C
  1292. mov A, Temp1 ; Limit to min
  1293. subb A, Pwm_Limit_Beg
  1294. jnc set_pwm_limit_low_rpm_exit
  1295. mov Temp1, Pwm_Limit_Beg
  1296. set_pwm_limit_low_rpm_exit:
  1297. mov Pwm_Limit_By_Rpm, Temp1
  1298. ret
  1299. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1300. ;
  1301. ; Set pwm limit high rpm
  1302. ;
  1303. ; Sets power limit for high rpms
  1304. ;
  1305. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1306. set_pwm_limit_high_rpm:
  1307. clr C
  1308. mov A, Comm_Period4x_L
  1309. IF MCU_48MHZ == 1
  1310. subb A, #0A0h ; Limit Comm_Period to 160, which is 500k erpm
  1311. ELSE
  1312. subb A, #0E4h ; Limit Comm_Period to 228, which is 350k erpm
  1313. ENDIF
  1314. mov A, Comm_Period4x_H
  1315. subb A, #00h
  1316. mov A, Pwm_Limit_By_Rpm
  1317. jnc set_pwm_limit_high_rpm_inc_limit
  1318. dec A
  1319. sjmp set_pwm_limit_high_rpm_store
  1320. set_pwm_limit_high_rpm_inc_limit:
  1321. inc A
  1322. set_pwm_limit_high_rpm_store:
  1323. jz ($+4)
  1324. mov Pwm_Limit_By_Rpm, A
  1325. ret
  1326. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1327. ;
  1328. ; Check temperature, power supply voltage and limit power
  1329. ;
  1330. ; Used to limit main motor power in order to maintain the required voltage
  1331. ;
  1332. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1333. check_temp_voltage_and_limit_power:
  1334. inc Adc_Conversion_Cnt ; Increment conversion counter
  1335. clr C
  1336. mov A, Adc_Conversion_Cnt ; Is conversion count equal to temp rate?
  1337. subb A, #8
  1338. jc check_voltage_start ; No - check voltage
  1339. ; Wait for ADC conversion to complete
  1340. jnb ADC0CN0_ADINT, check_temp_voltage_and_limit_power
  1341. ; Read ADC result
  1342. Read_Adc_Result
  1343. ; Stop ADC
  1344. Stop_Adc
  1345. mov Adc_Conversion_Cnt, #0 ; Yes - temperature check. Reset counter
  1346. mov A, Temp2 ; Move ADC MSB to Temp3
  1347. mov Temp3, A
  1348. mov Temp2, #Pgm_Enable_Temp_Prot ; Is temp protection enabled?
  1349. mov A, @Temp2
  1350. jz temp_check_exit ; No - branch
  1351. mov A, Temp3 ; Is temperature reading below 256?
  1352. jnz temp_average_inc_dec ; No - proceed
  1353. mov A, Current_Average_Temp ; Yes - decrement average
  1354. jz temp_average_updated ; Already zero - no change
  1355. sjmp temp_average_dec ; Decrement
  1356. temp_average_inc_dec:
  1357. clr C
  1358. mov A, Temp1 ; Check if current temperature is above or below average
  1359. subb A, Current_Average_Temp
  1360. jz temp_average_updated_load_acc ; Equal - no change
  1361. mov A, Current_Average_Temp ; Above - increment average
  1362. jnc temp_average_inc
  1363. jz temp_average_updated ; Below - decrement average if average is not already zero
  1364. temp_average_dec:
  1365. dec A ; Decrement average
  1366. sjmp temp_average_updated
  1367. temp_average_inc:
  1368. inc A ; Increment average
  1369. jz temp_average_dec
  1370. sjmp temp_average_updated
  1371. temp_average_updated_load_acc:
  1372. mov A, Current_Average_Temp
  1373. temp_average_updated:
  1374. mov Current_Average_Temp, A
  1375. clr C
  1376. subb A, Temp_Prot_Limit ; Is temperature below first limit?
  1377. jc temp_check_exit ; Yes - exit
  1378. mov Pwm_Limit, #192 ; No - limit pwm
  1379. clr C
  1380. subb A, #(TEMP_LIMIT_STEP/2) ; Is temperature below second limit
  1381. jc temp_check_exit ; Yes - exit
  1382. mov Pwm_Limit, #128 ; No - limit pwm
  1383. clr C
  1384. subb A, #(TEMP_LIMIT_STEP/2) ; Is temperature below third limit
  1385. jc temp_check_exit ; Yes - exit
  1386. mov Pwm_Limit, #64 ; No - limit pwm
  1387. clr C
  1388. subb A, #(TEMP_LIMIT_STEP/2) ; Is temperature below final limit
  1389. jc temp_check_exit ; Yes - exit
  1390. mov Pwm_Limit, #0 ; No - limit pwm
  1391. temp_check_exit:
  1392. ret
  1393. check_voltage_start:
  1394. ; Increase pwm limit
  1395. mov A, Pwm_Limit
  1396. add A, #16
  1397. jnc ($+4) ; If not max - branch
  1398. mov A, #255
  1399. mov Pwm_Limit, A ; Increment limit
  1400. ret
  1401. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1402. ;
  1403. ; Initialize timing routine
  1404. ;
  1405. ; Part of initialization before motor start
  1406. ;
  1407. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1408. initialize_timing:
  1409. mov Comm_Period4x_L, #00h ; Set commutation period registers
  1410. mov Comm_Period4x_H, #0F0h
  1411. ret
  1412. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1413. ;
  1414. ; Calculate next commutation timing routine
  1415. ;
  1416. ; Called immediately after each commutation
  1417. ; Also sets up timer 3 to wait advance timing
  1418. ; Two entry points are used
  1419. ;
  1420. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1421. calc_next_comm_timing: ; Entry point for run phase
  1422. ; Read commutation time
  1423. clr IE_EA
  1424. clr TMR2CN0_TR2 ; Timer 2 disabled
  1425. mov Temp1, TMR2L ; Load timer value
  1426. mov Temp2, TMR2H
  1427. mov Temp3, Timer2_X
  1428. jnb TMR2CN0_TF2H, ($+4) ; Check if interrupt is pending
  1429. inc Temp3 ; If it is pending, then timer has already wrapped
  1430. setb TMR2CN0_TR2 ; Timer 2 enabled
  1431. setb IE_EA
  1432. IF MCU_48MHZ == 1
  1433. clr C
  1434. mov A, Temp3
  1435. rrc A
  1436. mov Temp3, A
  1437. mov A, Temp2
  1438. rrc A
  1439. mov Temp2, A
  1440. mov A, Temp1
  1441. rrc A
  1442. mov Temp1, A
  1443. ENDIF
  1444. ; Calculate this commutation time
  1445. mov Temp4, Prev_Comm_L
  1446. mov Temp5, Prev_Comm_H
  1447. mov Prev_Comm_L, Temp1 ; Store timestamp as previous commutation
  1448. mov Prev_Comm_H, Temp2
  1449. clr C
  1450. mov A, Temp1
  1451. subb A, Temp4 ; Calculate the new commutation time
  1452. mov Temp1, A
  1453. mov A, Temp2
  1454. subb A, Temp5
  1455. jb Flag_STARTUP_PHASE, calc_next_comm_startup
  1456. IF MCU_48MHZ == 1
  1457. anl A, #7Fh
  1458. ENDIF
  1459. mov Temp2, A
  1460. jnb Flag_HIGH_RPM, calc_next_comm_normal ; Branch normal rpm
  1461. ajmp calc_next_comm_timing_fast ; Branch high rpm
  1462. calc_next_comm_startup:
  1463. mov Temp6, Prev_Comm_X
  1464. mov Prev_Comm_X, Temp3 ; Store extended timestamp as previous commutation
  1465. mov Temp2, A
  1466. mov A, Temp3
  1467. subb A, Temp6 ; Calculate the new extended commutation time
  1468. IF MCU_48MHZ == 1
  1469. anl A, #7Fh
  1470. ENDIF
  1471. mov Temp3, A
  1472. jz calc_next_comm_startup_no_X
  1473. mov Temp1, #0FFh
  1474. mov Temp2, #0FFh
  1475. sjmp calc_next_comm_startup_average
  1476. calc_next_comm_startup_no_X:
  1477. mov Temp7, Prev_Prev_Comm_L
  1478. mov Temp8, Prev_Prev_Comm_H
  1479. mov Prev_Prev_Comm_L, Temp4
  1480. mov Prev_Prev_Comm_H, Temp5
  1481. mov Temp1, Prev_Comm_L ; Reload this commutation time
  1482. mov Temp2, Prev_Comm_H
  1483. clr C
  1484. mov A, Temp1
  1485. subb A, Temp7 ; Calculate the new commutation time based upon the two last commutations (to reduce sensitivity to offset)
  1486. mov Temp1, A
  1487. mov A, Temp2
  1488. subb A, Temp8
  1489. mov Temp2, A
  1490. calc_next_comm_startup_average:
  1491. clr C
  1492. mov A, Comm_Period4x_H ; Average with previous and save
  1493. rrc A
  1494. mov Temp4, A
  1495. mov A, Comm_Period4x_L
  1496. rrc A
  1497. mov Temp3, A
  1498. mov A, Temp1
  1499. add A, Temp3
  1500. mov Comm_Period4x_L, A
  1501. mov A, Temp2
  1502. addc A, Temp4
  1503. mov Comm_Period4x_H, A
  1504. jnc ($+8)
  1505. mov Comm_Period4x_L, #0FFh
  1506. mov Comm_Period4x_H, #0FFh
  1507. sjmp calc_new_wait_times_setup
  1508. calc_next_comm_normal:
  1509. ; Calculate new commutation time
  1510. mov Temp3, Comm_Period4x_L ; Comm_Period4x(-l-h) holds the time of 4 commutations
  1511. mov Temp4, Comm_Period4x_H
  1512. mov Temp5, Comm_Period4x_L ; Copy variables
  1513. mov Temp6, Comm_Period4x_H
  1514. mov Temp7, #4 ; Divide Comm_Period4x 4 times as default
  1515. mov Temp8, #2 ; Divide new commutation time 2 times as default
  1516. clr C
  1517. mov A, Temp4
  1518. subb A, #04h
  1519. jc calc_next_comm_avg_period_div
  1520. dec Temp7 ; Reduce averaging time constant for low speeds
  1521. dec Temp8
  1522. clr C
  1523. mov A, Temp4
  1524. subb A, #08h
  1525. jc calc_next_comm_avg_period_div
  1526. jb Flag_INITIAL_RUN_PHASE, calc_next_comm_avg_period_div ; Do not average very fast during initial run
  1527. dec Temp7 ; Reduce averaging time constant more for even lower speeds
  1528. dec Temp8
  1529. calc_next_comm_avg_period_div:
  1530. clr C
  1531. mov A, Temp6
  1532. rrc A ; Divide by 2
  1533. mov Temp6, A
  1534. mov A, Temp5
  1535. rrc A
  1536. mov Temp5, A
  1537. djnz Temp7, calc_next_comm_avg_period_div
  1538. clr C
  1539. mov A, Temp3
  1540. subb A, Temp5 ; Subtract a fraction
  1541. mov Temp3, A
  1542. mov A, Temp4
  1543. subb A, Temp6
  1544. mov Temp4, A
  1545. mov A, Temp8 ; Divide new time
  1546. jz calc_next_comm_new_period_div_done
  1547. calc_next_comm_new_period_div:
  1548. clr C
  1549. mov A, Temp2
  1550. rrc A ; Divide by 2
  1551. mov Temp2, A
  1552. mov A, Temp1
  1553. rrc A
  1554. mov Temp1, A
  1555. djnz Temp8, calc_next_comm_new_period_div
  1556. calc_next_comm_new_period_div_done:
  1557. mov A, Temp3
  1558. add A, Temp1 ; Add the divided new time
  1559. mov Temp3, A
  1560. mov A, Temp4
  1561. addc A, Temp2
  1562. mov Temp4, A
  1563. mov Comm_Period4x_L, Temp3 ; Store Comm_Period4x_X
  1564. mov Comm_Period4x_H, Temp4
  1565. jnc calc_new_wait_times_setup; If period larger than 0xffff - go to slow case
  1566. mov Temp4, #0FFh
  1567. mov Comm_Period4x_L, Temp4 ; Set commutation period registers to very slow timing (0xffff)
  1568. mov Comm_Period4x_H, Temp4
  1569. calc_new_wait_times_setup:
  1570. ; Set high rpm bit (if above 156k erpm)
  1571. clr C
  1572. mov A, Temp4
  1573. subb A, #2
  1574. jnc ($+4)
  1575. setb Flag_HIGH_RPM ; Set high rpm bit
  1576. ; Load programmed commutation timing
  1577. jnb Flag_STARTUP_PHASE, calc_new_wait_per_startup_done ; Set dedicated timing during startup
  1578. mov Temp8, #3
  1579. sjmp calc_new_wait_per_demag_done
  1580. calc_new_wait_per_startup_done:
  1581. mov Temp1, #Pgm_Comm_Timing ; Load timing setting
  1582. mov A, @Temp1
  1583. mov Temp8, A ; Store in Temp8
  1584. clr C
  1585. mov A, Demag_Detected_Metric ; Check demag metric
  1586. subb A, #130
  1587. jc calc_new_wait_per_demag_done
  1588. inc Temp8 ; Increase timing
  1589. clr C
  1590. mov A, Demag_Detected_Metric
  1591. subb A, #160
  1592. jc ($+3)
  1593. inc Temp8 ; Increase timing again
  1594. clr C
  1595. mov A, Temp8 ; Limit timing to max
  1596. subb A, #6
  1597. jc ($+4)
  1598. mov Temp8, #5 ; Set timing to max
  1599. calc_new_wait_per_demag_done:
  1600. ; Set timing reduction
  1601. mov Temp7, #2
  1602. ; Load current commutation timing
  1603. mov A, Comm_Period4x_H ; Divide 4 times
  1604. swap A
  1605. anl A, #00Fh
  1606. mov Temp2, A
  1607. mov A, Comm_Period4x_H
  1608. swap A
  1609. anl A, #0F0h
  1610. mov Temp1, A
  1611. mov A, Comm_Period4x_L
  1612. swap A
  1613. anl A, #00Fh
  1614. add A, Temp1
  1615. mov Temp1, A
  1616. clr C
  1617. mov A, Temp1
  1618. subb A, Temp7
  1619. mov Temp3, A
  1620. mov A, Temp2
  1621. subb A, #0
  1622. mov Temp4, A
  1623. jc load_min_time ; Check that result is still positive
  1624. jnz calc_new_wait_times_exit ; Check that result is still above minumum
  1625. mov A, Temp3
  1626. jnz calc_new_wait_times_exit
  1627. load_min_time:
  1628. mov Temp3, #1
  1629. mov Temp4, #0
  1630. calc_new_wait_times_exit:
  1631. sjmp wait_advance_timing
  1632. ; Fast calculation (Comm_Period4x_H less than 2)
  1633. calc_next_comm_timing_fast:
  1634. ; Calculate new commutation time
  1635. mov Temp3, Comm_Period4x_L ; Comm_Period4x(-l-h) holds the time of 4 commutations
  1636. mov Temp4, Comm_Period4x_H
  1637. mov A, Temp4 ; Divide by 2 4 times
  1638. swap A
  1639. mov Temp7, A
  1640. mov A, Temp3
  1641. swap A
  1642. anl A, #0Fh
  1643. orl A, Temp7
  1644. mov Temp5, A
  1645. clr C
  1646. mov A, Temp3 ; Subtract a fraction
  1647. subb A, Temp5
  1648. mov Temp3, A
  1649. mov A, Temp4
  1650. subb A, #0
  1651. mov Temp4, A
  1652. clr C
  1653. mov A, Temp1
  1654. rrc A ; Divide by 2 2 times
  1655. clr C
  1656. rrc A
  1657. mov Temp1, A
  1658. mov A, Temp3 ; Add the divided new time
  1659. add A, Temp1
  1660. mov Temp3, A
  1661. mov A, Temp4
  1662. addc A, #0
  1663. mov Temp4, A
  1664. mov Comm_Period4x_L, Temp3 ; Store Comm_Period4x_X
  1665. mov Comm_Period4x_H, Temp4
  1666. clr C
  1667. subb A, #2 ; If erpm below 156k - go to normal case
  1668. jc ($+4)
  1669. clr Flag_HIGH_RPM ; Clear high rpm bit
  1670. ; Set timing reduction
  1671. mov Temp1, #2
  1672. mov A, Temp4 ; Divide by 2 4 times
  1673. swap A
  1674. mov Temp7, A
  1675. mov Temp4, #0
  1676. mov A, Temp3
  1677. swap A
  1678. anl A, #0Fh
  1679. orl A, Temp7
  1680. mov Temp3, A
  1681. clr C
  1682. subb A, Temp1
  1683. mov Temp3, A
  1684. jc load_min_time_fast ; Check that result is still positive
  1685. jnz calc_new_wait_times_fast_done ; Check that result is still above minumum
  1686. load_min_time_fast:
  1687. mov Temp3, #1
  1688. calc_new_wait_times_fast_done:
  1689. mov Temp1, #Pgm_Comm_Timing ; Load timing setting
  1690. mov A, @Temp1
  1691. mov Temp8, A ; Store in Temp8
  1692. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1693. ;
  1694. ; Wait advance timing routine
  1695. ; NOTE: Be VERY careful if using temp registers. They are passed over this routine
  1696. ;
  1697. ; Waits for the advance timing to elapse and sets up the next zero cross wait
  1698. ;
  1699. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1700. wait_advance_timing:
  1701. Wait_For_Timer3
  1702. ; Setup next wait time
  1703. mov TMR3RLL, Wt_ZC_Tout_Start_L
  1704. mov TMR3RLH, Wt_ZC_Tout_Start_H
  1705. setb Flag_T3_PENDING
  1706. orl EIE1, #80h ; Enable timer 3 interrupts
  1707. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1708. ;
  1709. ; Calculate new wait times routine
  1710. ;
  1711. ; Calculates new wait times
  1712. ;
  1713. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1714. calc_new_wait_times:
  1715. clr C
  1716. clr A
  1717. subb A, Temp3 ; Negate
  1718. mov Temp1, A
  1719. clr A
  1720. subb A, Temp4
  1721. mov Temp2, A
  1722. IF MCU_48MHZ == 1
  1723. clr C
  1724. mov A, Temp1 ; Multiply by 2
  1725. rlc A
  1726. mov Temp1, A
  1727. mov A, Temp2
  1728. rlc A
  1729. mov Temp2, A
  1730. ENDIF
  1731. jb Flag_HIGH_RPM, calc_new_wait_times_fast ; Branch if high rpm
  1732. mov A, Temp1 ; Copy values
  1733. mov Temp3, A
  1734. mov A, Temp2
  1735. mov Temp4, A
  1736. setb C ; Negative numbers - set carry
  1737. mov A, Temp2
  1738. rrc A ; Divide by 2
  1739. mov Temp6, A
  1740. mov A, Temp1
  1741. rrc A
  1742. mov Temp5, A
  1743. mov Wt_Zc_Tout_Start_L, Temp1 ; Set 15deg time for zero cross scan timeout
  1744. mov Wt_Zc_Tout_Start_H, Temp2
  1745. clr C
  1746. mov A, Temp8 ; (Temp8 has Pgm_Comm_Timing)
  1747. subb A, #3 ; Is timing normal?
  1748. jz store_times_decrease ; Yes - branch
  1749. mov A, Temp8
  1750. jb ACC.0, adjust_timing_two_steps; If an odd number - branch
  1751. mov A, Temp1 ; Add 7.5deg and store in Temp1/2
  1752. add A, Temp5
  1753. mov Temp1, A
  1754. mov A, Temp2
  1755. addc A, Temp6
  1756. mov Temp2, A
  1757. mov A, Temp5 ; Store 7.5deg in Temp3/4
  1758. mov Temp3, A
  1759. mov A, Temp6
  1760. mov Temp4, A
  1761. sjmp store_times_up_or_down
  1762. adjust_timing_two_steps:
  1763. mov A, Temp1 ; Add 15deg and store in Temp1/2
  1764. setb C ; Add 1 to final result (Temp1/2 * 2 + 1)
  1765. addc A, Temp1
  1766. mov Temp1, A
  1767. mov A, Temp2
  1768. addc A, Temp2
  1769. mov Temp2, A
  1770. mov Temp3, #0FFh ; Store minimum time in Temp3/4
  1771. mov Temp4, #0FFh
  1772. store_times_up_or_down:
  1773. clr C
  1774. mov A, Temp8
  1775. subb A, #3 ; Is timing higher than normal?
  1776. jc store_times_decrease ; No - branch
  1777. store_times_increase:
  1778. mov Wt_Comm_Start_L, Temp3 ; Now commutation time (~60deg) divided by 4 (~15deg nominal)
  1779. mov Wt_Comm_Start_H, Temp4
  1780. mov Wt_Adv_Start_L, Temp1 ; New commutation advance time (~15deg nominal)
  1781. mov Wt_Adv_Start_H, Temp2
  1782. mov Wt_Zc_Scan_Start_L, Temp5 ; Use this value for zero cross scan delay (7.5deg)
  1783. mov Wt_Zc_Scan_Start_H, Temp6
  1784. sjmp wait_before_zc_scan
  1785. store_times_decrease:
  1786. mov Wt_Comm_Start_L, Temp1 ; Now commutation time (~60deg) divided by 4 (~15deg nominal)
  1787. mov Wt_Comm_Start_H, Temp2
  1788. mov Wt_Adv_Start_L, Temp3 ; New commutation advance time (~15deg nominal)
  1789. mov Wt_Adv_Start_H, Temp4
  1790. mov Wt_Zc_Scan_Start_L, Temp5 ; Use this value for zero cross scan delay (7.5deg)
  1791. mov Wt_Zc_Scan_Start_H, Temp6
  1792. jnb Flag_STARTUP_PHASE, store_times_exit
  1793. ; Set very short delays for all but advance time during startup, in order to widen zero cross capture range
  1794. mov Wt_Comm_Start_L, #0F0h
  1795. mov Wt_Comm_Start_H, #0FFh
  1796. mov Wt_Zc_Scan_Start_L, #0F0h
  1797. mov Wt_Zc_Scan_Start_H, #0FFh
  1798. mov Wt_Zc_Tout_Start_L, #0F0h
  1799. mov Wt_Zc_Tout_Start_H, #0FFh
  1800. store_times_exit:
  1801. sjmp wait_before_zc_scan
  1802. calc_new_wait_times_fast:
  1803. mov A, Temp1 ; Copy values
  1804. mov Temp3, A
  1805. setb C ; Negative numbers - set carry
  1806. rrc A ; Divide by 2
  1807. mov Temp5, A
  1808. mov Wt_Zc_Tout_Start_L, Temp1 ; Set 15deg time for zero cross scan timeout
  1809. clr C
  1810. mov A, Temp8 ; (Temp8 has Pgm_Comm_Timing)
  1811. subb A, #3 ; Is timing normal?
  1812. jz store_times_decrease_fast ; Yes - branch
  1813. mov A, Temp8
  1814. jb ACC.0, adjust_timing_two_steps_fast ; If an odd number - branch
  1815. mov A, Temp1 ; Add 7.5deg and store in Temp1
  1816. add A, Temp5
  1817. mov Temp1, A
  1818. mov A, Temp5 ; Store 7.5deg in Temp3
  1819. mov Temp3, A
  1820. sjmp store_times_up_or_down_fast
  1821. adjust_timing_two_steps_fast:
  1822. mov A, Temp1 ; Add 15deg and store in Temp1
  1823. add A, Temp1
  1824. add A, #1
  1825. mov Temp1, A
  1826. mov Temp3, #0FFh ; Store minimum time in Temp3
  1827. store_times_up_or_down_fast:
  1828. clr C
  1829. mov A, Temp8
  1830. subb A, #3 ; Is timing higher than normal?
  1831. jc store_times_decrease_fast ; No - branch
  1832. store_times_increase_fast:
  1833. mov Wt_Comm_Start_L, Temp3 ; Now commutation time (~60deg) divided by 4 (~15deg nominal)
  1834. mov Wt_Adv_Start_L, Temp1 ; New commutation advance time (~15deg nominal)
  1835. mov Wt_Zc_Scan_Start_L, Temp5 ; Use this value for zero cross scan delay (7.5deg)
  1836. sjmp wait_before_zc_scan
  1837. store_times_decrease_fast:
  1838. mov Wt_Comm_Start_L, Temp1 ; Now commutation time (~60deg) divided by 4 (~15deg nominal)
  1839. mov Wt_Adv_Start_L, Temp3 ; New commutation advance time (~15deg nominal)
  1840. mov Wt_Zc_Scan_Start_L, Temp5 ; Use this value for zero cross scan delay (7.5deg)
  1841. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1842. ;
  1843. ; Wait before zero cross scan routine
  1844. ;
  1845. ; Waits for the zero cross scan wait time to elapse
  1846. ; Also sets up timer 3 for the zero cross scan timeout time
  1847. ;
  1848. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1849. wait_before_zc_scan:
  1850. Wait_For_Timer3
  1851. mov Startup_Zc_Timeout_Cntd, #2
  1852. setup_zc_scan_timeout:
  1853. setb Flag_T3_PENDING
  1854. orl EIE1, #80h ; Enable timer 3 interrupts
  1855. mov A, Flags_Startup
  1856. jz wait_before_zc_scan_exit
  1857. mov Temp1, Comm_Period4x_L ; Set long timeout when starting
  1858. mov Temp2, Comm_Period4x_H
  1859. clr C
  1860. mov A, Temp2
  1861. rrc A
  1862. mov Temp2, A
  1863. mov A, Temp1
  1864. rrc A
  1865. mov Temp1, A
  1866. IF MCU_48MHZ == 0
  1867. clr C
  1868. mov A, Temp2
  1869. rrc A
  1870. mov Temp2, A
  1871. mov A, Temp1
  1872. rrc A
  1873. mov Temp1, A
  1874. ENDIF
  1875. jnb Flag_STARTUP_PHASE, setup_zc_scan_timeout_startup_done
  1876. mov A, Temp2
  1877. add A, #40h ; Increase timeout somewhat to avoid false wind up
  1878. mov Temp2, A
  1879. setup_zc_scan_timeout_startup_done:
  1880. clr IE_EA
  1881. anl EIE1, #7Fh ; Disable timer 3 interrupts
  1882. mov TMR3CN0, #00h ; Timer 3 disabled and interrupt flag cleared
  1883. clr C
  1884. clr A
  1885. subb A, Temp1 ; Set timeout
  1886. mov TMR3L, A
  1887. clr A
  1888. subb A, Temp2
  1889. mov TMR3H, A
  1890. mov TMR3CN0, #04h ; Timer 3 enabled and interrupt flag cleared
  1891. setb Flag_T3_PENDING
  1892. orl EIE1, #80h ; Enable timer 3 interrupts
  1893. setb IE_EA
  1894. wait_before_zc_scan_exit:
  1895. ret
  1896. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1897. ;
  1898. ; Wait for comparator to go low/high routines
  1899. ;
  1900. ; Waits for the zero cross scan wait time to elapse
  1901. ; Then scans for comparator going low/high
  1902. ;
  1903. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  1904. wait_for_comp_out_low:
  1905. setb Flag_DEMAG_DETECTED ; Set demag detected flag as default
  1906. mov Comparator_Read_Cnt, #0 ; Reset number of comparator reads
  1907. mov Bit_Access, #00h ; Desired comparator output
  1908. jnb Flag_DIR_CHANGE_BRAKE, ($+6)
  1909. mov Bit_Access, #40h
  1910. sjmp wait_for_comp_out_start
  1911. wait_for_comp_out_high:
  1912. setb Flag_DEMAG_DETECTED ; Set demag detected flag as default
  1913. mov Comparator_Read_Cnt, #0 ; Reset number of comparator reads
  1914. mov Bit_Access, #40h ; Desired comparator output
  1915. jnb Flag_DIR_CHANGE_BRAKE, ($+6)
  1916. mov Bit_Access, #00h
  1917. wait_for_comp_out_start:
  1918. ; Set number of comparator readings
  1919. mov Temp1, #1 ; Number of OK readings required
  1920. mov Temp2, #1 ; Max number of readings required
  1921. jb Flag_HIGH_RPM, comp_scale_samples ; Branch if high rpm
  1922. mov A, Flags_Startup ; Clear demag detected flag if start phases
  1923. jz ($+4)
  1924. clr Flag_DEMAG_DETECTED
  1925. ; Too low value (~<15) causes rough running at pwm harmonics.
  1926. ; Too high a value (~>35) causes the RCT4215 630 to run rough on full throttle
  1927. mov Temp2, #20
  1928. mov A, Comm_Period4x_H ; Set number of readings higher for lower speeds
  1929. clr C
  1930. rrc A
  1931. jnz ($+3)
  1932. inc A
  1933. mov Temp1, A
  1934. clr C
  1935. subb A, #20
  1936. jc ($+4)
  1937. mov Temp1, #20
  1938. jnb Flag_STARTUP_PHASE, comp_scale_samples
  1939. mov Temp1, #27 ; Set many samples during startup, approximately one pwm period
  1940. mov Temp2, #27
  1941. comp_scale_samples:
  1942. IF MCU_48MHZ == 1
  1943. clr C
  1944. mov A, Temp1
  1945. rlc A
  1946. mov Temp1, A
  1947. clr C
  1948. mov A, Temp2
  1949. rlc A
  1950. mov Temp2, A
  1951. ENDIF
  1952. comp_check_timeout:
  1953. jb Flag_T3_PENDING, comp_check_timeout_not_timed_out ; Has zero cross scan timeout elapsed?
  1954. mov A, Comparator_Read_Cnt ; Check that comparator has been read
  1955. jz comp_check_timeout_not_timed_out ; If not read - branch
  1956. jnb Flag_STARTUP_PHASE, comp_check_timeout_timeout_extended ; Extend timeout during startup
  1957. djnz Startup_Zc_Timeout_Cntd, comp_check_timeout_extend_timeout
  1958. comp_check_timeout_timeout_extended:
  1959. setb Flag_COMP_TIMED_OUT
  1960. sjmp setup_comm_wait
  1961. comp_check_timeout_extend_timeout:
  1962. call setup_zc_scan_timeout
  1963. comp_check_timeout_not_timed_out:
  1964. inc Comparator_Read_Cnt ; Increment comparator read count
  1965. Read_Comp_Out ; Read comparator output
  1966. anl A, #40h
  1967. cjne A, Bit_Access, comp_read_wrong
  1968. ; Comp read ok
  1969. mov A, Startup_Cnt ; Force a timeout for the first commutation
  1970. jz wait_for_comp_out_start
  1971. jb Flag_DEMAG_DETECTED, wait_for_comp_out_start ; Do not accept correct comparator output if it is demag
  1972. djnz Temp1, comp_check_timeout ; Decrement readings counter - repeat comparator reading if not zero
  1973. clr Flag_COMP_TIMED_OUT
  1974. sjmp setup_comm_wait
  1975. comp_read_wrong:
  1976. jnb Flag_STARTUP_PHASE, comp_read_wrong_not_startup
  1977. inc Temp1 ; Increment number of OK readings required
  1978. clr C
  1979. mov A, Temp1
  1980. subb A, Temp2 ; If above initial requirement - do not increment further
  1981. jc ($+3)
  1982. dec Temp1
  1983. sjmp comp_check_timeout ; Continue to look for good ones
  1984. comp_read_wrong_not_startup:
  1985. jb Flag_DEMAG_DETECTED, comp_read_wrong_extend_timeout
  1986. inc Temp1 ; Increment number of OK readings required
  1987. clr C
  1988. mov A, Temp1
  1989. subb A, Temp2
  1990. jc comp_check_timeout ; If below initial requirement - take another reading
  1991. sjmp wait_for_comp_out_start ; Otherwise - go back and restart
  1992. comp_read_wrong_extend_timeout:
  1993. clr Flag_DEMAG_DETECTED ; Clear demag detected flag
  1994. anl EIE1, #7Fh ; Disable timer 3 interrupts
  1995. mov TMR3CN0, #00h ; Timer 3 disabled and interrupt flag cleared
  1996. jnb Flag_HIGH_RPM, comp_read_wrong_low_rpm ; Branch if not high rpm
  1997. mov TMR3L, #00h ; Set timeout to ~1ms
  1998. IF MCU_48MHZ == 1
  1999. mov TMR3H, #0F0h
  2000. ELSE
  2001. mov TMR3H, #0F8h
  2002. ENDIF
  2003. comp_read_wrong_timeout_set:
  2004. mov TMR3CN0, #04h ; Timer 3 enabled and interrupt flag cleared
  2005. setb Flag_T3_PENDING
  2006. orl EIE1, #80h ; Enable timer 3 interrupts
  2007. ajmp wait_for_comp_out_start ; If comparator output is not correct - go back and restart
  2008. comp_read_wrong_low_rpm:
  2009. mov A, Comm_Period4x_H ; Set timeout to ~4x comm period 4x value
  2010. mov Temp7, #0FFh ; Default to long
  2011. IF MCU_48MHZ == 1
  2012. clr C
  2013. rlc A
  2014. jc comp_read_wrong_load_timeout
  2015. ENDIF
  2016. clr C
  2017. rlc A
  2018. jc comp_read_wrong_load_timeout
  2019. clr C
  2020. rlc A
  2021. jc comp_read_wrong_load_timeout
  2022. mov Temp7, A
  2023. comp_read_wrong_load_timeout:
  2024. clr C
  2025. clr A
  2026. subb A, Temp7
  2027. mov TMR3L, #0
  2028. mov TMR3H, A
  2029. sjmp comp_read_wrong_timeout_set
  2030. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2031. ;
  2032. ; Setup commutation timing routine
  2033. ;
  2034. ; Sets up and starts wait from commutation to zero cross
  2035. ;
  2036. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2037. setup_comm_wait:
  2038. clr IE_EA
  2039. anl EIE1, #7Fh ; Disable timer 3 interrupts
  2040. mov TMR3CN0, #00h ; Timer 3 disabled and interrupt flag cleared
  2041. mov TMR3L, Wt_Comm_Start_L
  2042. mov TMR3H, Wt_Comm_Start_H
  2043. mov TMR3CN0, #04h ; Timer 3 enabled and interrupt flag cleared
  2044. ; Setup next wait time
  2045. mov TMR3RLL, Wt_Adv_Start_L
  2046. mov TMR3RLH, Wt_Adv_Start_H
  2047. setb Flag_T3_PENDING
  2048. orl EIE1, #80h ; Enable timer 3 interrupts
  2049. setb IE_EA ; Enable interrupts again
  2050. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2051. ;
  2052. ; Evaluate comparator integrity
  2053. ;
  2054. ; Checks comparator signal behaviour versus expected behaviour
  2055. ;
  2056. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2057. evaluate_comparator_integrity:
  2058. mov A, Flags_Startup
  2059. jz eval_comp_check_timeout
  2060. jb Flag_INITIAL_RUN_PHASE, ($+5) ; Do not increment beyond startup phase
  2061. inc Startup_Cnt ; Increment counter
  2062. sjmp eval_comp_exit
  2063. eval_comp_check_timeout:
  2064. jnb Flag_COMP_TIMED_OUT, eval_comp_exit ; Has timeout elapsed?
  2065. jb Flag_DIR_CHANGE_BRAKE, eval_comp_exit ; Do not exit run mode if it is braking
  2066. jb Flag_DEMAG_DETECTED, eval_comp_exit ; Do not exit run mode if it is a demag situation
  2067. dec SP ; Routine exit without "ret" command
  2068. dec SP
  2069. ljmp run_to_wait_for_power_on_fail ; Yes - exit run mode
  2070. eval_comp_exit:
  2071. ret
  2072. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2073. ;
  2074. ; Wait for commutation routine
  2075. ;
  2076. ; Waits from zero cross to commutation
  2077. ;
  2078. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2079. wait_for_comm:
  2080. ; Update demag metric
  2081. mov A, Demag_Detected_Metric ; Sliding average of 8, 256 when demag and 0 when not. Limited to minimum 120
  2082. mov B, #7
  2083. mul AB ; Multiply by 7
  2084. jnb Flag_DEMAG_DETECTED, ($+4) ; Add new value for current demag status
  2085. inc B
  2086. mov C, B.0 ; Divide by 8
  2087. rrc A
  2088. mov C, B.1
  2089. rrc A
  2090. mov C, B.2
  2091. rrc A
  2092. mov Demag_Detected_Metric, A
  2093. clr C
  2094. subb A, #120 ; Limit to minimum 120
  2095. jnc ($+5)
  2096. mov Demag_Detected_Metric, #120
  2097. clr C
  2098. mov A, Demag_Detected_Metric ; Check demag metric
  2099. subb A, Demag_Pwr_Off_Thresh
  2100. jc wait_for_comm_wait ; Cut power if many consecutive demags. This will help retain sync during hard accelerations
  2101. All_pwmFETs_off
  2102. Set_Pwms_Off
  2103. wait_for_comm_wait:
  2104. Wait_For_Timer3
  2105. ; Setup next wait time
  2106. mov TMR3RLL, Wt_Zc_Scan_Start_L
  2107. mov TMR3RLH, Wt_Zc_Scan_Start_H
  2108. setb Flag_T3_PENDING
  2109. orl EIE1, #80h ; Enable timer 3 interrupts
  2110. ret
  2111. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2112. ;
  2113. ; Commutation routines
  2114. ;
  2115. ; Performs commutation switching
  2116. ;
  2117. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2118. ; Comm phase 1 to comm phase 2
  2119. comm1comm2:
  2120. Set_RPM_Out
  2121. jb Flag_PGM_DIR_REV, comm12_rev
  2122. clr IE_EA ; Disable all interrupts
  2123. BcomFET_off ; Turn off comfet
  2124. AcomFET_on ; Turn on comfet
  2125. Set_Pwm_C ; To reapply power after a demag cut
  2126. setb IE_EA
  2127. Set_Comp_Phase_B ; Set comparator phase
  2128. ret
  2129. comm12_rev:
  2130. clr IE_EA ; Disable all interrupts
  2131. BcomFET_off ; Turn off comfet
  2132. CcomFET_on ; Turn on comfet (reverse)
  2133. Set_Pwm_A ; To reapply power after a demag cut
  2134. setb IE_EA
  2135. Set_Comp_Phase_B ; Set comparator phase
  2136. ret
  2137. ; Comm phase 2 to comm phase 3
  2138. comm2comm3:
  2139. Clear_RPM_Out
  2140. jb Flag_PGM_DIR_REV, comm23_rev
  2141. clr IE_EA ; Disable all interrupts
  2142. CpwmFET_off ; Turn off pwmfet
  2143. Set_Pwm_B ; To reapply power after a demag cut
  2144. AcomFET_on
  2145. setb IE_EA
  2146. Set_Comp_Phase_C ; Set comparator phase
  2147. ret
  2148. comm23_rev:
  2149. clr IE_EA ; Disable all interrupts
  2150. ApwmFET_off ; Turn off pwmfet (reverse)
  2151. Set_Pwm_B ; To reapply power after a demag cut
  2152. CcomFET_on
  2153. setb IE_EA
  2154. Set_Comp_Phase_A ; Set comparator phase (reverse)
  2155. ret
  2156. ; Comm phase 3 to comm phase 4
  2157. comm3comm4:
  2158. Set_RPM_Out
  2159. jb Flag_PGM_DIR_REV, comm34_rev
  2160. clr IE_EA ; Disable all interrupts
  2161. AcomFET_off ; Turn off comfet
  2162. CcomFET_on ; Turn on comfet
  2163. Set_Pwm_B ; To reapply power after a demag cut
  2164. setb IE_EA
  2165. Set_Comp_Phase_A ; Set comparator phase
  2166. ret
  2167. comm34_rev:
  2168. clr IE_EA ; Disable all interrupts
  2169. CcomFET_off ; Turn off comfet (reverse)
  2170. AcomFET_on ; Turn on comfet (reverse)
  2171. Set_Pwm_B ; To reapply power after a demag cut
  2172. setb IE_EA
  2173. Set_Comp_Phase_C ; Set comparator phase (reverse)
  2174. ret
  2175. ; Comm phase 4 to comm phase 5
  2176. comm4comm5:
  2177. Clear_RPM_Out
  2178. jb Flag_PGM_DIR_REV, comm45_rev
  2179. clr IE_EA ; Disable all interrupts
  2180. BpwmFET_off ; Turn off pwmfet
  2181. Set_Pwm_A ; To reapply power after a demag cut
  2182. CcomFET_on
  2183. setb IE_EA
  2184. Set_Comp_Phase_B ; Set comparator phase
  2185. ret
  2186. comm45_rev:
  2187. clr IE_EA ; Disable all interrupts
  2188. BpwmFET_off ; Turn off pwmfet
  2189. Set_Pwm_C
  2190. AcomFET_on ; To reapply power after a demag cut
  2191. setb IE_EA
  2192. Set_Comp_Phase_B ; Set comparator phase
  2193. ret
  2194. ; Comm phase 5 to comm phase 6
  2195. comm5comm6:
  2196. Set_RPM_Out
  2197. jb Flag_PGM_DIR_REV, comm56_rev
  2198. clr IE_EA ; Disable all interrupts
  2199. CcomFET_off ; Turn off comfet
  2200. BcomFET_on ; Turn on comfet
  2201. Set_Pwm_A ; To reapply power after a demag cut
  2202. setb IE_EA
  2203. Set_Comp_Phase_C ; Set comparator phase
  2204. ret
  2205. comm56_rev:
  2206. clr IE_EA ; Disable all interrupts
  2207. AcomFET_off ; Turn off comfet (reverse)
  2208. BcomFET_on ; Turn on comfet
  2209. Set_Pwm_C ; To reapply power after a demag cut
  2210. setb IE_EA
  2211. Set_Comp_Phase_A ; Set comparator phase (reverse)
  2212. ret
  2213. ; Comm phase 6 to comm phase 1
  2214. comm6comm1:
  2215. Clear_RPM_Out
  2216. jb Flag_PGM_DIR_REV, comm61_rev
  2217. clr IE_EA ; Disable all interrupts
  2218. ApwmFET_off ; Turn off pwmfet
  2219. Set_Pwm_C
  2220. BcomFET_on ; To reapply power after a demag cut
  2221. setb IE_EA
  2222. Set_Comp_Phase_A ; Set comparator phase
  2223. ret
  2224. comm61_rev:
  2225. clr IE_EA ; Disable all interrupts
  2226. CpwmFET_off ; Turn off pwmfet (reverse)
  2227. Set_Pwm_A
  2228. BcomFET_on ; To reapply power after a demag cut
  2229. setb IE_EA
  2230. Set_Comp_Phase_C ; Set comparator phase (reverse)
  2231. ret
  2232. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2233. ;
  2234. ; Beeper routines (4 different entry points)
  2235. ;
  2236. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2237. beep_f1: ; Entry point 1, load beeper frequency 1 settings
  2238. mov Temp3, #20 ; Off wait loop length
  2239. mov Temp4, #120 ; Number of beep pulses
  2240. sjmp beep
  2241. beep_f2: ; Entry point 2, load beeper frequency 2 settings
  2242. mov Temp3, #16
  2243. mov Temp4, #140
  2244. sjmp beep
  2245. beep_f3: ; Entry point 3, load beeper frequency 3 settings
  2246. mov Temp3, #13
  2247. mov Temp4, #180
  2248. sjmp beep
  2249. beep_f4: ; Entry point 4, load beeper frequency 4 settings
  2250. mov Temp3, #11
  2251. mov Temp4, #200
  2252. sjmp beep
  2253. beep: ; Beep loop start
  2254. mov A, Beep_Strength
  2255. djnz ACC, beep_start
  2256. ret
  2257. beep_start:
  2258. mov Temp2, #2
  2259. beep_onoff:
  2260. clr A
  2261. BcomFET_off ; BcomFET off
  2262. djnz ACC, $ ; Allow some time after comfet is turned off
  2263. BpwmFET_on ; BpwmFET on (in order to charge the driver of the BcomFET)
  2264. djnz ACC, $ ; Let the pwmfet be turned on a while
  2265. BpwmFET_off ; BpwmFET off again
  2266. djnz ACC, $ ; Allow some time after pwmfet is turned off
  2267. BcomFET_on ; BcomFET on
  2268. djnz ACC, $ ; Allow some time after comfet is turned on
  2269. ; Turn on pwmfet
  2270. mov A, Temp2
  2271. jb ACC.0, beep_apwmfet_on
  2272. ApwmFET_on ; ApwmFET on
  2273. beep_apwmfet_on:
  2274. jnb ACC.0, beep_cpwmfet_on
  2275. CpwmFET_on ; CpwmFET on
  2276. beep_cpwmfet_on:
  2277. mov A, Beep_Strength
  2278. djnz ACC, $
  2279. ; Turn off pwmfet
  2280. mov A, Temp2
  2281. jb ACC.0, beep_apwmfet_off
  2282. ApwmFET_off ; ApwmFET off
  2283. beep_apwmfet_off:
  2284. jnb ACC.0, beep_cpwmfet_off
  2285. CpwmFET_off ; CpwmFET off
  2286. beep_cpwmfet_off:
  2287. mov A, #150 ; 25us off
  2288. djnz ACC, $
  2289. djnz Temp2, beep_onoff
  2290. ; Copy variable
  2291. mov A, Temp3
  2292. mov Temp1, A
  2293. beep_off: ; Fets off loop
  2294. djnz ACC, $
  2295. djnz Temp1, beep_off
  2296. djnz Temp4, beep
  2297. BcomFET_off ; BcomFET off
  2298. ret
  2299. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2300. ;
  2301. ; Switch power off routine
  2302. ;
  2303. ; Switches all fets off
  2304. ;
  2305. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2306. switch_power_off:
  2307. All_pwmFETs_Off ; Turn off all pwm fets
  2308. All_comFETs_Off ; Turn off all commutation fets
  2309. Set_Pwms_Off
  2310. ret
  2311. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2312. ;
  2313. ; Set default parameters
  2314. ;
  2315. ; Sets default programming parameters
  2316. ;
  2317. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2318. set_default_parameters:
  2319. mov Temp1, #_Pgm_Gov_P_Gain
  2320. Push_Mem Temp1, #0FFh ; _Pgm_Gov_P_Gain
  2321. Push_Mem Temp1, #0FFh ; _Pgm_Gov_I_Gain
  2322. Push_Mem Temp1, #0FFh ; _Pgm_Gov_Mode
  2323. Push_Mem Temp1, #0FFh ; _Pgm_Low_Voltage_Lim
  2324. Push_Mem Temp1, #0FFh ; _Pgm_Motor_Gain
  2325. Push_Mem Temp1, #0FFh ; _Pgm_Motor_Idle
  2326. Push_Mem Temp1, #DEFAULT_PGM_STARTUP_PWR ; Pgm_Startup_Pwr
  2327. Push_Mem Temp1, #0FFh ; _Pgm_Pwm_Freq
  2328. Push_Mem Temp1, #DEFAULT_PGM_DIRECTION ; Pgm_Direction
  2329. Push_Mem Temp1, #0FFh ; _Pgm_Input_Pol
  2330. inc Temp1 ; Skip Initialized_L_Dummy
  2331. inc Temp1 ; Skip Initialized_H_Dummy
  2332. Push_Mem Temp1, #0FFh ; _Pgm_Enable_TX_Program
  2333. Push_Mem Temp1, #0FFh ; _Pgm_Main_Rearm_Start
  2334. Push_Mem Temp1, #0FFh ; _Pgm_Gov_Setup_Target
  2335. Push_Mem Temp1, #0FFh ; _Pgm_Startup_Rpm
  2336. Push_Mem Temp1, #0FFh ; _Pgm_Startup_Accel
  2337. Push_Mem Temp1, #0FFh ; _Pgm_Volt_Comp
  2338. Push_Mem Temp1, #DEFAULT_PGM_COMM_TIMING ; Pgm_Comm_Timing
  2339. Push_Mem Temp1, #0FFh ; _Pgm_Damping_Force
  2340. Push_Mem Temp1, #0FFh ; _Pgm_Gov_Range
  2341. Push_Mem Temp1, #0FFh ; _Pgm_Startup_Method
  2342. Push_Mem Temp1, #0FFh ; _Pgm_Min_Throttle
  2343. Push_Mem Temp1, #0FFh ; _Pgm_Max_Throttle
  2344. Push_Mem Temp1, #DEFAULT_PGM_BEEP_STRENGTH ; Pgm_Beep_Strength
  2345. Push_Mem Temp1, #DEFAULT_PGM_BEACON_STRENGTH ; Pgm_Beacon_Strength
  2346. Push_Mem Temp1, #DEFAULT_PGM_BEACON_DELAY ; Pgm_Beacon_Delay
  2347. Push_Mem Temp1, #0FFh ; _Pgm_Throttle_Rate
  2348. Push_Mem Temp1, #DEFAULT_PGM_DEMAG_COMP ; Pgm_Demag_Comp
  2349. Push_Mem Temp1, #0FFh ; _Pgm_BEC_Voltage_High
  2350. Push_Mem Temp1, #0FFh ; _Pgm_Center_Throttle
  2351. Push_Mem Temp1, #0FFh ; _Pgm_Main_Spoolup_Time
  2352. Push_Mem Temp1, #DEFAULT_PGM_ENABLE_TEMP_PROT ; Pgm_Enable_Temp_Prot
  2353. Push_Mem Temp1, #DEFAULT_PGM_ENABLE_POWER_PROT ; Pgm_Enable_Power_Prot
  2354. Push_Mem Temp1, #0FFh ; _Pgm_Enable_Pwm_Input
  2355. Push_Mem Temp1, #0FFh ; _Pgm_Pwm_Dither
  2356. Push_Mem Temp1, #DEFAULT_PGM_BRAKE_ON_STOP ; Pgm_Brake_On_Stop
  2357. Push_Mem Temp1, #DEFAULT_PGM_LED_CONTROL ; Pgm_LED_Control
  2358. ret
  2359. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2360. ;
  2361. ; Decode settings
  2362. ;
  2363. ; Decodes various settings
  2364. ;
  2365. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2366. decode_settings:
  2367. ; Load programmed direction
  2368. mov Temp1, #Pgm_Direction
  2369. mov A, @Temp1
  2370. clr C
  2371. subb A, #3
  2372. setb Flag_PGM_BIDIR
  2373. jnc ($+4)
  2374. clr Flag_PGM_BIDIR
  2375. clr Flag_PGM_DIR_REV
  2376. mov A, @Temp1
  2377. jnb ACC.1, ($+5)
  2378. setb Flag_PGM_DIR_REV
  2379. mov C, Flag_PGM_DIR_REV
  2380. mov Flag_PGM_BIDIR_REV, C
  2381. ; Decode startup power
  2382. mov Temp1, #Pgm_Startup_Pwr
  2383. mov A, @Temp1
  2384. dec A
  2385. mov DPTR, #STARTUP_POWER_TABLE
  2386. movc A, @A+DPTR
  2387. mov Temp1, #Pgm_Startup_Pwr_Decoded
  2388. mov @Temp1, A
  2389. ; Decode low rpm power slope
  2390. mov Temp1, #Pgm_Startup_Pwr
  2391. mov A, @Temp1
  2392. mov Low_Rpm_Pwr_Slope, A
  2393. clr C
  2394. subb A, #2
  2395. jnc ($+5)
  2396. mov Low_Rpm_Pwr_Slope, #2
  2397. ; Decode demag compensation
  2398. mov Temp1, #Pgm_Demag_Comp
  2399. mov A, @Temp1
  2400. mov Demag_Pwr_Off_Thresh, #255 ; Set default
  2401. cjne A, #2, decode_demag_high
  2402. mov Demag_Pwr_Off_Thresh, #160 ; Settings for demag comp low
  2403. decode_demag_high:
  2404. cjne A, #3, decode_demag_done
  2405. mov Demag_Pwr_Off_Thresh, #130 ; Settings for demag comp high
  2406. decode_demag_done:
  2407. ; Decode temperature protection limit
  2408. mov Temp1, #Pgm_Enable_Temp_Prot
  2409. mov A, @Temp1
  2410. mov Temp1, A
  2411. jz decode_temp_done
  2412. mov A, #(TEMP_LIMIT-TEMP_LIMIT_STEP)
  2413. decode_temp_step:
  2414. add A, #TEMP_LIMIT_STEP
  2415. djnz Temp1, decode_temp_step
  2416. decode_temp_done:
  2417. mov Temp_Prot_Limit, A
  2418. ; Dithering
  2419. IF PWM_BITS_H == 1
  2420. mov Temp1, #Dithering_Patterns
  2421. Push_Mem Temp1, #00h
  2422. Push_Mem Temp1, #55h
  2423. ELSEIF PWM_BITS_H == 0
  2424. mov Temp1, #Dithering_Patterns
  2425. Push_Mem Temp1, #00h
  2426. Push_Mem Temp1, #11h
  2427. Push_Mem Temp1, #55h
  2428. Push_Mem Temp1, #77h
  2429. ENDIF
  2430. ret
  2431. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2432. ;
  2433. ; Detect DShot RCP level
  2434. ;
  2435. ; Determine if RCP signal level is normal or inverted DShot
  2436. ;
  2437. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2438. detect_rcp_level:
  2439. mov A, #100 ; Must repeat the same level 100 times in a row
  2440. mov C, RTX_PORT.RTX_PIN
  2441. detect_rcp_level_read:
  2442. jc ($+5)
  2443. jb RTX_PORT.RTX_PIN, detect_rcp_level ; Level changed from low to high - start over
  2444. jnc ($+5)
  2445. jnb RTX_PORT.RTX_PIN, detect_rcp_level ; Level changed from high to low - start over
  2446. djnz ACC, detect_rcp_level_read
  2447. mov Flag_RCP_DSHOT_INVERTED, C
  2448. ret
  2449. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2450. ;
  2451. ; LED control
  2452. ;
  2453. ; Controls LEDs
  2454. ;
  2455. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2456. led_control:
  2457. mov Temp1, #Pgm_LED_Control
  2458. mov A, @Temp1
  2459. mov Temp2, A
  2460. anl A, #03h
  2461. Set_LED_0
  2462. jnz led_0_done
  2463. Clear_LED_0
  2464. led_0_done:
  2465. mov A, Temp2
  2466. anl A, #0Ch
  2467. Set_LED_1
  2468. jnz led_1_done
  2469. Clear_LED_1
  2470. led_1_done:
  2471. mov A, Temp2
  2472. anl A, #030h
  2473. Set_LED_2
  2474. jnz led_2_done
  2475. Clear_LED_2
  2476. led_2_done:
  2477. mov A, Temp2
  2478. anl A, #0C0h
  2479. Set_LED_3
  2480. jnz led_3_done
  2481. Clear_LED_3
  2482. led_3_done:
  2483. ret
  2484. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2485. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2486. ;
  2487. ; Main program start
  2488. ;
  2489. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2490. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2491. pgm_start:
  2492. ; Initialize flash keys to invalid values
  2493. mov Flash_Key_1, #0
  2494. mov Flash_Key_2, #0
  2495. ; Disable the WDT
  2496. mov WDTCN, #0DEh ; Disable watchdog
  2497. mov WDTCN, #0ADh
  2498. ; Initialize stack
  2499. mov SP, #Stack ; 16 bytes of indirect RAM
  2500. ; Initialize VDD monitor
  2501. orl VDM0CN, #080h ; Enable the VDD monitor
  2502. mov RSTSRC, #06h ; Set missing clock and VDD monitor as a reset source if not 1S capable
  2503. ; Set clock frequency
  2504. mov CLKSEL, #00h ; Set clock divider to 1
  2505. ; Switch power off
  2506. call switch_power_off
  2507. ; Ports initialization
  2508. mov P0, #P0_INIT
  2509. mov P0MDIN, #P0_DIGITAL
  2510. mov P0MDOUT, #P0_PUSHPULL
  2511. mov P0, #P0_INIT
  2512. mov P0SKIP, #P0_SKIP
  2513. mov P1, #P1_INIT
  2514. mov P1MDIN, #P1_DIGITAL
  2515. mov P1MDOUT, #P1_PUSHPULL
  2516. mov P1, #P1_INIT
  2517. mov P1SKIP, #P1_SKIP
  2518. mov P2MDOUT, #P2_PUSHPULL
  2519. ; Initialize the XBAR and related functionality
  2520. Initialize_Xbar
  2521. ; Switch power off again, after initializing ports
  2522. call switch_power_off
  2523. ; Clear RAM
  2524. clr A ; Clear accumulator
  2525. mov Temp1, A ; Clear Temp1
  2526. clear_ram:
  2527. mov @Temp1, A ; Clear RAM
  2528. djnz Temp1, clear_ram ; Is A not zero? - jump
  2529. ; Set default programmed parameters
  2530. call set_default_parameters
  2531. ; Read all programmed parameters
  2532. call read_all_eeprom_parameters
  2533. ; Set beep strength
  2534. mov Temp1, #Pgm_Beep_Strength
  2535. mov Beep_Strength, @Temp1
  2536. ; Initializing beep
  2537. clr IE_EA ; Disable interrupts explicitly
  2538. call wait200ms
  2539. call beep_f1
  2540. call wait30ms
  2541. call beep_f2
  2542. call wait30ms
  2543. call beep_f3
  2544. call wait30ms
  2545. call led_control
  2546. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2547. ;
  2548. ; No signal entry point
  2549. ;
  2550. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2551. init_no_signal:
  2552. ; Disable interrupts explicitly
  2553. clr IE_EA
  2554. ; Initialize flash keys to invalid values
  2555. mov Flash_Key_1, #0
  2556. mov Flash_Key_2, #0
  2557. ; Check if input signal is high for more than 15ms
  2558. mov Temp1, #250
  2559. input_high_check_1:
  2560. mov Temp2, #250
  2561. input_high_check_2:
  2562. jnb RTX_PORT.RTX_PIN, bootloader_done ; Look for low
  2563. djnz Temp2, input_high_check_2
  2564. djnz Temp1, input_high_check_1
  2565. ljmp 1C00h ; Jump to bootloader
  2566. bootloader_done:
  2567. ; Decode settings
  2568. call decode_settings
  2569. ; Set beep strength
  2570. mov Temp1, #Pgm_Beep_Strength
  2571. mov Beep_Strength, @Temp1
  2572. ; Switch power off
  2573. call switch_power_off
  2574. ; Set clock frequency
  2575. IF MCU_48MHZ == 1
  2576. Set_MCU_Clk_24MHz
  2577. ENDIF
  2578. ; Setup timers for DShot
  2579. mov TCON, #51h ; Timer 0/1 run and INT0 edge triggered
  2580. mov CKCON0, #01h ; Timer 0/1 clock is system clock divided by 4 (for DShot150)
  2581. mov TMOD, #0AAh ; Timer 0/1 set to 8bits auto reload and gated by INT0/1
  2582. mov TH0, #0 ; Auto reload value zero
  2583. mov TH1, #0
  2584. mov TMR2CN0, #04h ; Timer 2 enabled
  2585. mov TMR3CN0, #04h ; Timer 3 enabled
  2586. Initialize_PCA ; Initialize PCA
  2587. Set_Pwm_Polarity ; Set pwm polarity
  2588. Enable_Power_Pwm_Module ; Enable power pwm module
  2589. Enable_Damp_Pwm_Module ; Enable damping pwm module
  2590. Initialize_Comparator ; Initialize comparator
  2591. Initialize_Adc ; Initialize ADC operation
  2592. call wait1ms
  2593. mov Stall_Cnt, #0 ; Reset stall count
  2594. mov Dshot_Cmd, #0 ; Clear DShot command
  2595. mov Dshot_Cmd_Cnt, #0 ; Clear DShot command count
  2596. ; Setup RCP for DShot
  2597. call detect_rcp_level ; Detect normal or inverted DShot
  2598. ; Route RCP according to detected DShot signal (normal or inverted)
  2599. mov IT01CF, #(80h + (RTX_PIN SHL 4) + RTX_PIN) ; Route RCP input to INT0/1, with INT1 inverted
  2600. jnb Flag_RCP_DSHOT_INVERTED, ($+6)
  2601. mov IT01CF, #(08h + (RTX_PIN SHL 4) + RTX_PIN) ; Route RCP input to INT0/1, with INT0 inverted
  2602. ; Setup interrupts for DShot
  2603. mov IE, #2Dh ; Enable timer 1/2 interrupts and INT0/1 interrupts
  2604. mov EIE1, #90h ; Enable timer 3 and PCA0 interrupts
  2605. mov IP, #03h ; High priority to timer 0 and INT0 interrupts
  2606. setb IE_EA ; Enable all interrupts
  2607. call wait200ms
  2608. ; Setup variables for DShot150
  2609. ; TODO: dshot150 not supported for now
  2610. ; IF MCU_48MHZ == 1
  2611. ; mov DShot_Timer_Preset, #128 ; Load DShot sync timer preset (for DShot150)
  2612. ; ELSE
  2613. ; mov DShot_Timer_Preset, #192
  2614. ; ENDIF
  2615. ; ; TODO: we cannot currently support DShot150 on 48MHz (because of DShot_Frame_Length_Thr)
  2616. ; IF MCU_48MHZ == 0
  2617. ; mov DShot_Pwm_Thr, #10 ; Load DShot qualification pwm threshold (for DShot150)
  2618. ; mov DShot_Frame_Length_Thr, #160 ; Load DShot frame length criteria
  2619. ; Set_DShot_Tlm_Bitrate 187500 ; = 5/4 * 150000
  2620. ; ; Test whether signal is DShot150
  2621. ; mov Rcp_Outside_Range_Cnt, #10 ; Set out of range counter
  2622. ; call wait100ms ; Wait for new RC pulse
  2623. ; mov DShot_Pwm_Thr, #8 ; Load DShot regular pwm threshold
  2624. ; clr C
  2625. ; mov A, Rcp_Outside_Range_Cnt ; Check if pulses were accepted
  2626. ; subb A, #10
  2627. ; mov Dshot_Cmd, #0
  2628. ; mov Dshot_Cmd_Cnt, #0
  2629. ; jc arming_begin
  2630. ; ENDIF
  2631. mov CKCON0, #0Ch ; Timer 0/1 clock is system clock (for DShot300/600)
  2632. ; Setup variables for DShot300
  2633. IF MCU_48MHZ == 1
  2634. mov DShot_Timer_Preset, #0 ; Load DShot sync timer preset (for DShot300)
  2635. ELSE
  2636. mov DShot_Timer_Preset, #128
  2637. ENDIF
  2638. mov DShot_Pwm_Thr, #20 ; Load DShot qualification pwm threshold (for DShot300)
  2639. mov DShot_Frame_Length_Thr, #80 ; Load DShot frame length criteria
  2640. Set_DShot_Tlm_Bitrate 375000 ; = 5/4 * 300000
  2641. ; Test whether signal is DShot300
  2642. mov Rcp_Outside_Range_Cnt, #10 ; Set out of range counter
  2643. call wait100ms ; Wait for new RC pulse
  2644. mov DShot_Pwm_Thr, #16 ; Load DShot regular pwm threshold
  2645. clr C
  2646. mov A, Rcp_Outside_Range_Cnt ; Check if pulses were accepted
  2647. subb A, #10
  2648. mov Dshot_Cmd, #0
  2649. mov Dshot_Cmd_Cnt, #0
  2650. jc arming_begin
  2651. ; Setup variables for DShot600
  2652. IF MCU_48MHZ == 1
  2653. mov DShot_Timer_Preset, #128 ; Load DShot sync timer preset (for DShot600)
  2654. ELSE
  2655. mov DShot_Timer_Preset, #192
  2656. ENDIF
  2657. mov DShot_Pwm_Thr, #10 ; Load DShot qualification pwm threshold (for DShot600)
  2658. mov DShot_Frame_Length_Thr, #40 ; Load DShot frame length criteria
  2659. Set_DShot_Tlm_Bitrate 750000 ; = 5/4 * 600000
  2660. ; Test whether signal is DShot600
  2661. mov Rcp_Outside_Range_Cnt, #10 ; Set out of range counter
  2662. call wait100ms ; Wait for new RC pulse
  2663. mov DShot_Pwm_Thr, #8 ; Load DShot regular pwm threshold
  2664. clr C
  2665. mov A, Rcp_Outside_Range_Cnt ; Check if pulses were accepted
  2666. subb A, #10
  2667. mov Dshot_Cmd, #0
  2668. mov Dshot_Cmd_Cnt, #0
  2669. jc arming_begin
  2670. ajmp init_no_signal
  2671. arming_begin:
  2672. ; Beep arm sequence start signal
  2673. clr IE_EA ; Disable all interrupts
  2674. call beep_f1 ; Signal that RC pulse is ready
  2675. call beep_f1
  2676. call beep_f1
  2677. setb IE_EA ; Enable all interrupts
  2678. call wait200ms
  2679. ; Arming sequence start
  2680. arming_wait:
  2681. call wait100ms ; Wait for new throttle value
  2682. jnb Flag_RCP_STOP, arming_wait ; Start over if not below stop
  2683. ; Beep arm sequence end signal
  2684. clr IE_EA ; Disable all interrupts
  2685. call beep_f4 ; Signal that RC pulse is ready
  2686. call beep_f4
  2687. call beep_f4
  2688. setb IE_EA ; Enable all interrupts
  2689. call wait200ms
  2690. ; Armed and waiting for power on
  2691. wait_for_power_on:
  2692. clr A
  2693. mov Comm_Period4x_L, A ; Reset commutation period for telemetry
  2694. mov Comm_Period4x_H, A
  2695. mov Power_On_Wait_Cnt_L, A ; Clear wait counter
  2696. mov Power_On_Wait_Cnt_H, A
  2697. wait_for_power_on_loop:
  2698. inc Power_On_Wait_Cnt_L ; Increment low wait counter
  2699. mov A, Power_On_Wait_Cnt_L
  2700. cpl A
  2701. jnz wait_for_power_on_no_beep ; Counter wrapping (about 3 sec)
  2702. inc Power_On_Wait_Cnt_H ; Increment high wait counter
  2703. mov Temp1, #Pgm_Beacon_Delay
  2704. mov A, @Temp1
  2705. mov Temp1, #25 ; Approximately 1 min
  2706. dec A
  2707. jz beep_delay_set
  2708. mov Temp1, #50 ; Approximately 2 min
  2709. dec A
  2710. jz beep_delay_set
  2711. mov Temp1, #125 ; Approximately 5 min
  2712. dec A
  2713. jz beep_delay_set
  2714. mov Temp1, #250 ; Approximately 10 min
  2715. dec A
  2716. jz beep_delay_set
  2717. mov Power_On_Wait_Cnt_H, #0 ; Reset counter for infinite delay
  2718. beep_delay_set:
  2719. clr C
  2720. mov A, Power_On_Wait_Cnt_H
  2721. subb A, Temp1 ; Check against chosen delay
  2722. jc wait_for_power_on_no_beep ; Has delay elapsed?
  2723. call switch_power_off ; Switch power off in case braking is set
  2724. call wait1ms
  2725. dec Power_On_Wait_Cnt_H ; Decrement high wait counter
  2726. mov Power_On_Wait_Cnt_L, #0 ; Set low wait counter
  2727. mov Temp1, #Pgm_Beacon_Strength
  2728. mov Beep_Strength, @Temp1
  2729. clr IE_EA ; Disable all interrupts
  2730. call beep_f4 ; Signal that there is no signal
  2731. setb IE_EA ; Enable all interrupts
  2732. mov Temp1, #Pgm_Beep_Strength
  2733. mov Beep_Strength, @Temp1
  2734. call wait100ms ; Wait for new RC pulse to be measured
  2735. wait_for_power_on_no_beep:
  2736. jb Flag_PACKET_PENDING, wait_for_power_telemetry_done
  2737. setb Flag_T3_PENDING ; Set flag temporarily to avoid early return
  2738. call dshot_tlm_create_packet
  2739. clr Flag_T3_PENDING
  2740. wait_for_power_telemetry_done:
  2741. call wait10ms
  2742. mov A, Rcp_Timeout_Cntd ; Load RC pulse timeout counter value
  2743. jnz wait_for_power_on_not_missing ; If it is not zero - proceed
  2744. ajmp init_no_signal ; If pulses missing - go back to detect input signal
  2745. wait_for_power_on_not_missing:
  2746. jnb Flag_RCP_STOP, wait_for_power_on_nonzero ; Higher than stop, Yes - proceed
  2747. mov A, Dshot_Cmd
  2748. jz wait_for_power_on_loop ; Check DShot command if not zero, otherwise wait for power
  2749. call check_dshot_cmd
  2750. sjmp wait_for_power_on_not_missing ; Check dshot command again, in case command needs to be received multiple times
  2751. wait_for_power_on_nonzero:
  2752. call wait100ms ; Wait to see if start pulse was only a glitch
  2753. mov A, Rcp_Timeout_Cntd ; Load RC pulse timeout counter value
  2754. jnz ($+5) ; If it is not zero - proceed
  2755. ajmp init_no_signal ; If it is zero (pulses missing) - go back to detect input signal
  2756. mov Dshot_Cmd, #0
  2757. mov Dshot_Cmd_Cnt, #0
  2758. jmp init_start
  2759. check_dshot_cmd:
  2760. mov Temp1, Dshot_Cmd
  2761. cjne Temp1, #1, dshot_beep_2
  2762. clr IE_EA
  2763. call switch_power_off ; Switch power off in case braking is set
  2764. mov Temp1, #Pgm_Beacon_Strength
  2765. mov Beep_Strength, @Temp1
  2766. call beep_f1
  2767. mov Temp1, #Pgm_Beep_Strength
  2768. mov Beep_Strength, @Temp1
  2769. setb IE_EA
  2770. call wait100ms
  2771. ajmp clear_dshot_cmd
  2772. dshot_beep_2:
  2773. cjne Temp1, #2, dshot_beep_3
  2774. clr IE_EA
  2775. call switch_power_off ; Switch power off in case braking is set
  2776. mov Temp1, #Pgm_Beacon_Strength
  2777. mov Beep_Strength, @Temp1
  2778. call beep_f2
  2779. mov Temp1, #Pgm_Beep_Strength
  2780. mov Beep_Strength, @Temp1
  2781. setb IE_EA
  2782. call wait100ms
  2783. ajmp clear_dshot_cmd
  2784. dshot_beep_3:
  2785. cjne Temp1, #3, dshot_beep_4
  2786. clr IE_EA
  2787. call switch_power_off ; Switch power off in case braking is set
  2788. mov Temp1, #Pgm_Beacon_Strength
  2789. mov Beep_Strength, @Temp1
  2790. call beep_f3
  2791. mov Temp1, #Pgm_Beep_Strength
  2792. mov Beep_Strength, @Temp1
  2793. setb IE_EA
  2794. call wait100ms
  2795. ajmp clear_dshot_cmd
  2796. dshot_beep_4:
  2797. cjne Temp1, #4, dshot_beep_5
  2798. clr IE_EA
  2799. call switch_power_off ; Switch power off in case braking is set
  2800. mov Temp1, #Pgm_Beacon_Strength
  2801. mov Beep_Strength, @Temp1
  2802. call beep_f4
  2803. mov Temp1, #Pgm_Beep_Strength
  2804. mov Beep_Strength, @Temp1
  2805. setb IE_EA
  2806. call wait100ms
  2807. sjmp clear_dshot_cmd
  2808. dshot_beep_5:
  2809. cjne Temp1, #5, dshot_direction_1
  2810. clr IE_EA
  2811. call switch_power_off ; Switch power off in case braking is set
  2812. mov Temp1, #Pgm_Beacon_Strength
  2813. mov Beep_Strength, @Temp1
  2814. call beep_f4
  2815. mov Temp1, #Pgm_Beep_Strength
  2816. mov Beep_Strength, @Temp1
  2817. setb IE_EA
  2818. call wait100ms
  2819. sjmp clear_dshot_cmd
  2820. dshot_direction_1:
  2821. ; Change programmed motor direction to normal
  2822. cjne Temp1, #7, dshot_direction_2
  2823. clr C
  2824. mov A, Dshot_Cmd_Cnt
  2825. subb A, #6 ; Needs to receive it 6 times in a row
  2826. jc dont_clear_dshot_cmd
  2827. mov A, #1
  2828. jnb Flag_PGM_BIDIR, ($+5)
  2829. mov A, #3
  2830. mov Temp1, #Pgm_Direction
  2831. mov @Temp1, A
  2832. clr Flag_PGM_DIR_REV
  2833. clr Flag_PGM_BIDIR_REV
  2834. sjmp clear_dshot_cmd
  2835. dshot_direction_2:
  2836. ; Change programmed motor direction to reversed
  2837. cjne Temp1, #8, dshot_direction_bidir_off
  2838. clr C
  2839. mov A, Dshot_Cmd_Cnt
  2840. subb A, #6 ; Needs to receive it 6 times in a row
  2841. jc dont_clear_dshot_cmd
  2842. mov A, #2
  2843. jnb Flag_PGM_BIDIR, ($+5)
  2844. mov A, #4
  2845. mov Temp1, #Pgm_Direction
  2846. mov @Temp1, A
  2847. setb Flag_PGM_DIR_REV
  2848. setb Flag_PGM_BIDIR_REV
  2849. sjmp clear_dshot_cmd
  2850. dshot_direction_bidir_off:
  2851. ; Change programmed motor mode to normal (not bidirectional)
  2852. cjne Temp1, #9, dshot_direction_bidir_on
  2853. clr C
  2854. mov A, Dshot_Cmd_Cnt
  2855. subb A, #6 ; Needs to receive it 6 times in a row
  2856. jc dont_clear_dshot_cmd
  2857. jnb Flag_PGM_BIDIR, clear_dshot_cmd
  2858. clr C
  2859. mov Temp1, #Pgm_Direction
  2860. mov A, @Temp1
  2861. subb A, #2
  2862. mov @Temp1, A
  2863. clr Flag_PGM_BIDIR
  2864. sjmp clear_dshot_cmd
  2865. dshot_direction_bidir_on:
  2866. ; Change programmed motor mode to bidirectional
  2867. cjne Temp1, #10, dshot_direction_normal
  2868. clr C
  2869. mov A, Dshot_Cmd_Cnt
  2870. subb A, #6 ; Needs to receive it 6 times in a row
  2871. jc dont_clear_dshot_cmd
  2872. jb Flag_PGM_BIDIR, clear_dshot_cmd
  2873. mov Temp1, #Pgm_Direction
  2874. mov A, @Temp1
  2875. add A, #2
  2876. mov @Temp1, A
  2877. setb Flag_PGM_BIDIR
  2878. clear_dshot_cmd:
  2879. mov Dshot_Cmd, #0
  2880. mov Dshot_Cmd_Cnt, #0
  2881. dont_clear_dshot_cmd:
  2882. ret
  2883. dshot_direction_normal:
  2884. ; Change programmed motor direction to that stored in eeprom
  2885. cjne Temp1, #20, dshot_direction_reverse
  2886. clr C
  2887. mov A, Dshot_Cmd_Cnt
  2888. subb A, #6 ; Needs to receive it 6 times in a row
  2889. jc dont_clear_dshot_cmd
  2890. clr IE_EA ; DPTR used in interrupts
  2891. mov DPTR, #Eep_Pgm_Direction ; Read from flash
  2892. mov A, #0
  2893. movc A, @A+DPTR
  2894. setb IE_EA
  2895. mov Temp1, #Pgm_Direction
  2896. mov @Temp1, A
  2897. rrc A ; Lsb to carry
  2898. clr Flag_PGM_DIR_REV
  2899. clr Flag_PGM_BIDIR_REV
  2900. jc ($+4)
  2901. setb Flag_PGM_DIR_REV
  2902. jc ($+4)
  2903. setb Flag_PGM_BIDIR_REV
  2904. sjmp clear_dshot_cmd
  2905. dshot_direction_reverse: ; Temporary reverse
  2906. ; Change programmed motor direction to the reverse of what is stored in eeprom
  2907. cjne Temp1, #21, dshot_save_settings
  2908. clr C
  2909. mov A, Dshot_Cmd_Cnt
  2910. subb A, #6 ; Needs to receive it 6 times in a row
  2911. jc dont_clear_dshot_cmd
  2912. clr IE_EA ; DPTR used in interrupts
  2913. mov DPTR, #Eep_Pgm_Direction ; Read from flash
  2914. mov A, #0
  2915. movc A, @A+DPTR
  2916. setb IE_EA
  2917. mov Temp1, A
  2918. cjne Temp1, #1, ($+5)
  2919. mov A, #2
  2920. cjne Temp1, #2, ($+5)
  2921. mov A, #1
  2922. cjne Temp1, #3, ($+5)
  2923. mov A, #4
  2924. cjne Temp1, #4, ($+5)
  2925. mov A, #3
  2926. mov Temp1, #Pgm_Direction
  2927. mov @Temp1, A
  2928. rrc A ; Lsb to carry
  2929. clr Flag_PGM_DIR_REV
  2930. clr Flag_PGM_BIDIR_REV
  2931. jc ($+4)
  2932. setb Flag_PGM_DIR_REV
  2933. jc ($+4)
  2934. setb Flag_PGM_BIDIR_REV
  2935. sjmp clear_dshot_cmd
  2936. dshot_save_settings:
  2937. cjne Temp1, #12, clear_dshot_cmd
  2938. clr C
  2939. mov A, Dshot_Cmd_Cnt
  2940. subb A, #6 ; Needs to receive it 6 times in a row
  2941. jc dont_clear_dshot_cmd
  2942. mov Flash_Key_1, #0A5h ; Initialize flash keys to valid values
  2943. mov Flash_Key_2, #0F1h
  2944. call erase_and_store_all_in_eeprom
  2945. mov Flash_Key_1, #0 ; Initialize flash keys to invalid values
  2946. mov Flash_Key_2, #0
  2947. setb IE_EA
  2948. jmp clear_dshot_cmd
  2949. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2950. ;
  2951. ; Start entry point
  2952. ;
  2953. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  2954. init_start:
  2955. clr IE_EA
  2956. call switch_power_off
  2957. clr A
  2958. setb IE_EA
  2959. clr A
  2960. mov Adc_Conversion_Cnt, A
  2961. mov Flags0, A ; Clear flags0
  2962. mov Flags1, A ; Clear flags1
  2963. mov Flags_Startup, A ; Clear startup flags
  2964. mov Demag_Detected_Metric, A ; Clear demag metric
  2965. ;**** **** **** **** ****
  2966. ; Motor start beginning
  2967. ;**** **** **** **** ****
  2968. mov Adc_Conversion_Cnt, #8 ; Make sure a temp reading is done
  2969. call wait1ms
  2970. Start_Adc ; Start adc conversion
  2971. read_initial_temp:
  2972. jnb ADC0CN0_ADINT, read_initial_temp
  2973. Read_Adc_Result ; Read initial temperature
  2974. mov A, Temp2
  2975. jnz ($+3) ; Is reading below 256?
  2976. mov Temp1, A ; Yes - set average temperature value to zero
  2977. mov Current_Average_Temp, Temp1 ; Set initial average temperature
  2978. call check_temp_voltage_and_limit_power
  2979. mov Adc_Conversion_Cnt, #8 ; Make sure a temp reading is done next time
  2980. ; Set up start operating conditions
  2981. clr IE_EA ; Disable interrupts
  2982. ; Adjust startup power
  2983. mov Temp2, #Pgm_Startup_Pwr_Decoded
  2984. mov Pwm_Limit_Beg, @Temp2 ; Set initial pwm limit
  2985. mov Pwm_Limit, Pwm_Limit_Beg
  2986. mov Pwm_Limit_By_Rpm, Pwm_Limit_Beg
  2987. setb IE_EA
  2988. ; Begin startup sequence
  2989. IF MCU_48MHZ == 1
  2990. Set_MCU_Clk_48MHz
  2991. ; Scale DShot criteria for 48MHz
  2992. clr C
  2993. mov A, DShot_Frame_Length_Thr ; Scale frame length criteria
  2994. rlc A
  2995. mov DShot_Frame_Length_Thr, A
  2996. clr C
  2997. mov A, DShot_Pwm_Thr ; Scale pulse width criteria
  2998. rlc A
  2999. mov DShot_Pwm_Thr, A
  3000. ; Scale DShot telemetry for 24MHz
  3001. mov A, DShot_GCR_Pulse_Time_1
  3002. xch A, DShot_GCR_Pulse_Time_1_Tmp
  3003. mov DShot_GCR_Pulse_Time_1, A
  3004. mov A, DShot_GCR_Pulse_Time_2
  3005. xch A, DShot_GCR_Pulse_Time_2_Tmp
  3006. mov DShot_GCR_Pulse_Time_2, A
  3007. mov A, DShot_GCR_Pulse_Time_3
  3008. xch A, DShot_GCR_Pulse_Time_3_Tmp
  3009. mov DShot_GCR_Pulse_Time_3, A
  3010. mov DShot_GCR_Start_Delay, #DSHOT_TLM_START_DELAY_48
  3011. ENDIF
  3012. jnb Flag_PGM_BIDIR, init_start_bidir_done ; Check if bidirectional operation
  3013. clr Flag_PGM_DIR_REV ; Set spinning direction. Default fwd
  3014. jnb Flag_RCP_DIR_REV, ($+5) ; Check force direction
  3015. setb Flag_PGM_DIR_REV ; Set spinning direction
  3016. init_start_bidir_done:
  3017. setb Flag_STARTUP_PHASE ; Set startup phase flag
  3018. mov Startup_Cnt, #0 ; Reset counter
  3019. call comm5comm6 ; Initialize commutation
  3020. call comm6comm1
  3021. call initialize_timing ; Initialize timing
  3022. call calc_next_comm_timing ; Set virtual commutation point
  3023. call initialize_timing ; Initialize timing
  3024. call calc_next_comm_timing
  3025. call initialize_timing ; Initialize timing
  3026. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  3027. ;
  3028. ; Run entry point
  3029. ;
  3030. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  3031. ; Run 1 = B(p-on) + C(n-pwm) - comparator A evaluated
  3032. ; Out_cA changes from low to high
  3033. run1:
  3034. call wait_for_comp_out_high ; Wait for high
  3035. ; setup_comm_wait ; Setup wait time from zero cross to commutation
  3036. ; evaluate_comparator_integrity ; Check whether comparator reading has been normal
  3037. call wait_for_comm ; Wait from zero cross to commutation
  3038. call comm1comm2 ; Commutate
  3039. call calc_next_comm_timing ; Calculate next timing and wait advance timing wait
  3040. ; wait_advance_timing ; Wait advance timing and start zero cross wait
  3041. ; calc_new_wait_times
  3042. ; wait_before_zc_scan ; Wait zero cross wait and start zero cross timeout
  3043. ; Run 2 = A(p-on) + C(n-pwm) - comparator B evaluated
  3044. ; Out_cB changes from high to low
  3045. run2:
  3046. call wait_for_comp_out_low
  3047. ; setup_comm_wait
  3048. ; evaluate_comparator_integrity
  3049. call set_pwm_limit ; Set pwm power limit for low or high rpm
  3050. call wait_for_comm
  3051. call comm2comm3
  3052. call calc_next_comm_timing
  3053. ; wait_advance_timing
  3054. ; calc_new_wait_times
  3055. ; wait_before_zc_scan
  3056. ; Run 3 = A(p-on) + B(n-pwm) - comparator C evaluated
  3057. ; Out_cC changes from low to high
  3058. run3:
  3059. call wait_for_comp_out_high
  3060. ; setup_comm_wait
  3061. ; evaluate_comparator_integrity
  3062. call wait_for_comm
  3063. call comm3comm4
  3064. call calc_next_comm_timing
  3065. ; wait_advance_timing
  3066. ; calc_new_wait_times
  3067. ; wait_before_zc_scan
  3068. ; Run 4 = C(p-on) + B(n-pwm) - comparator A evaluated
  3069. ; Out_cA changes from high to low
  3070. run4:
  3071. call wait_for_comp_out_low
  3072. ; setup_comm_wait
  3073. ; evaluate_comparator_integrity
  3074. call wait_for_comm
  3075. call comm4comm5
  3076. call calc_next_comm_timing
  3077. ; wait_advance_timing
  3078. ; calc_new_wait_times
  3079. ; wait_before_zc_scan
  3080. ; Run 5 = C(p-on) + A(n-pwm) - comparator B evaluated
  3081. ; Out_cB changes from low to high
  3082. run5:
  3083. call wait_for_comp_out_high
  3084. ; setup_comm_wait
  3085. ; evaluate_comparator_integrity
  3086. call wait_for_comm
  3087. call comm5comm6
  3088. call calc_next_comm_timing
  3089. ; wait_advance_timing
  3090. ; calc_new_wait_times
  3091. ; wait_before_zc_scan
  3092. ; Run 6 = B(p-on) + A(n-pwm) - comparator C evaluated
  3093. ; Out_cC changes from high to low
  3094. run6:
  3095. Start_Adc ; Start adc conversion
  3096. call wait_for_comp_out_low
  3097. ; setup_comm_wait
  3098. ; evaluate_comparator_integrity
  3099. call wait_for_comm
  3100. call comm6comm1
  3101. call check_temp_voltage_and_limit_power
  3102. call calc_next_comm_timing
  3103. ; wait_advance_timing
  3104. ; calc_new_wait_times
  3105. ; wait_before_zc_scan
  3106. ; Check if it is direct startup
  3107. jnb Flag_STARTUP_PHASE, normal_run_checks
  3108. ; Set spoolup power variables
  3109. mov Pwm_Limit, Pwm_Limit_Beg ; Set initial max power
  3110. ; Check startup counter
  3111. mov Temp2, #24 ; Set nominal startup parameters
  3112. mov Temp3, #12
  3113. clr C
  3114. mov A, Startup_Cnt ; Load counter
  3115. subb A, Temp2 ; Is counter above requirement?
  3116. jc direct_start_check_rcp ; No - proceed
  3117. clr Flag_STARTUP_PHASE ; Clear startup phase flag
  3118. setb Flag_INITIAL_RUN_PHASE ; Set initial run phase flag
  3119. mov Initial_Run_Rot_Cntd, Temp3 ; Set initial run rotation count
  3120. mov Pwm_Limit, Pwm_Limit_Beg
  3121. mov Pwm_Limit_By_Rpm, Pwm_Limit_Beg
  3122. sjmp normal_run_checks
  3123. direct_start_check_rcp:
  3124. jnb Flag_RCP_STOP, run1 ; If pulse is above stop value - Continue to run
  3125. ajmp run_to_wait_for_power_on
  3126. normal_run_checks:
  3127. ; Check if it is initial run phase
  3128. jnb Flag_INITIAL_RUN_PHASE, initial_run_phase_done ; If not initial run phase - branch
  3129. jb Flag_DIR_CHANGE_BRAKE, initial_run_phase_done ; If a direction change - branch
  3130. ; Decrement startup rotaton count
  3131. mov A, Initial_Run_Rot_Cntd
  3132. dec A
  3133. ; Check number of initial rotations
  3134. jnz initial_run_check_startup_rot ; Branch if counter is not zero
  3135. clr Flag_INITIAL_RUN_PHASE ; Clear initial run phase flag
  3136. setb Flag_MOTOR_STARTED ; Set motor started
  3137. ajmp run1 ; Continue with normal run
  3138. initial_run_check_startup_rot:
  3139. mov Initial_Run_Rot_Cntd, A ; Not zero - store counter
  3140. jb Flag_PGM_BIDIR, initial_run_continue_run ; Check if bidirectional operation
  3141. jb Flag_RCP_STOP, run_to_wait_for_power_on ; Check if pulse is below stop value
  3142. initial_run_continue_run:
  3143. ajmp run1 ; Continue to run
  3144. initial_run_phase_done:
  3145. ; Reset stall count
  3146. mov Stall_Cnt, #0
  3147. ; Exit run loop after a given time
  3148. jb Flag_PGM_BIDIR, run6_check_timeout ; Check if bidirectional operation
  3149. mov Temp1, #250
  3150. mov Temp2, #Pgm_Brake_On_Stop
  3151. mov A, @Temp2
  3152. jz ($+4)
  3153. mov Temp1, #3 ; About 100ms before stopping when brake is set
  3154. clr C
  3155. mov A, Rcp_Stop_Cnt ; Load stop RC pulse counter low byte value
  3156. subb A, Temp1 ; Is number of stop RC pulses above limit?
  3157. jnc run_to_wait_for_power_on ; Yes, go back to wait for poweron
  3158. run6_check_timeout:
  3159. mov A, Rcp_Timeout_Cntd ; Load RC pulse timeout counter value
  3160. jz run_to_wait_for_power_on ; If it is zero - go back to wait for poweron
  3161. run6_check_dir:
  3162. jnb Flag_PGM_BIDIR, run6_check_speed ; Check if bidirectional operation
  3163. jb Flag_PGM_DIR_REV, run6_check_dir_rev ; Check if actual rotation direction
  3164. jb Flag_RCP_DIR_REV, run6_check_dir_change ; Matches force direction
  3165. sjmp run6_check_speed
  3166. run6_check_dir_rev:
  3167. jnb Flag_RCP_DIR_REV, run6_check_dir_change
  3168. sjmp run6_check_speed
  3169. run6_check_dir_change:
  3170. jb Flag_DIR_CHANGE_BRAKE, run6_check_speed
  3171. setb Flag_DIR_CHANGE_BRAKE ; Set brake flag
  3172. mov Pwm_Limit, Pwm_Limit_Beg ; Set max power while braking
  3173. ajmp run4 ; Go back to run 4, thereby changing force direction
  3174. run6_check_speed:
  3175. mov Temp1, #0F0h ; Default minimum speed
  3176. jnb Flag_DIR_CHANGE_BRAKE, run6_brake_done; Is it a direction change?
  3177. mov Pwm_Limit, Pwm_Limit_Beg ; Set max power while braking
  3178. mov Temp1, #20h ; Bidirectional braking termination speed
  3179. run6_brake_done:
  3180. clr C
  3181. mov A, Comm_Period4x_H ; Is Comm_Period4x more than 32ms (~1220 eRPM)?
  3182. subb A, Temp1
  3183. jnc ($+5) ; Yes - stop or turn direction
  3184. ajmp run1 ; No - go back to run 1
  3185. jnb Flag_DIR_CHANGE_BRAKE, run_to_wait_for_power_on ; If it is not a direction change - stop
  3186. clr Flag_DIR_CHANGE_BRAKE ; Clear brake flag
  3187. clr Flag_PGM_DIR_REV ; Set spinning direction. Default fwd
  3188. jnb Flag_RCP_DIR_REV, ($+5) ; Check force direction
  3189. setb Flag_PGM_DIR_REV ; Set spinning direction
  3190. setb Flag_INITIAL_RUN_PHASE
  3191. mov Initial_Run_Rot_Cntd, #18
  3192. mov Pwm_Limit, Pwm_Limit_Beg ; Set initial max power
  3193. ajmp run1 ; Go back to run 1
  3194. run_to_wait_for_power_on_fail:
  3195. inc Stall_Cnt ; Increment stall count
  3196. ; Check if RCP is zero, then it is a normal stop
  3197. jnb Flag_RCP_STOP, run_to_wait_for_power_on_stall_done
  3198. run_to_wait_for_power_on:
  3199. mov Stall_Cnt, #0
  3200. run_to_wait_for_power_on_stall_done:
  3201. clr IE_EA
  3202. call switch_power_off
  3203. mov Flags0, #0 ; Clear flags0
  3204. mov Flags1, #0 ; Clear flags1
  3205. mov Flags_Startup, #0 ; Clear startup flags
  3206. IF MCU_48MHZ == 1
  3207. Set_MCU_Clk_24MHz
  3208. ; Scale DShot criteria for 24MHz
  3209. clr C
  3210. mov A, DShot_Frame_Length_Thr ; Scale frame length criteria
  3211. rrc A
  3212. mov DShot_Frame_Length_Thr, A
  3213. clr C
  3214. mov A, DShot_Pwm_Thr ; Scale pulse width criteria
  3215. rrc A
  3216. mov DShot_Pwm_Thr, A
  3217. ; Scale DShot telemetry for 24MHz
  3218. mov A, DShot_GCR_Pulse_Time_1
  3219. xch A, DShot_GCR_Pulse_Time_1_Tmp
  3220. mov DShot_GCR_Pulse_Time_1, A
  3221. mov A, DShot_GCR_Pulse_Time_2
  3222. xch A, DShot_GCR_Pulse_Time_2_Tmp
  3223. mov DShot_GCR_Pulse_Time_2, A
  3224. mov A, DShot_GCR_Pulse_Time_3
  3225. xch A, DShot_GCR_Pulse_Time_3_Tmp
  3226. mov DShot_GCR_Pulse_Time_3, A
  3227. mov DShot_GCR_Start_Delay, #DSHOT_TLM_START_DELAY
  3228. ENDIF
  3229. setb IE_EA
  3230. call wait100ms ; Wait for pwm to be stopped
  3231. call switch_power_off
  3232. mov Temp1, #Pgm_Brake_On_Stop
  3233. mov A, @Temp1
  3234. jz run_to_wait_for_power_on_brake_done
  3235. AcomFET_on
  3236. BcomFET_on
  3237. CcomFET_on
  3238. run_to_wait_for_power_on_brake_done:
  3239. clr C
  3240. mov A, Stall_Cnt
  3241. subb A, #10 ; Maximum consecutive stalls before stopping
  3242. jc ($+5)
  3243. ljmp init_no_signal ; Stalled too many times
  3244. ljmp wait_for_power_on ; Go back to wait for power on
  3245. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  3246. $include (BLHeliPgm.inc) ; Include source code for programming the ESC
  3247. $include (BLHeliBootLoad.inc) ; Include source code for bootloader
  3248. ;**** **** **** **** **** **** **** **** **** **** **** **** ****
  3249. CSEG AT 19FDh
  3250. reset:
  3251. ljmp pgm_start
  3252. END