diff --git a/src/BLHeliBootLoad.inc b/src/BLHeliBootLoad.inc index 94afe97..6fd1afb 100644 --- a/src/BLHeliBootLoad.inc +++ b/src/BLHeliBootLoad.inc @@ -59,7 +59,7 @@ init: mov SP, #0c0h ; Stack = 64 upper bytes of RAM ; Initialize clock mov CLKSEL, #00h ; Set clock divider to 1 -IF MCU_TYPE == MCU_BB1 or MCU_TYPE = MCU_BB2 +IF MCU_TYPE == MCU_BB1 or MCU_TYPE == MCU_BB2 ; Initialize VDD monitor orl VDM0CN, #080h ; Enable the VDD monitor ENDIF @@ -68,7 +68,8 @@ ENDIF acall waitf ; Initialize flash keys - Unlock_Flash + mov BL_Flash_Key_1, #0A5h + mov BL_Flash_Key_2, #0F1h ; Initialize ports orl RTX_MDIN, #(1 SHL RTX_PIN) ; Set digital @@ -188,7 +189,11 @@ mai2: exit: mov Bit_Access, #0 ; Clear variable used by flash lock detect mov Bit_Access_Int, #0FFh ; Set variable to indicate that program execution came from bootloader - Lock_Flash + + ; Lock flash by setting invalid values + mov BL_Flash_Key_1, #0 + mov BL_Flash_Key_2, #0 + ljmp 0000h rst: ajmp init diff --git a/src/Bluejay.asm b/src/Bluejay.asm index 026f2e7..6428386 100644 --- a/src/Bluejay.asm +++ b/src/Bluejay.asm @@ -236,7 +236,7 @@ Wt_Zc_Tout_Start_L: DS 1 ; Timer3 start point for zero cross scan Wt_Zc_Tout_Start_H: DS 1 ; Timer3 start point for zero cross scan timeout (hi byte) Wt_Comm_Start_L: DS 1 ; Timer3 start point from zero cross to commutation (lo byte) Wt_Comm_Start_H: DS 1 ; Timer3 start point from zero cross to commutation (hi byte) -Pwm_Limit: DS 1 ; Maximum allowed pwm (8-bit) +Pwm_Limit_Startup_n_Temp: DS 1 ; Maximum allowed pwm (8-bit) - Used for startup power limit and temperature limit after startup Pwm_Limit_By_Rpm: DS 1 ; Maximum allowed pwm for low or high rpm (8-bit) Pwm_Limit_Beg: DS 1 ; Initial pwm limit (8-bit) Pwm_Braking24_L: DS 1 ; Max Braking @24khz pwm (lo byte) @@ -330,8 +330,8 @@ Temp_Storage: DS 48 ; Temporary storage (internal memory) ;**** **** **** **** **** **** **** **** **** **** **** **** **** CSEG AT CSEG_EEPROM EEPROM_FW_MAIN_REVISION EQU 0 ; Main revision of the firmware -EEPROM_FW_SUB_REVISION EQU 21 ; Sub revision of the firmware -EEPROM_LAYOUT_REVISION EQU 208 ; Revision of the EEPROM layout +EEPROM_FW_SUB_REVISION EQU 22 ; Sub revision of the firmware +EEPROM_LAYOUT_REVISION EQU 209 ; Revision of the EEPROM layout EEPROM_B2_PARAMETERS_COUNT EQU 30 ; Number of parameters Eep_FW_Main_Revision: DB EEPROM_FW_MAIN_REVISION ; EEPROM firmware main revision number @@ -734,28 +734,24 @@ wait_for_start_nonzero: ;**** **** **** **** **** **** **** **** **** **** **** **** **** motor_start: clr IE_EA ; Disable interrupts + call switch_power_off - setb IE_EA ; Enable interrupts clr A - mov Flags0, A ; Clear run time flags - mov Flags1, A - mov Demag_Detected_Metric, A ; Clear demag metric - mov Demag_Detected_Metric_Max, A ; Clear demag metric max - - call wait1ms - + mov Flags0, #0 ; Clear run time flags + mov Flags1, #0 + mov Demag_Detected_Metric, #0 ; Clear demag metric + mov Demag_Detected_Metric_Max, #0 ; Clear demag metric max mov Ext_Telemetry_H, #0 ; Clear extended telemetry data ; Set up start operating conditions - clr IE_EA ; Disable interrupts mov Temp2, #Pgm_Startup_Power_Max mov Pwm_Limit_Beg, @Temp2 ; Set initial pwm limit mov Pwm_Limit_By_Rpm, Pwm_Limit_Beg ; Set temperature PWM limit and setpoint to the maximum value - mov Pwm_Limit, #255 - mov Temp_Pwm_Level_Setpoint, #255 + mov Pwm_Limit_Startup_n_Temp, Pwm_Limit_Beg + mov Temp_Pwm_Level_Setpoint, Pwm_Limit_Beg ; Begin startup sequence IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 @@ -778,7 +774,6 @@ IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 mov DShot_GCR_Start_Delay, #DSHOT_TLM_START_DELAY_48 ENDIF - setb IE_EA ; Enable interrupts mov C, Flag_Pgm_Dir_Rev ; Read spin direction setting mov Flag_Motor_Dir_Rev, C @@ -792,11 +787,14 @@ ENDIF ; Motor start beginning ;**** **** **** **** **** **** **** **** **** **** **** **** **** motor_start_bidir_done: + ; Set initial motor state setb Flag_Startup_Phase ; Set startup phase flags setb Flag_Initial_Run_Phase mov Startup_Cnt, #0 ; Reset startup phase run counter mov Initial_Run_Rot_Cntd, #12 ; Set initial run rotation countdown - call comm5_comm6 ; Initialize commutation + + ; Initialize commutation + call comm5_comm6 ; Enable MOSFET commutation call comm6_comm1 call initialize_timing ; Initialize timing call calc_next_comm_period ; Set virtual commutation point @@ -804,6 +802,8 @@ motor_start_bidir_done: call calc_next_comm_period call initialize_timing ; Initialize timing + setb IE_EA ; Enable interrupts + ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Run entry point @@ -894,6 +894,7 @@ run6: jnb Flag_Startup_Phase, initial_run_phase ; Startup phase + mov Pwm_Limit_Startup_n_Temp, Pwm_Limit_Beg ; Set initial max power mov Pwm_Limit_By_Rpm, Pwm_Limit_Beg; Set initial max power clr C mov A, Startup_Cnt ; Load startup counter @@ -906,7 +907,6 @@ run6: startup_phase_done: ; Clear startup phase flag & remove pwm limits clr Flag_Startup_Phase - mov Pwm_Limit_By_Rpm, #255 initial_run_phase: ; If it is a direction change - branch @@ -927,6 +927,16 @@ initial_run_phase: initial_run_phase_done: clr Flag_Initial_Run_Phase ; Clear initial run phase flag + + ; Lift startup power restrictions + ; Temperature protection acts until this point + ; as a max startup power limiter. + ; This plus the power limits applied in set_pwm_limit function + ; act as a startup power limiter to protect the esc and the motor + ; during startup, jams produced after crashes and desyncs recovery + mov Pwm_Limit_Startup_n_Temp, #255 ; Reset temperature level pwm limit + mov Temp_Pwm_Level_Setpoint, #255 ; Reset temperature level setpoint + setb Flag_Motor_Started ; Set motor started jmp run1 ; Continue with normal run @@ -1011,11 +1021,13 @@ exit_run_mode_on_timeout: inc Startup_Stall_Cnt ; Increment stall count if motors did not properly start exit_run_mode: - clr IE_EA ; Disable all interrupts - clr Flag_Ext_Tele ; Clear extended DSHOT telemetry flag + ; Disable all interrupts (they will be disabled for a while, be aware) + clr IE_EA + call switch_power_off mov Flags0, #0 ; Clear run time flags (in case they are used in interrupts) mov Flags1, #0 + clr Flag_Ext_Tele ; Clear extended DSHOT telemetry flag IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 Set_MCU_Clk_24MHz @@ -1038,38 +1050,44 @@ IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 mov DShot_GCR_Start_Delay, #DSHOT_TLM_START_DELAY ENDIF - setb IE_EA ; Enable all interrupts - ; Check if RCP is zero, then it is a normal stop or signal timeout jb Flag_Rcp_Stop, exit_run_mode_no_stall + ; It is a stall! ; Signal stall setb Flag_Stall_Notify - clr C ; Otherwise - it's a stall + ; Check max consecutive stalls and exit if stall counter > 3 + clr C mov A, Startup_Stall_Cnt - subb A, #4 ; Maximum consecutive stalls - jnc exit_run_mode_stall_done + subb A, #3 + jnc exit_run_mode_is_stall + + ; At this point there was a desync event, and a new try is to be done. + ; The program will jump to motor_start. Interrupts are disabled at this + ; point so it is safe to jump to motor start, where a new initial state + ; will be set call wait100ms ; Wait for a bit between stall restarts + ljmp motor_start ; Go back and try starting motors again -exit_run_mode_stall_done: +exit_run_mode_is_stall: ; Clear extended DSHOT telemetry flag if turtle mode is not active ; This flag is also used for EDT safety arm flag ; We don't want to deactivate extended telemetry during turtle mode ; Extended telemetry flag is important because it is involved in ; EDT safety feature. We don't want to disable EDT arming during ; turtle mode. - jb Flag_User_Reverse_Requested, exit_run_mode_stall_done_beep + jb Flag_User_Reverse_Requested, exit_run_mode_is_stall_beep clr Flag_Ext_Tele -exit_run_mode_stall_done_beep: +exit_run_mode_is_stall_beep: ; Stalled too many times - clr IE_EA call beep_motor_stalled - setb IE_EA + ; Enable all interrupts before jump (disabled above, in exit_run_mode) + setb IE_EA ljmp arming_begin ; Go back and wait for arming exit_run_mode_no_stall: @@ -1079,10 +1097,10 @@ exit_run_mode_no_stall: ; Extended telemetry flag is important because it is involved in ; EDT safety feature. We don't want to disable EDT arming during ; turtle mode. - jb Flag_User_Reverse_Requested, exit_run_mode_no_stall_beep + jb Flag_User_Reverse_Requested, exit_run_mode_no_stall_no_beep clr Flag_Ext_Tele -exit_run_mode_no_stall_beep: +exit_run_mode_no_stall_no_beep: ; Clear stall counter mov Startup_Stall_Cnt, #0 @@ -1095,6 +1113,8 @@ exit_run_mode_no_stall_beep: C_Com_Fet_On exit_run_mode_brake_done: + ; Enable all interrupts before jump (disabled above, in exit_run_mode) + setb IE_EA ljmp wait_for_start ; Go back to wait for power on ;**** **** **** **** **** **** **** **** **** **** **** **** **** diff --git a/src/Modules/Isrs.asm b/src/Modules/Isrs.asm index 5535e87..9ad0e8b 100644 --- a/src/Modules/Isrs.asm +++ b/src/Modules/Isrs.asm @@ -347,7 +347,7 @@ t1_int_zero_rcp_checked: t1_int_zero_rcp_checked_set_limit: ; Set pwm limit clr C - mov A, Pwm_Limit ; Limit to the smallest + mov A, Pwm_Limit_Startup_n_Temp ; Limit to the smallest mov Temp6, A ; Store limit in Temp6 subb A, Pwm_Limit_By_Rpm jc t1_int_zero_rcp_checked_check_limit diff --git a/src/Modules/Power.asm b/src/Modules/Power.asm index 91d9a62..629efef 100644 --- a/src/Modules/Power.asm +++ b/src/Modules/Power.asm @@ -35,9 +35,16 @@ ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** switch_power_off: + ; This three macros disable MOSFET communtation. + ; Dshot frames will have no effect after disabling MOSFET communtation. + ; Commutation is started again at motor_start_bidir_done. All_Pwm_Fets_Off ; Turn off all pwm FETs All_Com_Fets_Off ; Turn off all commutation FETs Set_All_Pwm_Phases_Off + + ; Enforce all PWM limits to zero to disable dshot frame rcpulses + mov Pwm_Limit_By_Rpm, #0 + mov Pwm_Limit_Startup_n_Temp, #0 ret ;**** **** **** **** **** **** **** **** **** **** **** **** **** @@ -50,10 +57,17 @@ switch_power_off: set_pwm_limit: jb Flag_High_Rpm, set_pwm_limit_high_rpm ; If high rpm,limit pwm by rpm instead - ;set_pwm_limit_low_rpm: - ; Set pwm limit +set_pwm_limit_low_rpm: + ; Set pwm limit for startup phase to avoid burning the esc/motor during startup + ; (Startup can happen after a desync caused by a crash, if that is the case it + ; will be better to avoid burning esc/motor) + mov Temp1, Pwm_Limit_Beg + + ; Exit if startup phase is set + jb Flag_Startup_Phase, set_pwm_limit_low_rpm_exit + + ; Set default pwm limit for other phases mov Temp1, #0FFh ; Default full power - jb Flag_Startup_Phase, set_pwm_limit_low_rpm_exit ; Exit if startup phase set mov A, Low_Rpm_Pwr_Slope ; Check if low RPM power protection is enabled jz set_pwm_limit_low_rpm_exit ; Exit if disabled (zero) @@ -72,9 +86,13 @@ set_pwm_limit_calculate: mul AB mov Temp1, A ; Set new limit xch A, B + + ; If RPM_PWM_LIMIT < 255 goto set_pwm_limit_check_limit_to_min jz set_pwm_limit_check_limit_to_min ; Limit to max - mov Temp1, #0FFh + ; Limit is bigger than 0xFF -> set max pwm and exit + mov Pwm_Limit_By_Rpm, #0FFh + ret set_pwm_limit_check_limit_to_min: clr C diff --git a/src/Modules/Scheduler.asm b/src/Modules/Scheduler.asm index 4f17fac..44bf985 100644 --- a/src/Modules/Scheduler.asm +++ b/src/Modules/Scheduler.asm @@ -183,21 +183,21 @@ scheduler_steps_odd: ; resulting in current spikes, that may damage motor/ESC. ; Compare pwm limit to setpoint clr C - mov A, Pwm_Limit + mov A, Pwm_Limit_Startup_n_Temp subb A, Temp_Pwm_Level_Setpoint jz scheduler_steps_odd_choose_step ; pwm limit == setpoint -> next jc scheduler_steps_odd_temp_pwm_limit_inc ; pwm limit < setpoint -> increase pwm limit scheduler_steps_odd_temp_pwm_limit_dec: ; Decrease pwm limit - dec Pwm_Limit + dec Pwm_Limit_Startup_n_Temp ; Continue with odd scheduler step selection sjmp scheduler_steps_odd_choose_step scheduler_steps_odd_temp_pwm_limit_inc: ; Increase pwm limit - inc Pwm_Limit + inc Pwm_Limit_Startup_n_Temp ; Run speciffic odd scheduler step scheduler_steps_odd_choose_step: diff --git a/src/Modules/Timing.asm b/src/Modules/Timing.asm index d12dea6..19eba76 100644 --- a/src/Modules/Timing.asm +++ b/src/Modules/Timing.asm @@ -776,9 +776,16 @@ evaluate_comparator_integrity: jb Flag_Dir_Change_Brake, eval_comp_exit ; Do not exit run mode if braking jb Flag_Demag_Detected, eval_comp_exit ; Do not exit run mode if it is a demag situation - dec SP ; Routine exit without "ret" command + ; Disable all interrupts and cut power ASAP. They will be enabled in exit_run_mode_on_timeout + clr IE_EA + call switch_power_off + + ; Routine exit without "ret" command dec SP - ljmp exit_run_mode_on_timeout ; Exit run mode if timeout has elapsed + dec SP + + ; Go to exit run mode if timeout has elapsed + ljmp exit_run_mode_on_timeout eval_comp_startup: inc Startup_Cnt ; Increment startup counter diff --git a/src/Settings/BluejaySettings.asm b/src/Settings/BluejaySettings.asm index aa02349..485796f 100644 --- a/src/Settings/BluejaySettings.asm +++ b/src/Settings/BluejaySettings.asm @@ -42,10 +42,10 @@ DEFAULT_PGM_POWER_RATING EQU 2 ; 1=1S,2=2S+ DEFAULT_PGM_BRAKE_ON_STOP EQU 0 ; 1=Enabled 0=Disabled DEFAULT_PGM_LED_CONTROL EQU 0 ; Byte for LED control. 2 bits per LED,0=Off,1=On -DEFAULT_PGM_STARTUP_POWER_MIN EQU 51 ; 0..255 => (1000..1125 Throttle): value * (1000 / 2047) + 1000 +DEFAULT_PGM_STARTUP_POWER_MIN EQU 21 ; 0..255 => (1000..1125 Throttle): value * (1000 / 2047) + 1000 DEFAULT_PGM_STARTUP_BEEP EQU 1 ; 0=Short beep,1=Melody -DEFAULT_PGM_STARTUP_POWER_MAX EQU 25 ; 0..255 => (1000..2000 Throttle): Maximum startup power +DEFAULT_PGM_STARTUP_POWER_MAX EQU 5 ; 0..255 => (1000..2000 Throttle): Maximum startup power DEFAULT_PGM_BRAKING_STRENGTH EQU 255 ; 0..255 => 0..100 % Braking DEFAULT_PGM_SAFETY_ARM EQU 0 ; EDT safety arm is disabled by default