diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8598f6..caa40f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: push: tags: - '*' - pull_request: + pull_request_target: branches: - main - develop diff --git a/.gitignore b/.gitignore index f9fc868..135791f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ /build /tools/.wine *.diff +.project + diff --git a/BLHeliBootLoad.inc b/BLHeliBootLoad.inc index 3be05cd..ce91cc3 100644 --- a/BLHeliBootLoad.inc +++ b/BLHeliBootLoad.inc @@ -3,9 +3,9 @@ XTAL EQU 25000000 ; Bootloader segment address -IF MCU_48MHZ < 2 +IF MCU_TYPE < 2 BOOT_START EQU 1C00h -ELSEIF MCU_48MHZ == 2 +ELSEIF MCU_TYPE == 2 BOOT_START EQU 0F000h ENDIF @@ -58,7 +58,7 @@ init:clr IE_EA mov SP, #0c0h ; Stack = 64 upper bytes of RAM ; Initialize clock mov CLKSEL, #00h ; Set clock divider to 1 - IF MCU_48MHZ < 2 + IF MCU_TYPE < 2 ; Initialize VDD monitor orl VDM0CN, #080h ; Enable the VDD monitor ENDIF @@ -239,9 +239,9 @@ pro4:djnz Xl, pro5 pro5: clr C mov A, DPH ; Check that address is not in bootloader area - IF MCU_48MHZ < 2 + IF MCU_TYPE < 2 subb A, #1Ch - ELSEIF MCU_48MHZ == 2 + ELSEIF MCU_TYPE == 2 subb A, #0F0h ENDIF jc ($+5) diff --git a/Bluejay.asm b/Bluejay.asm index e01bb54..41d80d1 100644 --- a/Bluejay.asm +++ b/Bluejay.asm @@ -71,7 +71,7 @@ ; PORT 0 PORT 1 PWM COM PWM LED ; P0 P1 P2 P3 P4 P5 P6 P7 P0 P1 P2 P3 P4 P5 P6 P7 inv inv side n ; ----------------------- ----------------------- ------------------ -IF MCU_48MHZ < 2 +IF MCU_TYPE < 2 A_ EQU 1 ; Vn Am Bm Cm __ RX __ __ Ap Ac Bp Bc Cp Cc __ __ no no high _ B_ EQU 2 ; Vn Am Bm Cm __ RX __ __ Cc Cp Bc Bp Ac Ap __ __ no no high _ C_ EQU 3 ; RX __ Vn Am Bm Cm Ap Ac Bp Bc Cp Cc __ __ __ __ no no high _ @@ -101,7 +101,7 @@ Z_ EQU 26 ; Bm Cm Am Vn __ RX __ __ Ac Ap Bc Bp Cc Cp __ __ yes no high _ Pinou ENDIF ; BB51 - Required -IF MCU_48MHZ = 2 +IF MCU_TYPE = 2 A_ EQU 1 ; __ Bm Cm Am Vn RX __ __ Ap Ac Bp Bc Cp Cc __ __ no no low _ B_ EQU 2 ; __ Bm Cm Am Vn RX __ __ Ac Ap Bc Bp Cc Cp __ __ no yes high _ C_ EQU 3 ; __ Bm Cm Am Vn RX __ __ Ac Ap Bc Bp Cc Cp __ __ yes yes high _ @@ -113,9 +113,9 @@ ENDIF ;**** **** **** **** **** ; Select the MCU type (or unselect for use with external batch compile file) -;MCU_48MHZ EQU 0 ; BB1 -;MCU_48MHZ EQU 1 ; BB2 -;MCU_48MHZ EQU 2 ; BB51 +;MCU_TYPE EQU 0 ; BB1 +;MCU_TYPE EQU 1 ; BB2 +;MCU_TYPE EQU 2 ; BB51 ;**** **** **** **** **** ; Select the FET dead time (or unselect for use with external batch compile file) @@ -125,16 +125,15 @@ ENDIF ; Select the pwm frequency (or unselect for use with external batch compile file) ;PWM_FREQ EQU 0 ; 0=24, 1=48, 2=96 kHz - PWM_CENTERED EQU DEADTIME > 0 ; Use center aligned pwm on ESCs with dead time -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 IS_MCU_48MHZ EQU 0 ELSE IS_MCU_48MHZ EQU 1 ENDIF -IF MCU_48MHZ < 3 AND PWM_FREQ < 3 +IF MCU_TYPE < 3 AND PWM_FREQ < 3 ; Number of bits in pwm high byte PWM_BITS_H EQU (2 + IS_MCU_48MHZ - PWM_CENTERED - PWM_FREQ) ENDIF @@ -152,6 +151,8 @@ DEFAULT_PGM_BEACON_STRENGTH EQU 80 ; 0..255 DEFAULT_PGM_BEACON_DELAY EQU 4 ; 1=1m 2=2m 3=5m 4=10m 5=Infinite DEFAULT_PGM_ENABLE_TEMP_PROT EQU 7 ; 0=Disabled 1=80C 2=90C 3=100C 4=110C 5=120C 6=130C 7=140C +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 @@ -184,6 +185,9 @@ Flags0: DS 1 ; State flags. Reset upon motor_start Flag_Startup_Phase BIT Flags0.0 ; Set when in startup phase Flag_Initial_Run_Phase BIT Flags0.1 ; Set when in initial run phase (or startup phase), before synchronized run is achieved. Flag_Motor_Dir_Rev BIT Flags0.2 ; Set if the current spinning direction is reversed +Flag_Demag_Notify BIT Flags0.3 ; Set when motor demag has been detected but still not notified +Flag_Desync_Notify BIT Flags0.4 ; Set when motor desync has been detected but still not notified +Flag_Stall_Notify BIT Flags0.5 ; Set when motor stall detected but still not notified Flags1: DS 1 ; State flags. Reset upon motor_start Flag_Timer3_Pending BIT Flags1.0 ; Timer3 pending flag @@ -226,6 +230,7 @@ Startup_Zc_Timeout_Cntd: DS 1 ; Startup zero cross timeout counter (decrementin Initial_Run_Rot_Cntd: DS 1 ; Initial run rotations counter (decrementing) Startup_Stall_Cnt: DS 1 ; Counts start/run attempts that resulted in stall. Reset upon a proper stop Demag_Detected_Metric: DS 1 ; Metric used to gauge demag event frequency +Demag_Detected_Metric_Max: DS 1 ; Metric used to gauge demag event frequency Demag_Pwr_Off_Thresh: DS 1 ; Metric threshold above which power is cut Low_Rpm_Pwr_Slope: DS 1 ; Sets the slope of power increase for low rpm @@ -328,6 +333,7 @@ _Pgm_Enable_Pwm_Input: DS 1 ; Enable PWM input signal _Pgm_Pwm_Dither: DS 1 ; Output PWM dither Pgm_Brake_On_Stop: DS 1 ; Braking when throttle is zero Pgm_LED_Control: DS 1 ; LED control +Pgm_Power_Rating: DS 1 ; Power rating ISEG AT 0B0h Stack: DS 16 ; Reserved stack space @@ -341,14 +347,15 @@ Temp_Storage: DS 48 ; Temporary storage (internal memory) ;**** **** **** **** **** ; EEPROM code segments ; A segment of the flash is used as "EEPROM", which is not available in SiLabs MCUs -IF MCU_48MHZ == 2 +IF MCU_TYPE == 2 CSEG AT 3000h ELSE CSEG AT 1A00h ENDIF EEPROM_FW_MAIN_REVISION EQU 0 ; Main revision of the firmware -EEPROM_FW_SUB_REVISION EQU 18 ; Sub revision of the firmware -EEPROM_LAYOUT_REVISION EQU 204 ; Revision of the EEPROM layout +EEPROM_FW_SUB_REVISION EQU 19 ; Sub revision of the firmware +EEPROM_LAYOUT_REVISION EQU 206 ; Revision of the EEPROM layout +EEPROM_B2_PARAMETERS_COUNT EQU 27 ; Number of parameters Eep_FW_Main_Revision: DB EEPROM_FW_MAIN_REVISION ; EEPROM firmware main revision number Eep_FW_Sub_Revision: DB EEPROM_FW_SUB_REVISION ; EEPROM firmware sub revision number @@ -366,6 +373,8 @@ Eep_Pgm_Direction: DB DEFAULT_PGM_DIRECTION ; EEPROM copy of programmed rotat _Eep__Pgm_Input_Pol: DB 0FFh Eep_Initialized_L: DB 055h ; EEPROM initialized signature (lo byte) Eep_Initialized_H: DB 0AAh ; EEPROM initialized signature (hi byte) + +; EEPROM parameters block 2 (B2) _Eep_Enable_TX_Program: DB 0FFh ; EEPROM TX programming enable Eep_Pgm_Braking_Strength: DB DEFAULT_PGM_BRAKING_STRENGTH _Eep_Pgm_Gov_Setup_Target: DB 0FFh @@ -392,17 +401,18 @@ _Eep_Pgm_Enable_Pwm_Input: DB 0FFh _Eep_Pgm_Pwm_Dither: DB 0FFh Eep_Pgm_Brake_On_Stop: DB DEFAULT_PGM_BRAKE_ON_STOP ; EEPROM copy of programmed braking when throttle is zero Eep_Pgm_LED_Control: DB DEFAULT_PGM_LED_CONTROL ; EEPROM copy of programmed LED control +Eep_Pgm_Power_Rating: DB DEFAULT_PGM_POWER_RATING ; EEPROM copy of programmed power rating Eep_Dummy: DB 0FFh ; EEPROM address for safety reason -IF MCU_48MHZ == 2 +IF MCU_TYPE == 2 CSEG AT 3060h ELSE CSEG AT 1A60h ENDIF Eep_Name: DB "Bluejay " ; Name tag (16 Bytes) -IF MCU_48MHZ == 2 +IF MCU_TYPE == 2 CSEG AT 3070h ELSE CSEG AT 1A70h @@ -426,13 +436,13 @@ CSEG AT 80h ; Code segment after interrupt vectors DSHOT_TLM_CLOCK EQU 24500000 ; 24.5MHz DSHOT_TLM_START_DELAY EQU -(5 * 25 / 4) ; Start telemetry after 5 us (~30 us after receiving DShot cmd) -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 DSHOT_TLM_PREDELAY EQU 9 ; 9 Timer0 ticks inherent delay ELSE DSHOT_TLM_PREDELAY EQU 7 ; 7 Timer0 ticks inherent delay ENDIF -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 DSHOT_TLM_CLOCK_48 EQU 49000000 ; 49MHz DSHOT_TLM_START_DELAY_48 EQU -(16 * 49 / 4) ; Start telemetry after 16 us (~30 us after receiving DShot cmd) DSHOT_TLM_PREDELAY_48 EQU 11 ; 11 Timer0 ticks inherent delay @@ -445,7 +455,7 @@ Set_DShot_Tlm_Bitrate MACRO rate mov DShot_GCR_Start_Delay, #DSHOT_TLM_START_DELAY -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 mov DShot_GCR_Pulse_Time_1_Tmp, #(DSHOT_TLM_PREDELAY_48 - (1 * DSHOT_TLM_CLOCK_48 / 4 / rate)) mov DShot_GCR_Pulse_Time_2_Tmp, #(DSHOT_TLM_PREDELAY_48 - (2 * DSHOT_TLM_CLOCK_48 / 4 / rate)) mov DShot_GCR_Pulse_Time_3_Tmp, #(DSHOT_TLM_PREDELAY_48 - (3 * DSHOT_TLM_CLOCK_48 / 4 / rate)) @@ -1066,7 +1076,7 @@ IF DEADTIME != 0 ; Damping pwm duty cycle will be higher because numbers are inverted clr C mov A, Temp2 ; Skew damping FET timing -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 subb A, #((DEADTIME + 1) SHR 1) ELSE subb A, #(DEADTIME) @@ -1673,7 +1683,7 @@ set_pwm_limit_low_rpm_exit: set_pwm_limit_high_rpm: clr C mov A, Comm_Period4x_L -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 subb A, #0A0h ; Limit Comm_Period4x to 160, which is ~510k erpm ELSE subb A, #0E4h ; Limit Comm_Period4x to 228, which is ~358k erpm @@ -1700,6 +1710,22 @@ set_pwm_limit_high_rpm_store: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Scheduler +; Each step 32ms, cycle 256ms (8 steps) +; +; ReqSch00: - Steps even [0, 2, 4, 6] +; ReqSch01: - Update temperature setpoint +; ReqSch02: - [TELEMETRY] Send demag metric frame +; ReqSch03: - Steps odd [1, 3, 5, 7] +; ReqSch04: - Update temperature PWM limit +; ReqSch06: - Case step 1 +; ReqSch07: - [TELEMETRY] Send status frame +; ReqSch08: - Case step 3 +; ReqSch09: - [TELEMETRY] Send debug1 frame +; ReqSch10: - Case step 5 +; ReqSch11: - [TELEMETRY] Send debug2 frame +; ReqSch12: - Case step 7 +; ReqSch13: - [TELEMETRY] Send temperature frame +; ReqSch14: - Start new ADC conversion ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** @@ -1712,194 +1738,235 @@ scheduler_start: ; Increment Scheduler Counter inc Scheduler_Counter -;****************** 128 ms scheduler ******************* -;*********** For PWM temperature limiting ************** -scheduler_128ms_switch_case: - ; Apply 128ms mask to Scheduler_Counter (2 lowest bits) + ; Choose between odd or even steps mov A, Scheduler_Counter - anl A, #03h + jb ACC.0, scheduler_steps_odd -scheduler_128ms_switch_case_32ms: - cjne A, #1, scheduler_128ms_switch_case_64ms +scheduler_steps_even: + ; ********************* UPDATE TEMPERATURE SETPOINT ***************** - ; Check temp protection enabled, and exit when protection is disabled + ; Check temp protection enabled, and skip when protection is disabled mov A, Temp_Prot_Limit - jz scheduler_1024ms_switch_case + jz scheduler_steps_even_demag_metric_frame - ; ******* UPDATE TEMPERATURE SETPOINT ******* - mov Temp_Pwm_Level_Setpoint, #255 ; Remove setpoint + ; Set setpoint maximum value + mov Temp_Pwm_Level_Setpoint, #255 ; Check TEMP_LIMIT in Base.inc and make calculations to understand temperature readings - ; Is temperature reading below 256? (ADC 10bit value corresponding to about 25ºC) + ; Is temperature reading below 256? + ; On BB1 & BB21 + ; - Using external voltage regulator and vdd 3.3V as ADC reference -> ADC 10bit value corresponding to about 25ºC + ; - Using external voltage regulator and internal 1.65V as ADC reference -> ADC 10bit value corresponding to about 0ºC + ; On BB51 + ; - Using external voltage regulator and internal 1.65V as ADC reference -> ADC 10bit value corresponding to about 0ºC mov A, ADC0H ; Load temp hi - jz scheduler_1024ms_switch_case ; Temperature below 25ºC (on BB1 or BB2) and below 0ºC (on BB51) do not update setpoint + jz scheduler_steps_even_demag_metric_frame ; Temperature below 25ºC (on 2S+ (BB1, BB2)) and below 0ºC (on 1S (BB1, BB21), BB51) do not update setpoint - mov A, ADC0L ; Load temp lo + mov A, ADC0L ; Load temp lo clr C - subb A, Temp_Prot_Limit ; Is temperature below first limit? - jc scheduler_1024ms_switch_case ; Yes - Jump to next scheduler + subb A, Temp_Prot_Limit ; Is temperature below first limit? + jc scheduler_steps_even_demag_metric_frame ; Yes - Jump to next scheduler - mov Temp_Pwm_Level_Setpoint, #200 ; No - update pwm limit (about 80%) + mov Temp_Pwm_Level_Setpoint, #200 ; No - update pwm limit (about 80%) - subb A, #(TEMP_LIMIT_STEP / 2) ; Is temperature below second limit - jc scheduler_1024ms_switch_case ; Yes - Jump to next scheduler + subb A, #(TEMP_LIMIT_STEP / 2) ; Is temperature below second limit + jc scheduler_steps_even_demag_metric_frame ; Yes - Jump to next scheduler - mov Temp_Pwm_Level_Setpoint, #150 ; No - update pwm limit (about 60%) + mov Temp_Pwm_Level_Setpoint, #150 ; No - update pwm limit (about 60%) - subb A, #(TEMP_LIMIT_STEP / 2) ; Is temperature below third limit - jc scheduler_1024ms_switch_case ; Yes - Jump to next scheduler + subb A, #(TEMP_LIMIT_STEP / 2) ; Is temperature below third limit + jc scheduler_steps_even_demag_metric_frame ; Yes - Jump to next scheduler - mov Temp_Pwm_Level_Setpoint, #100 ; No - update pwm limit (about 40% allowing landing) + mov Temp_Pwm_Level_Setpoint, #100 ; No - update pwm limit (about 40% allowing landing) - subb A, #(TEMP_LIMIT_STEP / 2) ; Is temperature below final limit - jc scheduler_1024ms_switch_case ; Yes - Jump to next scheduler + subb A, #(TEMP_LIMIT_STEP / 2) ; Is temperature below final limit + jc scheduler_steps_even_demag_metric_frame ; Yes - Jump to next scheduler - mov Temp_Pwm_Level_Setpoint, #50 ; No - update pwm limit (about 20% forced landing) + mov Temp_Pwm_Level_Setpoint, #50 ; No - update pwm limit (about 20% forced landing) ; Zero pwm cannot be set because of set_pwm_limit algo restrictions ; Otherwise hard stuttering is produced - ; Jump to next scheduler - sjmp scheduler_1024ms_switch_case +scheduler_steps_even_demag_metric_frame: + ; ********************* [TELEMETRY] SEND DEMAG METRIC FRAME ***************** + mov Ext_Telemetry_L, Demag_Detected_Metric ; Set telemetry low value to demag metric data + mov Ext_Telemetry_H, #0Ch ; Set telemetry high value to demag metric frame ID + + ; No more work to do + jmp scheduler_exit -scheduler_128ms_switch_case_64ms: - cjne A, #2, scheduler_128ms_switch_case_96ms +scheduler_steps_odd: + ; ********************* UPDATE TEMPERATURE PWM LIMIT ***************** ; Check temp protection enabled, and exit when protection is disabled mov A, Temp_Prot_Limit - jz scheduler_1024ms_switch_case - - ; Update PWM limit + jz scheduler_steps_odd_choose_step ; pwm limit is updated one unit at a time to avoid abrupt pwm changes - ; resulting in current spikes + ; resulting in current spikes, that may damage motor/esc ; Compare pwm limit to setpoint clr C mov A, Pwm_Limit subb A, Temp_Pwm_Level_Setpoint - jz scheduler_1024ms_switch_case ; pwm limit == setpoint -> next - jc scheduler_128ms_temp_update_pwm_limit_inc ; pwm limit < setpoint -> increase pwm limit + 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_128ms_temp_update_pwm_limit_dec: +scheduler_steps_odd_temp_pwm_limit_dec: ; Decrease pwm limit - mov A, Pwm_Limit - jz scheduler_1024ms_switch_case ; pwm limit is 0 -> Exit dec Pwm_Limit - ; Jump to next scheduler - sjmp scheduler_1024ms_switch_case + ; Now run speciffic odd scheduler step + sjmp scheduler_steps_odd_choose_step -scheduler_128ms_temp_update_pwm_limit_inc: +scheduler_steps_odd_temp_pwm_limit_inc: ; Increase pwm limit - mov A, Pwm_Limit - inc A - jz ($+4) inc Pwm_Limit - ; Jump to next scheduler - sjmp scheduler_1024ms_switch_case + ; Now run speciffic odd scheduler step -scheduler_128ms_switch_case_96ms: - cjne A, #3, scheduler_1024ms_switch_case +scheduler_steps_odd_choose_step: + ; Let A = Scheduler_Counter % 8, so A = [0 - 7] value + mov A, Scheduler_Counter + anl A, #07h - ; Start a new ADC conversion so after 64ms it will be ready for stage 2 og 128ms scheduler - Stop_Adc - Start_Adc +scheduler_steps_odd_status_frame: + ; ********************* [TELEMETRY] SEND STATUS FRAME ***************** + cjne A, #1, scheduler_steps_odd_debug1_frame - ; Continue on next scheduler + ; if (Demag_Detected_Metric_Max >= 120) + ; stat.demagMetricMax = (Demag_Detected_Metric_Max - 120) / 9 + ; else + ; stat.demagMetricMax = 0 + clr C + mov A, Demag_Detected_Metric_Max + subb A, #120 ; 120: substract the minimum + jnc scheduler_steps_odd_status_frame_max_load + clr A + sjmp scheduler_steps_odd_status_frame_max_loaded +scheduler_steps_odd_status_frame_max_load: + mov B, #9 + div AB ; Ranges: [0 - 135] / 9 == [0 - 15] +scheduler_steps_odd_status_frame_max_loaded: + ; Load flags + mov C, Flag_Demag_Notify + mov ACC.7, C + mov C, Flag_Desync_Notify + mov ACC.6, C + mov C, Flag_Stall_Notify + mov ACC.5, C -;****************** 1024 ms scheduler ******************* -;************ For Extended Dshot Telemetry ************** -scheduler_1024ms_switch_case: - ; Return if extended telemetry is disabled - jnb Flag_Ext_Tele, scheduler_exit + ; Data loaded clear flags + clr Flag_Demag_Notify + clr Flag_Desync_Notify + clr Flag_Stall_Notify - ; Apply 1s mask to Scheduler_Counter (5 lowest bits) - mov A, Scheduler_Counter - anl A, #01Fh - -IF MCU_48MHZ < 2 - scheduler_1024ms_switch_case_128ms: - cjne A, #4, scheduler_1024ms_switch_case_256ms - - ; Prepare extended telemetry temperature value for next telemetry transmission - ; Check value above or below 20ºC - this is an approximation ADCOH having a value - ; of 0x01 equals to around 22.5ºC. - mov A, ADC0H - jnz scheduler_1024ms_do_extended_telemetry_temp_above_20 - - scheduler_1024ms_do_extended_telemetry_temp_below_20: - ; Value below 20ºC -> to code between 0-20 - mov A, ADC0L - clr C - subb A, #(255 - 20) - jnc scheduler_1024ms_do_extended_telemetry_temp_load - - ; Value below 0ºC -> clamp to 0 - clr A - sjmp scheduler_1024ms_do_extended_telemetry_temp_load - - scheduler_1024ms_do_extended_telemetry_temp_above_20: - ; Value above 20ºC -> to code between 20-255 - mov A, ADC0L ; This is an approximation: 9 ADC steps @10 Bit are 10 degrees - add A, #20 -ELSEIF MCU_48MHZ == 2 - scheduler_1024ms_switch_case_128ms: - cjne A, #4, scheduler_1024ms_switch_case_256ms - - mov A, ADC0H - jnz scheduler_1024ms_do_extended_telemetry_temp_above_0 - - scheduler_1024ms_do_extended_telemetry_temp_below_0: - ; If Hi Byte is not 0x01 we are definetly below 0, thus - ; clamp to 0. - clr A - sjmp scheduler_1024ms_do_extended_telemetry_temp_load - - scheduler_1024ms_do_extended_telemetry_temp_above_0: - ; Prepare extended telemetry temperature value for next telemetry transmission - ; On BB51 they hi byte is always 1 if the temperature is above 0ºC. - ; In fact the value is 0x0114 at 0ºC, thus we ignore the hi byte and normalize - ; the low byte to - mov A, ADC0L - subb A, #14h -ENDIF + ; Load status frame + mov Ext_Telemetry_L, A ; Set telemetry low value to status data + mov Ext_Telemetry_H, #0Eh ; Set telemetry high value to status frame ID -scheduler_1024ms_do_extended_telemetry_temp_load: - mov Ext_Telemetry_L, A ; Set telemetry low value with temperature data - mov Ext_Telemetry_H, #02h ; Set telemetry high value on first repeated dshot coding partition + ; Now restart ADC conversion + sjmp scheduler_steps_odd_restart_ADC - ; Exit switch case - sjmp scheduler_exit +scheduler_steps_odd_debug1_frame: + ; ********************* [TELEMETRY] SEND DEBUG1 FRAME ***************** + cjne A, #3, scheduler_steps_odd_debug2_frame -scheduler_1024ms_switch_case_256ms: - cjne A, #8, scheduler_1024ms_switch_case_384ms + ; Stub for debug 1 + mov Ext_Telemetry_L, #088h ; Set telemetry low value + mov Ext_Telemetry_H, #08h ; Set telemetry high value to debug1 frame ID - ; Stub for debug 0 - mov Ext_Telemetry_L, #088h ; Set telemetry low value with temperature data - mov Ext_Telemetry_H, #08h ; Set telemetry high value on first repeated dshot coding partition + ; Now restart ADC conversion + sjmp scheduler_steps_odd_restart_ADC - sjmp scheduler_exit +scheduler_steps_odd_debug2_frame: + ; ********************* [TELEMETRY] SEND DEBUG2 FRAME ***************** + cjne A, #5, scheduler_steps_odd_temperature_frame -scheduler_1024ms_switch_case_384ms: - cjne A, #12, scheduler_1024ms_switch_case_512ms + ; Stub for debug 2 + mov Ext_Telemetry_L, #0AAh ; Set telemetry low value + mov Ext_Telemetry_H, #0Ah ; Set telemetry high value to debug2 frame ID + + ; Now restart ADC conversion + sjmp scheduler_steps_odd_restart_ADC + +scheduler_steps_odd_temperature_frame: + ; ********************* [TELEMETRY] SEND TEMPERATURE FRAME ***************** + cjne A, #7, scheduler_steps_odd_restart_ADC + + ; ****************************************************************** + ; Power rating only applies to BB21 because voltage references behave diferently + ; depending on an external voltage regulator is used or not. + ; For BB51 (MCU_TYPE == 2) 1s power rating code path is mandatory + ; ****************************************************************** +IF MCU_TYPE < 2 + mov Temp1, #Pgm_Power_Rating + cjne @Temp1, #01h, scheduler_steps_odd_temperature_frame_power_rating_2s +ENDIF - ; Stub for debug 1 - mov Ext_Telemetry_L, #0AAh ; Set telemetry low value with temperature data - mov Ext_Telemetry_H, #0Ah ; Set telemetry high value on first repeated dshot coding partition +scheduler_steps_odd_temperature_frame_power_rating_1s: + ; ****************************************************************** + ; ON BB51 and BB1, BB2 at 1S, all using internal 1.65V ADC reference + ; ****************************************************************** + mov A, ADC0H + jnz scheduler_steps_odd_temperature_frame_pr1s_temperature_above_0 + +scheduler_steps_odd_temperature_frame_pr1s_temperature_below_0: + ; If Hi Byte is not 0x01 we are definetly below 0, thus + ; clamp to 0. + clr A + sjmp scheduler_steps_odd_temperature_frame_temp_load + +scheduler_steps_odd_temperature_frame_pr1s_temperature_above_0: + ; Prepare extended telemetry temperature value for next telemetry transmission + ; On BB51 they hi byte is always 1 if the temperature is above 0ºC. + ; In fact the value is 0x0114 at 0ºC, thus we ignore the hi byte and normalize + ; the low byte to + mov A, ADC0L + subb A, #14h + sjmp scheduler_steps_odd_temperature_frame_temp_load + +scheduler_steps_odd_temperature_frame_power_rating_2s: + ; ***************************************************** + ; ON BB1, BB2 at more than 1S, using vdd V3.3 ADC reference + ; ***************************************************** + ; Prepare extended telemetry temperature value for next telemetry transmission + ; Check value above or below 20ºC - this is an approximation ADCOH having a value + ; of 0x01 equals to around 22.5ºC. + mov A, ADC0H + jnz scheduler_steps_odd_temperature_frame_pr2s_temperature_above_20 + +scheduler_steps_odd_temperature_frame_pr2s_temperature_below_20: + ; Value below 20ºC -> to code between 0-20 + mov A, ADC0L + clr C + subb A, #(255 - 20) + jnc scheduler_steps_odd_temperature_frame_temp_load + + ; Value below 0ºC -> clamp to 0 + clr A + sjmp scheduler_steps_odd_temperature_frame_temp_load + +scheduler_steps_odd_temperature_frame_pr2s_temperature_above_20: + ; Value above 20ºC -> to code between 20-255 + mov A, ADC0L ; This is an approximation: 9 ADC steps @10 Bit are 10 degrees + add A, #20 + +scheduler_steps_odd_temperature_frame_temp_load: + mov Ext_Telemetry_L, A ; Set telemetry low value with temperature data + mov Ext_Telemetry_H, #02h ; Set telemetry high value on first repeated dshot coding partition - sjmp scheduler_exit + ; Now restart ADC conversion -scheduler_1024ms_switch_case_512ms: - cjne A, #16, scheduler_exit +scheduler_steps_odd_restart_ADC: + ; ********************* START NEW ADC CONVERSION ***************** - ; Stub for debug 2 - mov Ext_Telemetry_L, #0CCh ; Set telemetry low value with temperature data - mov Ext_Telemetry_H, #0Ch ; Set telemetry high value on first repeated dshot coding partition + ; Start a new ADC conversion so after 64ms it will be ready for stage 2 og 128ms scheduler + Stop_Adc + Start_Adc - ; exit + ; Nothing else to do scheduler_exit: ret @@ -1951,7 +2018,7 @@ calc_next_comm_period: setb TMR2CN0_TR2 ; Timer2 enabled setb IE_EA -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 clr C ; Divide time by 2 on 48MHz rrca Temp3 rrca Temp2 @@ -1969,7 +2036,7 @@ ENDIF mov A, Temp2 subb A, Prev_Comm_H mov Prev_Comm_H, Temp2 ; Save timestamp as previous commutation -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 anl A, #7Fh ENDIF mov Temp2, A ; Store commutation period in Temp2 (hi byte) @@ -1993,7 +2060,7 @@ calc_next_comm_startup: subb A, Temp5 mov A, Temp3 subb A, Temp6 ; Calculate the new extended commutation time -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 anl A, #7Fh ENDIF jz calc_next_comm_startup_no_X @@ -2243,7 +2310,7 @@ calc_new_wait_times: clr A subb A, Temp4 mov Temp2, A -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 clr C rlca Temp1 ; Multiply by 2 rlca Temp2 @@ -2445,7 +2512,7 @@ setup_zc_scan_timeout: clr C rrca Temp2 rrca Temp1 -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 clr C rrca Temp2 rrca Temp1 @@ -2518,7 +2585,7 @@ comp_not_startup: ; Too high a value (~>35) causes the RCT4215 630 to run rough on full throttle mov Temp4, #(20 SHL IS_MCU_48MHZ) mov A, Comm_Period4x_H ; Set number of readings higher for lower speeds -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 clr C rrc A ENDIF @@ -2605,7 +2672,7 @@ comp_read_wrong_low_rpm: mov A, Comm_Period4x_H ; Set timeout to ~4x comm period 4x value mov Temp7, #0FFh ; Default to long timeout -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 clr C rlc A jc comp_read_wrong_load_timeout @@ -2698,9 +2765,13 @@ wait_for_comm: mov B, #7 mul AB ; Multiply by 7 - jnb Flag_Demag_Detected, ($+4) ; Add new value for current demag status + jnb Flag_Demag_Detected, wait_for_comm_demag_event_added + ; Add new value for current demag status inc B + ; Signal demag + setb Flag_Demag_Notify +wait_for_comm_demag_event_added: mov C, B.0 ; Divide by 8 rrc A mov C, B.1 @@ -2713,11 +2784,23 @@ wait_for_comm: jnc ($+5) mov Demag_Detected_Metric, #120 + ; Update demag metric max clr C - mov A, Demag_Detected_Metric ; Check demag metric + mov A, Demag_Detected_Metric + subb A, Demag_Detected_Metric_Max + jc wait_for_comm_demag_metric_max_updated + mov Demag_Detected_Metric_Max, Demag_Detected_Metric + +wait_for_comm_demag_metric_max_updated: + ; Check demag metric + clr C + mov A, Demag_Detected_Metric subb A, Demag_Pwr_Off_Thresh jc wait_for_comm_wait + ; Signal desync + setb Flag_Desync_Notify; + ; Cut power if many consecutive demags. This will help retain sync during hard accelerations All_Pwm_Fets_Off Set_All_Pwm_Phases_Off @@ -3068,21 +3151,20 @@ dshot_tlm_create_packet: mov A, Ext_Telemetry_H jnz dshot_tlm_ready - ; Read commutation period clr IE_EA - mov Tlm_Data_L, Comm_Period4x_L + mov A, Comm_Period4x_L ; Read commutation period mov Tlm_Data_H, Comm_Period4x_H setb IE_EA - ; Multiply period by 3/4 (1/2 + 1/4) - mov A, Tlm_Data_L + ; Calculate e-period (6 commutations) in microseconds + ; Comm_Period * 6 * 0.5 = Comm_Period4x * 3/4 (1/2 + 1/4) mov C, Tlm_Data_H.0 rrc A mov Temp2, A mov C, Tlm_Data_H.1 rrc A add A, Temp2 - mov Tlm_Data_L, A + mov Temp3, A ; Comm_Period3x_L mov A, Tlm_Data_H rr A @@ -3091,6 +3173,25 @@ dshot_tlm_create_packet: rr A clr ACC.7 addc A, Temp2 + mov Temp4, A ; Comm_Period3x_H + + ; Timer2 ticks are ~489ns (not 500ns), so use approximation for better accuracy: + ; E-period = Comm_Period3x - 4 * Comm_Period4x_H + + ; Note: For better performance assume Comm_Period4x_H < 64 (6-bit, above ~5k erpm) + ; At lower speed result will be less precise + mov A, Tlm_Data_H ; Comm_Period4x_H + rl A ; Multiply by 4 + rl A + anl A, #0FCh + mov Temp5, A + + clr C + mov A, Temp3 ; Comm_Period3x_L + subb A, Temp5 + mov Tlm_Data_L, A + mov A, Temp4 ; Comm_Period3x_H + subb A, #0 mov Tlm_Data_H, A dshot_tlm_ready: @@ -3444,9 +3545,11 @@ read_eeprom_block1: inc Temp1 djnz Temp4, read_eeprom_block1 + ; Read eeprom after Eep_Initialized_x flags + ; Temp4 = EEPROM_B2_PARAMETERS_COUNT parameters: [_Eep_Enable_TX_Program - Eep_Pgm_Power_Rating] mov DPTR, #_Eep_Enable_TX_Program mov Temp1, #_Pgm_Enable_TX_Program - mov Temp4, #26 ; 26 parameters + mov Temp4, #EEPROM_B2_PARAMETERS_COUNT read_eeprom_block2: call read_eeprom_byte inc DPTR @@ -3482,29 +3585,36 @@ erase_and_store_all_in_eeprom: mov A, #EEPROM_LAYOUT_REVISION call write_eeprom_byte_from_acc - ; Write eeprom + ; Write eeprom before Eep_Initialized_x flags + ; Temp4 = 10 parameters [_Eep_Pgm_Gov_P_Gain - Eep_Initialized_x] mov DPTR, #_Eep_Pgm_Gov_P_Gain mov Temp1, #_Pgm_Gov_P_Gain - mov Temp4, #10 ; 10 parameters + mov Temp4, #10 write_eeprom_block1: call write_eeprom_byte inc DPTR inc Temp1 djnz Temp4, write_eeprom_block1 + ; Write eeprom after Eep_Initialized_x flags + ; Temp4 = EEPROM_B2_PARAMETERS_COUNT parameters: [_Eep_Enable_TX_Program - Eep_Pgm_Power_Rating] mov DPTR, #_Eep_Enable_TX_Program mov Temp1, #_Pgm_Enable_TX_Program - mov Temp4, #26 ; 26 parameters + mov Temp4, #EEPROM_B2_PARAMETERS_COUNT write_eeprom_block2: call write_eeprom_byte inc DPTR inc Temp1 djnz Temp4, write_eeprom_block2 + ; Now write tags, melogy and signature call write_tags call write_melody call write_eeprom_signature mov DPTR, #Eep_Dummy ; Set pointer to uncritical area + + ; Give time to flash controller to settle data down + call wait200ms ret @@ -3539,7 +3649,7 @@ write_eeprom_byte_from_acc: mov Temp8, A clr C mov A, DPH ; Check that address is not in bootloader area - IF MCU_48MHZ == 2 + IF MCU_TYPE == 2 subb A, #0F0h ELSE subb A, #1Ch @@ -3723,6 +3833,7 @@ set_default_parameters: imov Temp1, #0FFh ; _Pgm_Pwm_Dither imov Temp1, #DEFAULT_PGM_BRAKE_ON_STOP ; Pgm_Brake_On_Stop imov Temp1, #DEFAULT_PGM_LED_CONTROL ; Pgm_LED_Control + imov Temp1, #DEFAULT_PGM_POWER_RATING ; Pgm_Power_Rating ret @@ -3778,14 +3889,33 @@ decode_demag_done: mov Temp_Prot_Limit, #0 mov Temp1, #Pgm_Enable_Temp_Prot mov A, @Temp1 - mov Temp1, A + mov Temp2, A ; Temp2 = *Pgm_Enable_Temp_Prot; jz decode_temp_done - mov A, #(TEMP_LIMIT-TEMP_LIMIT_STEP) + ; ****************************************************************** + ; Power rating only applies to BB21 because voltage references behave diferently + ; depending on an external voltage regulator is used or not. + ; For BB51 (MCU_TYPE == 2) 1s power rating code path is mandatory + ; ****************************************************************** +IF MCU_TYPE < 2 + ; Read power rating and decode temperature limit + mov Temp1, #Pgm_Power_Rating + cjne @Temp1, #01h, decode_temp_use_adc_use_vdd_3V3_vref +ENDIF + + ; Set A to temperature limit depending on power rating +decode_temp_use_adc_use_internal_1V65_vref: + mov A, #(TEMP_LIMIT_1S - TEMP_LIMIT_STEP) + sjmp decode_temp_step +decode_temp_use_adc_use_vdd_3V3_vref: + mov A, #(TEMP_LIMIT_2S - TEMP_LIMIT_STEP) + + ; Increase A while Temp2-- != 0; decode_temp_step: add A, #TEMP_LIMIT_STEP - djnz Temp1, decode_temp_step + djnz Temp2, decode_temp_step + ; Set Temp_Prot_Limit to the temperature limit calculated in A decode_temp_done: mov Temp_Prot_Limit, A @@ -3881,7 +4011,7 @@ pgm_start: mov WDTCN, #0DEh ; Disable watchdog (WDT) mov WDTCN, #0ADh mov SP, #Stack ; Initialize stack (16 bytes of indirect RAM) - IF MCU_48MHZ < 2 + IF MCU_TYPE < 2 orl VDM0CN, #080h ; Enable the VDD monitor ENDIF mov RSTSRC, #06h ; Set missing clock and VDD monitor as a reset source if not 1S capable @@ -3899,11 +4029,11 @@ pgm_start: mov P1, #P1_INIT mov P1SKIP, #P1_SKIP mov P2MDOUT, #P2_PUSHPULL -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 ; Not available on BB1 mov SFRPAGE, #20h mov P2MDIN, #P2_DIGITAL - IF MCU_48MHZ == 1 + IF MCU_TYPE == 1 ; Not available on BB51 mov P2SKIP, #P2_SKIP ENDIF @@ -3943,7 +4073,7 @@ init_no_signal: mov Flash_Key_2, #0 call switch_power_off -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 Set_MCU_Clk_24MHz ; Set clock frequency ENDIF @@ -3958,7 +4088,7 @@ input_high_check: call beep_enter_bootloader - IF MCU_48MHZ == 2 + IF MCU_TYPE == 2 ljmp 0F000h ; Jump to bootloader ELSE ljmp 1C00h ; Jump to bootloader @@ -3998,6 +4128,9 @@ setup_dshot: jnb Flag_Rcp_DShot_Inverted, ($+6) mov IT01CF, #(08h + (RTX_PIN SHL 4) + RTX_PIN) ; Route RCP input to Int0/1, with Int0 inverted + clr Flag_Demag_Notify ; Clear motor events + clr Flag_Desync_Notify + clr Flag_Stall_Notify clr Flag_Telemetry_Pending ; Clear DShot telemetry flag clr Flag_Ext_Tele ; Clear extended telemetry enabled flag @@ -4009,7 +4142,7 @@ setup_dshot: setb IE_EA ; Enable all interrupts ; Setup variables for DShot150 (Only on 24MHz because frame length threshold cannot be scaled up) -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 mov DShot_Timer_Preset, #-64 ; Load DShot sync timer preset (for DShot150) mov DShot_Pwm_Thr, #8 ; Load DShot qualification pwm threshold (for DShot150) mov DShot_Frame_Length_Thr, #160 ; Load DShot frame length criteria @@ -4039,7 +4172,7 @@ ENDIF jz arming_begin ; Setup variables for DShot600 (Only on 48MHz for performance reasons) -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 mov DShot_Timer_Preset, #-64 ; Load DShot sync timer preset (for DShot600) mov DShot_Pwm_Thr, #8 ; Load DShot pwm threshold (for DShot600) mov DShot_Frame_Length_Thr, #40 ; Load DShot frame length criteria @@ -4166,6 +4299,7 @@ motor_start: 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 @@ -4180,7 +4314,7 @@ motor_start: mov Temp_Pwm_Level_Setpoint, Pwm_Limit_Beg ; Begin startup sequence -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 Set_MCU_Clk_48MHz ; Scale DShot criteria for 48MHz @@ -4443,7 +4577,7 @@ exit_run_mode: mov Flags0, #0 ; Clear run time flags (in case they are used in interrupts) mov Flags1, #0 -IF MCU_48MHZ >= 1 +IF MCU_TYPE >= 1 Set_MCU_Clk_24MHz ; Scale DShot criteria for 24MHz @@ -4469,12 +4603,15 @@ ENDIF ; Check if RCP is zero, then it is a normal stop or signal timeout jb Flag_Rcp_Stop, exit_run_mode_no_stall + ; Signal stall + setb Flag_Stall_Notify + clr C ; Otherwise - it's a stall mov A, Startup_Stall_Cnt subb A, #4 ; Maximum consecutive stalls jnc exit_run_mode_stall_done - call wait100ms ; Wait for a bit between stall restarts + call wait100ms ; Wait for a bit between stall restarts ljmp motor_start ; Go back and try starting motors again exit_run_mode_stall_done: @@ -4508,7 +4645,7 @@ exit_run_mode_brake_done: ; as code flash after offset 1A00 is used for EEPROM storage ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** -IF MCU_48MHZ == 2 +IF MCU_TYPE == 2 CSEG AT 2FFDh ELSE CSEG AT 19FDh diff --git a/Common.inc b/Common.inc index bf773eb..d55cde6 100644 --- a/Common.inc +++ b/Common.inc @@ -29,11 +29,11 @@ ;********************* ; Device SiLabs EFM8BB1x/2x/51 ;********************* -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 $include (Silabs/SI_EFM8BB1_Defs.inc) -ELSEIF MCU_48MHZ == 1 +ELSEIF MCU_TYPE == 1 $include (Silabs/SI_EFM8BB2_Defs.inc) -ELSEIF MCU_48MHZ == 2 +ELSEIF MCU_TYPE == 2 $include (Silabs/SI_EFM8BB51_Defs.inc) ENDIF @@ -43,7 +43,7 @@ ENDIF ;**** **** **** **** **** ; ESC selection statements -IF MCU_48MHZ < 2 +IF MCU_TYPE < 2 IF ESCNO == A_ $include (Layouts/A.inc) ; Select pinout A ELSEIF ESCNO == B_ @@ -99,7 +99,7 @@ IF MCU_48MHZ < 2 ENDIF ENDIF -IF MCU_48MHZ == 2 +IF MCU_TYPE == 2 IF ESCNO == A_ $include (Layouts/BB51/A.inc) ; Select pinout A ELSEIF ESCNO == B_ @@ -110,11 +110,11 @@ IF MCU_48MHZ == 2 ENDIF SIGNATURE_001 EQU 0E8h ; Device signature -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 SIGNATURE_002 EQU 0B1h -ELSEIF MCU_48MHZ == 1 +ELSEIF MCU_TYPE == 1 SIGNATURE_002 EQU 0B2h -ELSEIF MCU_48MHZ == 2 +ELSEIF MCU_TYPE == 2 SIGNATURE_002 EQU 0B5h ENDIF @@ -124,11 +124,11 @@ ENDIF ESC_C EQU "A" + ESCNO - 1 ; ESC target letter ; MCU letter (24Mhz=L, 48Mhz=H, BB51=X) -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 MCU_C EQU "L" -ELSEIF MCU_48MHZ == 1 +ELSEIF MCU_TYPE == 1 MCU_C EQU "H" -ELSEIF MCU_48MHZ == 2 +ELSEIF MCU_TYPE == 2 MCU_C EQU "X" ENDIF ENDIF @@ -139,9 +139,9 @@ DT_C1 EQU "0" + ((DEADTIME / 10) MOD 10) DT_C0 EQU "0" + (DEADTIME MOD 10) ; ESC layout tag -IF MCU_48MHZ < 2 +IF MCU_TYPE < 2 CSEG AT 1A40h -ELSEIF MCU_48MHZ == 2 +ELSEIF MCU_TYPE == 2 CSEG AT 3040h ENDIF @@ -151,18 +151,18 @@ ELSE Eep_ESC_Layout: DB "#", ESC_C, "_", MCU_C, "_", DT_C2, DT_C1, DT_C0, "# " ENDIF -IF MCU_48MHZ < 2 +IF MCU_TYPE < 2 CSEG AT 1A50h -ELSEIF MCU_48MHZ == 2 +ELSEIF MCU_TYPE == 2 CSEG AT 3050h ENDIF ; Project and MCU tag (16 Bytes) -IF MCU_48MHZ == 0 +IF MCU_TYPE == 0 Eep_ESC_MCU: DB "#BLHELI$EFM8B10#" -ELSEIF MCU_48MHZ == 1 +ELSEIF MCU_TYPE == 1 Eep_ESC_MCU: DB "#BLHELI$EFM8B21#" -ELSEIF MCU_48MHZ == 2 +ELSEIF MCU_TYPE == 2 Eep_ESC_MCU: DB "#BLHELI$EFM8B51#" ENDIF @@ -208,9 +208,9 @@ ENDM Set_MCU_Clk_48MHz MACRO mov SFRPAGE, #10h - IF MCU_48MHZ == 1 + IF MCU_TYPE == 1 mov PFE0CN, #30h ;; Set flash timing for 48MHz and enable prefetch engine - ELSEIF MCU_48MHZ == 2 + ELSEIF MCU_TYPE == 2 mov PFE0CN, #10h ;; Set flash timing for 48MHz ENDIF mov SFRPAGE, #00h diff --git a/Layouts/Base.inc b/Layouts/Base.inc index 2eb9cad..8c411ca 100644 --- a/Layouts/Base.inc +++ b/Layouts/Base.inc @@ -120,41 +120,41 @@ ENDIF Initialize_Comparator MACRO mov CMP_CN0, #80h ;; Comparator enabled, no hysteresis mov CMP_MD, #00h ;; Comparator response time 100ns -IF COMPARATOR_INVERT == 1 AND MCU_48MHZ >= 1 +IF COMPARATOR_INVERT == 1 AND MCU_TYPE >= 1 mov CMP_MD, #40h ;; Output polarity inverted (Only supported on BB2 and BB51) ENDIF ENDM Read_Comparator_Output MACRO mov A, CMP_CN0 ;; Read comparator output -IF COMPARATOR_INVERT == 1 AND MCU_48MHZ == 0 +IF COMPARATOR_INVERT == 1 AND MCU_TYPE == 0 cpl A ;; Invert output polarity manually on BB1 ENDIF ENDM ; Set comparator multiplexer to phase A Set_Comparator_Phase_A MACRO - IF MCU_48MHZ < 2 + IF MCU_TYPE < 2 mov CMP_MX, #((A_Mux SHL 4) + V_Mux) - ELSEIF MCU_48MHZ == 2 + ELSEIF MCU_TYPE == 2 mov CMP_MX, #12h ENDIF ENDM ; Set comparator multiplexer to phase B Set_Comparator_Phase_B MACRO - IF MCU_48MHZ < 2 + IF MCU_TYPE < 2 mov CMP_MX, #((B_Mux SHL 4) + V_Mux) - ELSEIF MCU_48MHZ == 2 + ELSEIF MCU_TYPE == 2 mov CMP_MX, #10h ENDIF ENDM ; Set comparator multiplexer to phase C Set_Comparator_Phase_C MACRO - IF MCU_48MHZ < 2 + IF MCU_TYPE < 2 mov CMP_MX, #((C_Mux SHL 4) + V_Mux) - ELSEIF MCU_48MHZ == 2 + ELSEIF MCU_TYPE == 2 mov CMP_MX, #11h ENDIF ENDM @@ -328,43 +328,50 @@ $endif ; ADC and temperature measurement ;**** **** **** **** **** ; Temperature measurement ADC value for which main motor power is limited at 80degC (low byte, assuming high byte is 1) -IF MCU_48MHZ < 2 - TEMP_LIMIT EQU 49 -ELSEIF MCU_48MHZ == 2 - TEMP_LIMIT EQU 92 ; 0degC is on the BB51 at 0x0114 so ((92 - 20) / 9 * 10) = 80degC -ENDIF +TEMP_LIMIT_2S EQU 49 ; When using vdd 3.3V reference +TEMP_LIMIT_1S EQU 92 ; When using 1.65V internal reference TEMP_LIMIT_STEP EQU 9 ; Temperature measurement ADC value increment for another 10degC Initialize_Adc MACRO - IF MCU_48MHZ < 2 - mov REF0CN, #0Ch ;; Set vdd (3.3V) as reference. Enable temp sensor and bias - IF MCU_48MHZ == 0 - mov ADC0CF, #59h ;; ADC clock 2MHz, PGA gain 1 - ELSEIF MCU_48MHZ == 1 - mov ADC0CF, #0B9h ;; ADC clock 2MHz, PGA gain 1 - ENDIF - ELSEIF MCU_48MHZ == 2 - mov CLKGRP0, #18h ;; Enable SAR clock, at 12MHz - mov ADC0CF1, #0Ah ;; 800ns tracking time - mov ADC0CF2, #2Fh ;; 1.65V reference - ENDIF +LOCAL initialize_adc_use_internal_1V65_vref initialize_adc_use_vdd_3V3_vref initialize_adc_vref_selected +IF MCU_TYPE < 2 + mov Temp1, #Pgm_Power_Rating + cjne @Temp1, #01h, initialize_adc_use_vdd_3V3_vref + +initialize_adc_use_internal_1V65_vref: + mov REF0CN, #1Ch ;; Set internal 1.65V as reference on 1S. Enable temp sensor and bias + sjmp initialize_adc_vref_selected +initialize_adc_use_vdd_3V3_vref: + mov REF0CN, #0Ch ;; Set vdd (3.3V) as reference on 2S+. Enable temp sensor and bias + +initialize_adc_vref_selected: + IF MCU_TYPE == 0 + mov ADC0CF, #59h ;; ADC clock 2MHz, PGA gain 1 + ELSEIF MCU_TYPE == 1 + mov ADC0CF, #0B9h ;; ADC clock 2MHz, PGA gain 1 + ENDIF +ELSEIF MCU_TYPE == 2 + mov CLKGRP0, #18h ;; Enable SAR clock, at 12MHz + mov ADC0CF1, #0Ah ;; 800ns tracking time + mov ADC0CF2, #2Fh ;; 1.65V reference +ENDIF - mov ADC0MX, #10h ;; Select temp sensor input - IF MCU_48MHZ < 2 - mov ADC0CN0, #80h ;; ADC enabled - mov ADC0CN1, #01h ;; Common mode buffer enabled - ELSEIF MCU_48MHZ == 2 - mov ADC0CN0, #85h ;; ADC enabled (gain 0.5, temp sensor enabled) - mov ADC0CN1, #20h ;; 10bit mode - ENDIF + mov ADC0MX, #10h ;; Select temp sensor input +IF MCU_TYPE < 2 + mov ADC0CN0, #80h ;; ADC enabled + mov ADC0CN1, #01h ;; Common mode buffer enabled +ELSEIF MCU_TYPE == 2 + mov ADC0CN0, #85h ;; ADC enabled (gain 0.5, temp sensor enabled) + mov ADC0CN1, #20h ;; 10bit mode +ENDIF ENDM Start_Adc MACRO - IF MCU_48MHZ < 2 - mov ADC0CN0, #90h ;; Initiate conversion - ELSEIF MCU_48MHZ == 2 - mov ADC0CN0, #95h ;; Initiate conversion (gain 0.5, temp sensor enabled) - ENDIF +IF MCU_TYPE < 2 + mov ADC0CN0, #90h ;; Initiate conversion +ELSEIF MCU_TYPE == 2 + mov ADC0CN0, #95h ;; Initiate conversion (gain 0.5, temp sensor enabled) +ENDIF ENDM Stop_Adc MACRO diff --git a/Makefile b/Makefile index a10548b..19a77b3 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ VERSION ?= $(TAG) # Target parameters LAYOUTS = A B C D E F G H I J K L M N O P Q R S T U V W Z -MCUS = H L +MCUS = H LAYOUTS_X = A B C MCUS_X = X DEADTIMES = 0 5 10 15 20 25 30 40 50 70 90 120 @@ -63,7 +63,7 @@ $(OUTPUT_DIR)/$(1)_$(2)_$(3)_$(4)_$(VERSION).OBJ : $(ASM_SRC) $(ASM_INC) $(eval _ESC := $(1)) $(eval _ESC_INT := $(shell printf "%d" "'${_ESC}")) $(eval _ESCNO := $(shell echo $$(( $(_ESC_INT) - 65 + 1)))) - $(eval _MCU_48MHZ := $(subst L,0,$(subst H,1,$(subst X,2,$(2))))) + $(eval _MCU_TYPE := $(subst L,0,$(subst H,1,$(subst X,2,$(2))))) $(eval _DEADTIME := $(3)) $(eval _PWM_FREQ := $(subst 24,0,$(subst 48,1,$(subst 96,2,$(4))))) $$(eval _LST := $$(patsubst %.OBJ,%.LST,$$@)) @@ -71,7 +71,7 @@ $(OUTPUT_DIR)/$(1)_$(2)_$(3)_$(4)_$(VERSION).OBJ : $(ASM_SRC) $(ASM_INC) @echo "AX51 : $$@" @$(AX51) $(ASM_SRC) \ "DEFINE(ESCNO=$(_ESCNO)) " \ - "DEFINE(MCU_48MHZ=$(_MCU_48MHZ)) "\ + "DEFINE(MCU_TYPE=$(_MCU_TYPE)) "\ "DEFINE(DEADTIME=$(_DEADTIME)) "\ "DEFINE(PWM_FREQ=$(_PWM_FREQ)) "\ "OBJECT($$@) "\ diff --git a/README.md b/README.md index 40f3bc4..871771e 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ Bluejay aims to be an open source successor to BLHeli_S adding several improveme ## Current Features -- Digital signal protocol: DShot 150, 300 and 600 -- Bidirectional DShot: RPM telemetry +- Digital signal protocol: DShot 300 and 600 +- Bidirectional DShot: RPM telemetry and [extended DSHOT telemetry](https://github.com/bird-sanctuary/extended-dshot-telemetry) - Selectable PWM frequency: 24, 48 and 96 kHz - PWM dithering: 11-bit effective throttle resolution - Power configuration: Startup power and RPM protection @@ -25,6 +25,15 @@ Bluejay aims to be an open source successor to BLHeli_S adding several improveme See the project [changelog](CHANGELOG.md) for a list of changes. +## Supported Platforms +- SiLabs EFM8 BB21 +- SiLabs EFM8 BB51 + +### Deprecated Platforms +The `SiLabs EFM8 BB10` has been deprecated. The last official release is [0.18.1](https://github.com/bird-sanctuary/bluejay/releases/tag/v0.18.1). The BB10 has it's limitations in comparison to the BB21 and BB51. Not many of those seem to be around anymore and the team does not have a single one for testing, thus decided to drop support. + +> You will still be able to manually build for it, but we can not guarantee compatibility and do not want to suffer from it's limitations during further development. + ## Flashing ESCs Bluejay firmware can be flashed to BLHeli_S compatible ESCs and configured using the following configurator tools: diff --git a/tools/build.sh b/tools/build.sh index aa4e2c9..802e1ad 100755 --- a/tools/build.sh +++ b/tools/build.sh @@ -2,7 +2,7 @@ source_path=$(dirname $(pwd)) usage() { - echo "Usage: $0 [-l ] [-m ] [-d ] [-p <24|48|96>]" 1>&2 + echo "Usage: $0 [-l ] [-m ] [-d ] [-p <24|48|96>]" 1>&2 exit 1 }