diff --git a/src/Bluejay.asm b/src/Bluejay.asm index 0d6b4dc..8e065c9 100644 --- a/src/Bluejay.asm +++ b/src/Bluejay.asm @@ -468,7 +468,26 @@ ENDIF Initialize_Crossbar ; Initialize the crossbar and related functionality call switch_power_off ; Switch power off again,after initializing ports - ; Clear RAM +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Internal RAM +; +; EFM8 consists of 256 bytes of internal RAM of which the lower 128 bytes can be +; directly adressed and the upper portion (starting at 0x80) can only be +; indirectly accessed. +; +; NOTE: Upper portion of RAM and SFR use the same address space. RAM is accessed +; indirectly. If you are directly accessing the upper space, you are - in +; fact - addressing the SFR. +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Clear internal RAM +; +; First the accumlator is cleared, then address is overflowed to 255 and content +; of addresses 255 - 0 is set to 0. +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** clr A ; Clear accumulator mov Temp1, A ; Clear Temp1 clear_ram: @@ -496,14 +515,17 @@ init_no_signal: call switch_power_off IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 - Set_MCU_Clk_24MHz ; Set clock frequency + ; While not armed, all MCUs run at 24MHz clock frequency. After arming those + ; MCUs that support it (BB2 & BB51) are switched to 48MHz clock frequency. + Set_MCU_Clk_24MHz ENDIF - mov Temp1, #9 ; Check if input signal is high for ~150ms + ; If input signal is high for about ~150ms, enter bootloader mode + mov Temp1, #9 mov Temp2, #0 mov Temp3, #0 input_high_check: - jnb RTX_BIT, bootloader_done ; Look for low + jnb RTX_BIT, bootloader_done ; If low is detected, skip bootloader check djnz Temp3, input_high_check djnz Temp2, input_high_check djnz Temp1, input_high_check @@ -513,9 +535,14 @@ input_high_check: ljmp CSEG_BOOT_START ; Jump to bootloader bootloader_done: - jnb Flag_Had_Signal, setup_dshot ; Check if DShot signal was lost + ; If we had a signal before, reset the flag, beep, wait a bit and contiune + ; with DSHOT setup. If we did not have a signal yet, continue with DSHOT + ; setup straight away. + jnb Flag_Had_Signal, setup_dshot call beep_signal_lost - call wait250ms ; Wait for flight controller to get ready + + ; Wait for flight controller to get ready + call wait250ms call wait250ms call wait250ms clr Flag_Had_Signal @@ -584,7 +611,7 @@ ENDIF Set_DShot_Tlm_Bitrate 375000 ; = 5/4 * 300000 - ; Test whether signal is DShot300 + ; Test whether signal is DShot300, if so begin arming mov Rcp_Outside_Range_Cnt, #10 ; Set out of range counter call wait100ms ; Wait for new RC pulse mov A, Rcp_Outside_Range_Cnt ; Check if pulses were accepted @@ -598,13 +625,14 @@ IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 Set_DShot_Tlm_Bitrate 750000 ; = 5/4 * 600000 - ; Test whether signal is DShot600 + ; Test whether signal is DShot600, if so begin arming mov Rcp_Outside_Range_Cnt, #10 ; Set out of range counter call wait100ms ; Wait for new RC pulse mov A, Rcp_Outside_Range_Cnt ; Check if pulses were accepted jz arming_begin ENDIF + ; No valid signal detected, try again ljmp init_no_signal arming_begin: @@ -617,20 +645,22 @@ arming_begin: mov Startup_Stall_Cnt, #0 ; Reset stall count clr IE_EA - call beep_f1_short ; Beep signal that RC pulse is ready + call beep_f1_short ; Confirm RC pulse detection by beeping setb IE_EA +; Make sure RC pulse has been zero for ~300ms arming_wait: clr C mov A, Rcp_Stop_Cnt subb A, #10 - jc arming_wait ; Wait until rcp has been zero for ~300ms + jc arming_wait clr IE_EA - call beep_f2_short ; Beep signal that ESC is armed + call beep_f2_short ; Confirm arm state by beeping setb IE_EA -wait_for_start: ; Armed and waiting for power on +; Armed and waiting for power on (RC pulse > 0) +wait_for_start: clr A mov Comm_Period4x_L, A ; Reset commutation period for telemetry mov Comm_Period4x_H, A @@ -688,7 +718,8 @@ wait_for_start_no_beep: call scheduler_run wait_for_start_check_rcp: - jnb Flag_Rcp_Stop, wait_for_start_nonzero ; Higher than stop,Yes - proceed + ; If RC pulse is higher than stop (>0) then proceed to start the motor + jnb Flag_Rcp_Stop, wait_for_start_nonzero mov A, Rcp_Timeout_Cntd ; Load RC pulse timeout counter value ljz init_no_signal ; If pulses are missing - go back to detect input signal @@ -700,7 +731,7 @@ wait_for_start_check_rcp: wait_for_start_nonzero: call wait100ms ; Wait to see if start pulse was glitch - ; If Rcp returned to stop - start over + ; If RC pulse returned to stop (0) - start over jb Flag_Rcp_Stop, wait_for_start_loop ; If no safety arm jump to motor start @@ -747,7 +778,7 @@ motor_start: ; Begin startup sequence IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 - Set_MCU_Clk_48MHz + Set_MCU_Clk_48MHz ; Enable 48MHz clock frequency ; Scale DShot criteria for 48MHz clr C @@ -990,7 +1021,8 @@ run6_bidir_continue: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Exit run mode and power off -; on normal stop or comparator timeout +; +; Happens on normal stop (RC pulse == 0) or comparator timeout ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** exit_run_mode_on_timeout: diff --git a/src/Modules/Common.asm b/src/Modules/Common.asm index 77e2350..29c02ce 100644 --- a/src/Modules/Common.asm +++ b/src/Modules/Common.asm @@ -28,7 +28,11 @@ ;**** **** **** **** **** **** **** **** **** **** **** **** **** ;**** **** **** **** **** **** **** **** **** **** **** **** **** +; ; Device SiLabs EFM8BB1x/2x/51 +; +; Include defines provided by SiLabs depending on target platform. +; ;**** **** **** **** **** **** **** **** **** **** **** **** **** IF MCU_TYPE == MCU_BB1 $include (Silabs/SI_EFM8BB1_Defs.inc) @@ -134,7 +138,8 @@ ELSEIF ESCNO == C_ ENDIF ENDIF -SIGNATURE_001 EQU 0E8h ; Device signature +; Build device signature based on target platform: 0xE8, [0xB1 | 0xB2 | 0xB5] +SIGNATURE_001 EQU 0E8h IF MCU_TYPE == MCU_BB1 SIGNATURE_002 EQU 0B1h ELSEIF MCU_TYPE == MCU_BB2 diff --git a/src/Modules/Commutation.asm b/src/Modules/Commutation.asm index 7140329..90f867e 100644 --- a/src/Modules/Commutation.asm +++ b/src/Modules/Commutation.asm @@ -25,14 +25,37 @@ ; ; Commutation ; -;**** **** **** **** **** **** **** **** **** **** **** **** **** - -;**** **** **** **** **** **** **** **** **** **** **** **** **** +; Performs 6-step commutation switching. +; +; In 6-step commutation switching a full rotation is segregated in 6 sectors. +; Every sectors is 60 degrees (6 * 60 = 360), thus 6 steps are needed to +; complete one full rotation. +; +; Non reversed switching (PWM, non inverted shown here). The diagram shows two +; full commutation runs: +; +; 123456123456 +; A __/‾‾\__/‾‾\ +; +; B /‾‾\__/‾‾\__ +; +; C ‾\__/‾‾\__/‾ ; -; Commutation routines +; The followind table shows the states of the FETs for all phases including +; complementary states: ; -; Performs commutation switching +; Step AA' BB' CC' +; 1 C->A 01 00 10 +; 2 B->A 01 10 00 +; 3 B->C 00 10 01 +; 4 A->C 10 00 01 +; 5 A->B 10 01 00 +; 6 C->B 00 01 10 ; +; NOTE: Every step has a "reverse" step which is used in bi-directional mode +; where the motor is allowed to spin in both directions. Depending on the +; current RC pulse the motor is commutated either in "normal" direction +; or in "reverse". ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; Comm phase 1 to comm phase 2 diff --git a/src/Modules/DShot.asm b/src/Modules/DShot.asm index 2b116bf..0001b0d 100644 --- a/src/Modules/DShot.asm +++ b/src/Modules/DShot.asm @@ -29,9 +29,10 @@ ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; -; Detect DShot RCP level +; Detect DShot RC pulse level ; -; Determine if RCP signal level is normal or inverted DShot +; Determine if RC pulse signal level is normal or inverted DShot. If inverted +; DShot - we are using ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** detect_rcp_level: @@ -56,7 +57,23 @@ detect_rcp_level_check_loop: ; ; Check DShot command ; -; Determine received DShot command and perform action +; Determine received DShot command and perform action if DShot command is not +; zero: +; +; 1-5: Beacon beep +; +; All following commands need to be received 6 times in a row before action is +; taken: +; +; 7: Set motor direction to normal +; 8: Set motor direction to reverse +; 9: Disable 3D mode +; 10: Enable 3D mode +; 12: Save settings +; 13: Enable EDT (Extended DShot Telemetry) +; 14: Disable EDT (Extended DShot Telemetry) +; 20: Set motor direction to user programmed direction +; 21: Set motor direction to reversed user programmed direction ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** dshot_cmd_check: @@ -105,6 +122,7 @@ dshot_cmd_direction_bidir_off: ; Set motor control mode to normal (not bidirectional) cjne Temp1, #CMD_BIDIR_OFF, dshot_cmd_direction_bidir_on + ; 9: Set motor control mode to normal (not bidirectional) clr Flag_Pgm_Bidir sjmp dshot_cmd_exit @@ -191,8 +209,8 @@ dshot_cmd_save_settings: setb IE_EA dshot_cmd_exit: - mov DShot_Cmd, #0 ; Clear DShot command and exit - mov DShot_Cmd_Cnt, #0 + mov DShot_Cmd, #0 ; Clear DShot command + mov DShot_Cmd_Cnt, #0 ; Clear Dshot command counter dshot_cmd_exit_no_clear: ret @@ -244,11 +262,13 @@ dshot_tlm_create_packet: addc A, Temp2 mov Temp4, A ; Comm_Period3x_H - ; Timer2 ticks are ~489ns (not 500ns), so use approximation for better accuracy: + ; Timer2 ticks are ~489ns (not 500ns) - 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 + ; 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 @@ -334,7 +354,7 @@ dshot_tlm_12bit_encoded: ; Encodes 16-bit e-period as a 12-bit value of the form: ; where M SHL E ~ e-period [us] ; -; Note: Not callable to improve performance +; NOTE: Not callable to improve performance ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** dshot_12bit_encode: @@ -429,6 +449,7 @@ dshot_12bit_1: ; - Temp1: Data pointer for storing pulse timings ; - A: 4-bit value to GCR encode ; - B: Time that must be added to transition +; ; Output ; - B: Time remaining to be added to next transition ; diff --git a/src/Modules/Eeprom.asm b/src/Modules/Eeprom.asm index 36a2671..d99925f 100644 --- a/src/Modules/Eeprom.asm +++ b/src/Modules/Eeprom.asm @@ -1,4 +1,4 @@ -;**** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Bluejay digital ESC firmware for controlling brushless motors in multirotors ; @@ -25,6 +25,11 @@ ; ; ESC programming (EEPROM emulation) ; +; The BB EFM8 technically does not have a dedicated EEPROM but in Bluejay a +; part of the flash space is dedicated to emulate an EEPROM. This is the space +; that holds all the settings and is what the configurator reads/writes ( via +; the bootloader). +; ;**** **** **** **** **** **** **** **** **** **** **** **** **** ESC_LAYOUT_SIZE EQU 48 @@ -32,9 +37,7 @@ MELODY_SIZE EQU 140 ;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Read all eeprom parameters -; +; Read all "EEPROM" parameters ;**** **** **** **** **** **** **** **** **** **** **** **** **** read_all_eeprom_parameters: ; Check initialized signature @@ -57,52 +60,56 @@ read_eeprom_store_defaults: sjmp read_eeprom_exit read_eeprom_read: - ; Read eeprom + ; Read "EEPROM" mov DPTR, #_Eep_Pgm_Gov_P_Gain mov Temp1, #_Pgm_Gov_P_Gain mov Temp4, #10 ; 10 parameters + read_eeprom_block1: call read_eeprom_byte inc DPTR inc Temp1 djnz Temp4, read_eeprom_block1 - ; Read eeprom after Eep_Initialized_x flags + ; 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, #EEPROM_B2_PARAMETERS_COUNT + read_eeprom_block2: call read_eeprom_byte inc DPTR inc Temp1 djnz Temp4, read_eeprom_block2 - mov DPTR, #Eep_Dummy ; Set pointer to uncritical area + ; Set pointer to uncritical area + mov DPTR, #Eep_Dummy read_eeprom_exit: ret ;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Erase flash and store all parameter values in EEPROM -; +; Erase flash and store all parameter values in "EEPROM" ;**** **** **** **** **** **** **** **** **** **** **** **** **** erase_and_store_all_in_eeprom: clr IE_EA ; Disable interrupts call read_esc_layout call read_melody - call erase_flash ; Erase flash + call erase_flash - mov DPTR, #Eep_FW_Main_Revision ; Store firmware main revision + ; Store firmware main revision + mov DPTR, #Eep_FW_Main_Revision mov A, #EEPROM_FW_MAIN_REVISION call write_eeprom_byte_from_acc - inc DPTR ; Now firmware sub revision + ; Store firmware sub revision + inc DPTR mov A, #EEPROM_FW_SUB_REVISION call write_eeprom_byte_from_acc - inc DPTR ; Now layout revision + ; Store layout revision + inc DPTR mov A, #EEPROM_LAYOUT_REVISION call write_eeprom_byte_from_acc @@ -111,6 +118,7 @@ erase_and_store_all_in_eeprom: mov DPTR, #_Eep_Pgm_Gov_P_Gain mov Temp1, #_Pgm_Gov_P_Gain mov Temp4, #10 + write_eeprom_block1: call write_eeprom_byte inc DPTR @@ -122,6 +130,7 @@ write_eeprom_block1: mov DPTR, #_Eep_Enable_TX_Program mov Temp1, #_Pgm_Enable_TX_Program mov Temp4, #EEPROM_B2_PARAMETERS_COUNT + write_eeprom_block2: call write_eeprom_byte inc DPTR @@ -132,9 +141,11 @@ write_eeprom_block2: call write_esc_layout 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 + ; Set pointer to uncritical area + mov DPTR, #Eep_Dummy + + ; Allow the flash controller to settle data down call wait200ms ret @@ -142,8 +153,9 @@ write_eeprom_block2: ; ; Read eeprom byte ; -; Gives data in A and in address given by Temp1 -; Assumes address in DPTR +; ASSERT: +; - Target address in DPTR +; - Destination address in Temp1 ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** read_eeprom_byte: @@ -156,12 +168,15 @@ read_eeprom_byte: ; ; Write eeprom byte ; -; Assumes data in address given by Temp1, or in accumulator -; Assumes address in DPTR +; ASSERT: +; - Data in address given by Temp1 +; - Destination address in DPTR ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** write_eeprom_byte: mov A, @Temp1 + +; Shorthand if data is already in accumulator write_eeprom_byte_from_acc: orl PSCTL, #01h ; Set the PSWE bit anl PSCTL, #0FDh ; Clear the PSEE bit @@ -174,8 +189,11 @@ write_eeprom_byte_from_acc: write_eeprom_byte_write: mov A, Temp8 + + ; Attempt to unlock flash mov FLKEY, Flash_Key_1 ; First key code mov FLKEY, Flash_Key_2 ; Second key code + movx @DPTR, A ; Write to flash anl PSCTL, #0FEh ; Clear the PSWE bit ret @@ -186,8 +204,11 @@ write_eeprom_byte_write: erase_flash: orl PSCTL, #02h ; Set the PSEE bit orl PSCTL, #01h ; Set the PSWE bit + + ; Attempt to unlock flash mov FLKEY, Flash_Key_1 ; First key code mov FLKEY, Flash_Key_2 ; Second key code + mov DPTR, #Eep_Initialized_L movx @DPTR, A anl PSCTL, #0FCh ; Clear the PSEE and PSWE bits @@ -240,8 +261,10 @@ write_esc_layout_byte: ret ;**** **** **** **** **** **** **** **** **** **** **** **** **** -; Read bytes from flash and store in external memory +; Melody ;**** **** **** **** **** **** **** **** **** **** **** **** **** + +; Read 140 bytes from "EEPROM" and store in external memory (XRAM) read_melody: mov Temp3, #MELODY_SIZE ; Number of bytes mov Temp2, #0 ; Set XRAM address @@ -256,9 +279,7 @@ read_melody_byte: djnz Temp3, read_melody_byte ret -;**** **** **** **** **** **** **** **** **** **** **** **** **** -; Write bytes from external memory and store in flash -;**** **** **** **** **** **** **** **** **** **** **** **** **** +; Read 140 bytes from external memory (XRAM) and store them in "EEPROM" write_melody: mov Temp3, #MELODY_SIZE ; Number of bytes mov Temp2, #0 ; Set XRAM address diff --git a/src/Modules/Fx.asm b/src/Modules/Fx.asm index ddf4be5..4cba883 100644 --- a/src/Modules/Fx.asm +++ b/src/Modules/Fx.asm @@ -1,4 +1,5 @@ -;**** **** **** **** **** + +;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Bluejay digital ESC firmware for controlling brushless motors in multirotors ; @@ -22,12 +23,10 @@ ; along with Bluejay. If not, see . ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** -;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Misc utility functions ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** -;**** **** **** **** **** **** **** **** **** **** **** **** **** ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; @@ -90,7 +89,8 @@ wait_ms_start: ; ; Beeper routines (Multiple entry points) ; -; Requirements: Interrupts must be disabled and FETs turned off +; Requirements: +; - Interrupts must be disabled and FETs turned off ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** beep_f1: @@ -210,10 +210,12 @@ beep_safety_no_arm: ; ; Beacon beep ; -; Beep with beacon strength -; Beep tone 1-5 in Temp1 +; Beep with beacon strength. ; -; Requirements: Interrupts must be disabled and FETs turned off +; Requirements: +; - Interrupts must be disabled +; - FETs must be turned off +; - Beep tone 1-5 in Temp1 ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** beacon_beep: @@ -255,10 +257,14 @@ beacon_beep_exit: ; ; A melody has 64 pairs of (item1, item2) - a total of 128 items. ; the first 4 values of the 128 items are metadata -; item2 - is the duration of each pulse of the musical note, lower the value, higher the pitch -; item1 - if item2 is zero, it is the number of milliseconds of wait time, else it is the number of pulses of item2 +; item2 - is the duration of each pulse of the musical note. +; The lower the value, the higher the pitch. +; item1 - if item2 is zero, it is the number of milliseconds of wait time, else +; it is the number of pulses of item2. ; -; Requirements: Interrupts must be disabled and FETs turned off +; Requirements: +; - Interrupts must be disabled +; - FETs must be turned off ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** play_beep_melody: diff --git a/src/Modules/Isrs.asm b/src/Modules/Isrs.asm index cd43664..e1ad05a 100644 --- a/src/Modules/Isrs.asm +++ b/src/Modules/Isrs.asm @@ -1,4 +1,4 @@ -;**** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Bluejay digital ESC firmware for controlling brushless motors in multirotors ; @@ -33,7 +33,7 @@ ; ; Generate DShot telemetry signal ; -; Requirements: +; ASSERT: ; - Must NOT be called while Flag_Telemetry_Pending is cleared ; - Must NOT write to Temp7, Temp8 ; @@ -43,7 +43,7 @@ t0_int: mov PSW, #10h ; Select register bank 2 for this interrupt dec Temp1 - cjne Temp1, #(Temp_Storage - 1),t0_int_dshot_tlm_transition + cjne Temp1, #(Temp_Storage - 1), t0_int_dshot_tlm_transition inc Temp1 ; Set pointer to uncritical position @@ -85,9 +85,13 @@ t0_int_dshot_tlm_finish: ; ; Timer1 interrupt routine ; -; Decode DShot frame -; Process new throttle value and update pwm registers -; Schedule DShot telemetry +; Tasks: +; - Decode DShot frame +; - Process new throttle value and update PWM registers +; - Schedule DShot telemetry +; +; NOTE: The ISR should be left as soon as possible. Instead of using loops, +; often times more codespace is used since it saves valuable time. ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** t1_int: @@ -100,8 +104,8 @@ t1_int: push ACC push B - ; Note: Interrupts are not explicitly disabled - ; Assume higher priority interrupts (Int0, Timer0) to be disabled at this point + ; NOTE: Interrupts are not explicitly disabled. Assume higher priority + ; interrupts (Int0, Timer0) to be disabled at this point. clr TMR2CN0_TR2 ; Timer2 disabled mov Temp2, TMR2L ; Read timer value mov Temp3, TMR2H @@ -123,7 +127,7 @@ t1_int: subb A, DShot_Frame_Length_Thr jnc t1_int_frame_fail ; Frame too long - ; Check that correct number of pulses is received + ; Check that correct number (16) of pulses is received cjne Temp1, #16, t1_int_frame_fail ; Read current pointer ; Decode transmitted data @@ -131,16 +135,17 @@ t1_int: mov Temp2, DShot_Pwm_Thr ; DShot pulse width criteria mov Temp6, #0 ; Reset timestamp - ; Decode DShot data Msb. Use more code space to save time (by not using loop) + ; Decode DShot data MSB nibble (4bit). + ; Use more code space to save time (by not using loop) Decode_DShot_2Bit Temp5, t1_int_frame_fail Decode_DShot_2Bit Temp5, t1_int_frame_fail - sjmp t1_int_decode_lsb + sjmp t1_int_decode_lsb ; Continue with decoding LSB t1_int_frame_fail: sjmp t1_int_outside_range t1_int_decode_lsb: - ; Decode DShot data Lsb + ; Decode DShot data LSB (8bit) Decode_DShot_2Bit Temp4, t1_int_outside_range Decode_DShot_2Bit Temp4, t1_int_outside_range Decode_DShot_2Bit Temp4, t1_int_outside_range @@ -159,10 +164,10 @@ t1_int_outside_range_check_limit: subb A, #50 ; Allow a given number of outside pulses jc t1_int_exit_timeout ; If outside limits - ignore first pulses - ; RCP signal has not timed out, but pulses are not recognized as DShot + ; RC pulse signal has not timed out, but pulses are not recognized as DShot setb Flag_Rcp_Stop ; Set pulse length to zero mov DShot_Cmd, #0 ; Reset DShot command - mov DShot_Cmd_Cnt, #0 + mov DShot_Cmd_Cnt, #0 ; Reset Dshot command counter ajmp t1_int_exit_no_tlm ; Exit without resetting timeout @@ -205,7 +210,7 @@ t1_int_decode_checksum_xor_check: mov A, Temp3 ; Check for 0 or DShot command mov Temp5, #0 mov Temp4, #0 - jz t1_int_dshot_set_cmd ; Clear DShot command when RCP is zero + jz t1_int_dshot_set_cmd ; Clear DShot command when RC pulse is zero clr C ; We are in the special DShot range rrc A ; Shift tlm bit into carry @@ -245,7 +250,8 @@ t1_int_bidir_set: t1_int_bidir_set_dir: mov Flag_Rcp_Dir_Rev, C ; Set rcp direction - clr C ; Multiply throttle value by 2 + ; Multiply throttle value by 2 + clr C rlca Temp4 rlca Temp5 @@ -253,14 +259,15 @@ t1_int_not_bidir: ; From here Temp5/Temp4 should be at most 3999 (4095-96) mov A, Temp4 ; Divide by 16 (12 to 8-bit) anl A, #0F0h - orl A, Temp5 ; Note: Assumes Temp5 to be 4-bit + orl A, Temp5 ; NOTE: Assumes Temp5 to be 4-bit swap A mov B, #5 ; Divide by 5 (80 in total) div AB mov Temp3, A ; Align to 11 bits - ;clr C ; Note: Cleared by div + ;clr C ; NOTE: Cleared by div + rrca Temp5 mov A, Temp4 rrc A @@ -298,10 +305,10 @@ t1_int_not_bidir_do_not_boost: t1_int_stall_boost: mov A, Startup_Stall_Cnt ; Check stall count jz t1_int_startup_boosted - mov B, #40 ; Note: Stall count should be less than 6 + mov B, #40 ; NOTE: Stall count should be less than 6 mul AB - add A, Temp4 ; Add more power when failing to start motor (stalling) + add A, Temp4 ; Increase power when motor fails to start (stalling) mov Temp4, A mov A, Temp5 addc A, #0 @@ -314,7 +321,7 @@ t1_int_startup_boosted: ; Set 8-bit value mov A, Temp4 anl A, #0F8h - orl A, Temp5 ; Assumes Temp5 to be 3-bit (11-bit rcp) + orl A, Temp5 ; Assumes Temp5 to be 3-bit (11-bit RC pulse) swap A rl A mov Temp2, A @@ -328,7 +335,7 @@ t1_int_startup_boosted: sjmp t1_int_zero_rcp_checked t1_int_rcp_not_zero: - mov Rcp_Stop_Cnt, #0 ; Reset rcp stop counter + mov Rcp_Stop_Cnt, #0 ; Reset RC pulse stop counter clr Flag_Rcp_Stop ; Pulse ready t1_int_zero_rcp_checked: @@ -438,10 +445,10 @@ ENDIF ENDIF t1_int_set_pwm: -; Set pwm registers +; Set PWM registers IF DEADTIME != 0 - ; Subtract dead time from normal pwm and store as damping pwm - ; Damping pwm duty cycle will be higher because numbers are inverted + ; Subtract dead time from normal pwm and store as damping PWM + ; Damping PWM duty cycle will be higher because numbers are inverted clr C mov A, Temp2 ; Skew damping FET timing IF MCU_TYPE == MCU_BB1 @@ -473,8 +480,8 @@ t1_int_max_braking_set: t1_int_pwm_braking_set: ENDIF -; Note: Interrupts are not explicitly disabled -; Assume higher priority interrupts (Int0, Timer0) to be disabled at this point +; NOTE: Interrupts are not explicitly disabled. Assume higher priority +; interrupts (Int0, Timer0) to be disabled at this point. IF PWM_BITS_H != PWM_8_BIT ; Set power pwm auto-reload registers Set_Power_Pwm_Reg_L Temp2 @@ -509,7 +516,7 @@ ENDIF mov Temp1, #0 ; Set pointer to start - ; Note: Delay must be large enough to ensure port is ready for output + ; NOTE: Delay must be large enough to ensure port is ready for output mov TL0, DShot_GCR_Start_Delay ; Telemetry will begin after this delay clr TCON_TF0 ; Clear Timer0 overflow flag setb IE_ET0 ; Enable Timer0 interrupts @@ -532,14 +539,19 @@ t1_int_exit_no_int: ; ; Timer2 interrupt routine ; -; Update RC pulse timeout and stop counters -; Happens every 32ms before arming and every 16 ms after arming +; Happens every 32ms before arming and every 16 ms after arming (on 48MHz MCUs) ; -; Requirements: No PSW instructions or Temp registers +; Tasks: +; - Update RC pulse timeout +; - Update stop counters +; +; ASSERT: +; - No PSW instructions +; - Mp usage of Temp registers ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** t2_int: - push ACC + push ACC ; Preserve registers clr TMR2CN0_TF2H ; Clear interrupt flag inc Timer2_X ; Increment extended byte setb Flag_16ms_Elapsed ; Set 16ms elapsed flag @@ -574,9 +586,12 @@ t2_int_exit: ; ; Timer3 interrupt routine ; -; Used for commutation timing +; Tasks: +; - Commutation timing ; -; Requirements: No PSW instructions or Temp/Acc/B registers +; ASSERT: +; - No PSW instructions +; - No usage of Temp/Acc/B registers ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** t3_int: @@ -593,20 +608,22 @@ t3_int: ; ; Int0 interrupt routine (High priority) ; -; Read and store DShot pwm signal for decoding +; Tasks: +; - Read and store DShot PWM signal for decoding ; -; Requirements: No PSW instructions +; ASSERT: +; - No PSW instructions ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** int0_int: push ACC - mov A, TL0 ; Read pwm for DShot immediately + mov A, TL0 ; Read PWM for DShot immediately mov TL1, DShot_Timer_Preset ; Reset sync timer -; Temp1 in register bank 1 points to pwm timings + ; Temp1 in register bank 1 points to PWM timings push PSW mov PSW, #8h - movx @Temp1, A ; Store pwm in external memory + movx @Temp1, A ; Store PWM in external memory inc Temp1 pop PSW @@ -617,18 +634,22 @@ int0_int: ; ; Int1 interrupt routine ; -; Used for RC pulse timing +; Tasks: +; - RC pulse timing ; -; Requirements: No PSW instructions or Temp/Acc registers +; ASSERT: +; - No PSW instructions +; - No Temp/Acc registers ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** int1_int: clr IE_EX1 ; Disable Int1 interrupts setb TCON_TR1 ; Start Timer1 - ; Note: Interrupts are not explicitly disabled, assuming higher priority interrupts: - ; - Timer0 to be disabled at this point - ; - Int0 to not trigger for valid DShot signal + ; NOTE: Interrupts are not explicitly disabled, assuming higher priority + ; interrupts: + ; - Timer0 to be disabled at this point + ; - Int0 to not trigger for valid DShot signal clr TMR2CN0_TR2 ; Timer2 disabled mov DShot_Frame_Start_L, TMR2L ; Read timer value mov DShot_Frame_Start_H, TMR2H diff --git a/src/Modules/Macros.asm b/src/Modules/Macros.asm index 8a1a602..e4a9b5b 100644 --- a/src/Modules/Macros.asm +++ b/src/Modules/Macros.asm @@ -1,4 +1,4 @@ -;**** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Bluejay digital ESC firmware for controlling brushless motors in multirotors ; @@ -100,7 +100,64 @@ IF num < 5 ENDIF ENDM -Decode_DShot_2Bit MACRO dest,decode_fail +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decode 2 bit of a DShot frame +; +; ASSERT: +; - Temp1 is a pointer to the first pulse timestamp to be decoded +; - Temp2 holds DShot pulse width mimimum criteria +; - Temp6 holds the previous timestamp +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Decode 4 bit example with DShot 300: +; +; Temp1 | Value +; ------------- +; 0 | 16 +; 1 | 49 +; 2 | 83 +; 3 | 102 +; +; 1st call: (Temp1 = 0, Temp2 = 16, Temp6 = 0, dest = 0b00000000) +; --------------------------------------------------------------- +; Bit 1 (Temp1 = 0, dest = 0b00000000): +; - New value: A = 16 +; - last timestamp (0) is subtracted: A = 16 +; - min pulse width criteria (16) is subtracted: A = 0 +; - carry not set - value valid +; - A - Temp2 = 0 - 16 -> carry set +; - rotate dest left through carry -> dest = 0b00000001 +; +; Bit 2 (Temp1 = 1, dest = 0b00000001): +; - New value: A = 49 +; - last timestamp (16) is subtracted: A = 33 +; - min pulse width criteria (16) is subtracted: A = 17 +; - carry not set - value valid +; - A - Temp2 = 17 - 16 -> carry NOT set +; - rotate dest left through carry -> dest = 0b00000010 +; +; 2nd call: (Temp1 = 2, Temp2 = 16, Temp6 = 49, dest = 0b00000010) +; ---------------------------------------------------------------- +; Bit 1 (Temp1 = 2, dest = 0b00000010): +; - New value: A = 83 +; - last timestamp (49) is subtracted: A = 34 +; - min pulse width criteria (16) is subtracted: A = 18 +; - carry not set - value valid +; - A - Temp2 = 18 - 16 -> carry NOT set +; - rotate dest left through carry -> dest = 0b00000100 +; +; Bit 2 (Temp3 = 2, dest = 0b00000100): +; - New value: A = 102 +; - last timestamp (83) is subtracted: A = 19 +; - min pulse width criteria (16) is subtracted: A = 3 +; - carry not set - value valid +; - A - Temp2 = 3 - 16 -> carry set +; - rotate dest left through carry -> dest = 0b00001001 +;**** **** **** **** **** **** **** **** **** **** **** **** **** +Decode_DShot_2Bit MACRO dest, decode_fail + ; Bit 1 movx A, @Temp1 mov Temp7, A clr C @@ -111,19 +168,23 @@ Decode_DShot_2Bit MACRO dest,decode_fail subb A, Temp2 ; Check if bit is zero or one rlca dest ; Shift bit into data byte + + ; Bit 2 inc Temp1 ; Next bit movx A, @Temp1 - mov Temp6, A + mov Temp6, A ; Update timestamp clr C - subb A, Temp7 + subb A, Temp7 ; Subtract previous timestamp clr C subb A, Temp2 - jc decode_fail + jc decode_fail ; Check that bit is longer than minimum - subb A, Temp2 - rlca dest - inc Temp1 + subb A, Temp2 ; Check if bit is zero or one + rlca dest ; Shift bit into data byte + + ; Increase Bit for the (potential) next run of this macro + inc Temp1 ; Next bit ENDM ;**** **** **** **** **** **** **** **** **** **** **** **** **** @@ -176,11 +237,13 @@ ENDM ; ; Division ; -; ih, il: input (hi byte, lo byte) +; ih, il: input (hi byte, lo byte) ; oh, ol: output (hi byte, lo byte) ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** -Divide_By_16 MACRO ih,il,oh,ol + +; 16 bit Division by 16 (swap nibbles, mask and or) +Divide_By_16 MACRO ih, il, oh, ol mov A, ih swap A mov ol, A @@ -196,7 +259,15 @@ Divide_By_16 MACRO ih,il,oh,ol mov ol, A ENDM -Divide_12Bit_By_16 MACRO ih,il,ol ; Only if ih < 16 +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 12 bit Division by 16 (reduces 2 byte to a single) +; +; ASSERT: +; - ih < 16 +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** +Divide_12Bit_By_16 MACRO ih, il, ol mov A, ih swap A mov ol, A @@ -207,7 +278,8 @@ Divide_12Bit_By_16 MACRO ih,il,ol ; Only if ih < 16 mov ol, A ENDM -Divide_By_8 MACRO ih,il,oh,ol +; 16 bit Division by 8 (swap nibbles, shift, mask and or) +Divide_By_8 MACRO ih, il, oh, ol mov A, ih swap A rl A @@ -225,7 +297,14 @@ Divide_By_8 MACRO ih,il,oh,ol mov ol, A ENDM -Divide_11Bit_By_8 MACRO ih,il,ol ; Only if ih < 8 +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; 11 bit Division by 8 (swap nibbles, shift, mask and or) +; +; ASSERT: +; - ih < 8 +;**** **** **** **** **** **** **** **** **** **** **** **** **** +Divide_11Bit_By_8 MACRO ih, il, ol mov A, ih swap A rl A @@ -238,19 +317,27 @@ Divide_11Bit_By_8 MACRO ih,il,ol ; Only if ih < 8 mov ol, A ENDM -Divide_By_4 MACRO ih,il,oh,ol +; 16 bit Division by 4 (divide through 2, two times) (14 cycles) +; ih, oh and il, ol can be the same if inplace operation is fine +Divide_By_4 MACRO ih, il, oh, ol + ; Hi: Division by 2 through right shift clr C mov A, ih rrc A mov oh, A + + ; Lo: Division by 2 through carry (previous Hi right shift might have set it) mov A, il rrc A mov ol, A + ; Hi: Division by 2 trough right shift clr C mov A, oh rrc A mov oh, A + + ; Lo: Division by 2 through carry (previous Hi right shift might have set it) mov A, ol rrc A mov ol, A diff --git a/src/Modules/Power.asm b/src/Modules/Power.asm index 59808aa..91d9a62 100644 --- a/src/Modules/Power.asm +++ b/src/Modules/Power.asm @@ -1,4 +1,4 @@ -;**** **** **** **** **** +;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Bluejay digital ESC firmware for controlling brushless motors in multirotors ; @@ -42,9 +42,9 @@ switch_power_off: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; -; Set pwm limit low rpm +; Set PWM limit low RPM ; -; Sets power limit for low rpm +; Sets power limit for low RPM ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** set_pwm_limit: @@ -90,9 +90,9 @@ set_pwm_limit_low_rpm_exit: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; -; Set pwm limit high rpm +; Set PWM limit high RPM ; -; Sets power limit for high rpm +; Sets power limit for high RPM ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** set_pwm_limit_high_rpm: diff --git a/src/Modules/Scheduler.asm b/src/Modules/Scheduler.asm index 0b82700..4f17fac 100644 --- a/src/Modules/Scheduler.asm +++ b/src/Modules/Scheduler.asm @@ -22,17 +22,28 @@ ; along with Bluejay. If not, see . ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Scheduler +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** -; Divider of scheduler counter as a power of 2 number -; This macro exists for convenience to easily change scheduler step time -; In the table below you can find valid values for this parameter +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Divider of scheduler counter as a power of 2 number. +; +; This macro exists for convenience to easily change scheduler step time. +; In the table below you can find valid values for this parameter. +; ; Value Step Cycle (8 steps) Zero crossing scan interference +; --------------------------------------------------------------------- ; 0 16ms 128ms Medium - High ; 1 32ms 256ms Medium ; 2 64ms 512ms Low ; 3 128ms 1024ms Low ; 4 256ms 2048ms Low ; 5 512ms 4096ms Low +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** SCHEDULER_COUNTER_DIVIDER_POW2 EQU 3 ; Bitmask to get the remainder of dividing a number by 8 @@ -46,26 +57,26 @@ STEP1_STATUS_FRAME EQU (001h SHL SCHEDULER_COUNTER_DIVIDER_POW2) STEP3_DEBUG1_FRAME EQU (003h SHL SCHEDULER_COUNTER_DIVIDER_POW2) STEP5_DEBUG2_FRAME EQU (005h SHL SCHEDULER_COUNTER_DIVIDER_POW2) - ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; Scheduler -; Each step 128ms, cycle 1024ms (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 +; Each step is 128ms, a complete cycle is 1024ms (8 steps) +; +; ReqSch00: - Steps even [0, 2, 4, 6] +; ReqSch01: - Update temperature setpoint on every even step +; ReqSch02: - [TELEMETRY] Send demag metric frame +; ReqSch03: - Steps odd [1, 3, 5, 7] +; ReqSch04: - Update temperature PWM limit on every odd step +; 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 after every odd step ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** @@ -97,7 +108,7 @@ scheduler_steps_even: ; UPDATE TEMPERATURE SETPOINT ;**** **** **** **** **** **** **** **** **** **** **** **** **** - ; Check temp protection enabled, and skip when protection is disabled + ; Check temp protection: skip when protection is disabled mov A, Temp_Prot_Limit jz scheduler_steps_even_demag_metric_frame @@ -106,11 +117,13 @@ scheduler_steps_even: ; Check TEMP_LIMIT in Base.inc and make calculations to understand temperature readings ; 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 + ; + ; 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_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 @@ -139,17 +152,18 @@ scheduler_steps_even: ; Zero pwm cannot be set because of set_pwm_limit algo restrictions ; Otherwise hard stuttering is produced + scheduler_steps_even_demag_metric_frame: - ; Check telemetry is enable to produce telemetry frames + ; Check if extended telemetry is enabled, otherwise we are done here. jb Flag_Ext_Tele, scheduler_steps_even_demag_metric_frame_prepare ; No more work to do ret -scheduler_steps_even_demag_metric_frame_prepare: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; [TELEMETRY] SEND DEMAG METRIC FRAME ;**** **** **** **** **** **** **** **** **** **** **** **** **** +scheduler_steps_even_demag_metric_frame_prepare: 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 @@ -161,12 +175,12 @@ scheduler_steps_odd: ; UPDATE TEMPERATURE PWM LIMIT EVERY 256ms (ON ODD STEP) ;**** **** **** **** **** **** **** **** **** **** **** **** **** - ; Check temp protection enabled, and exit when protection is disabled + ; Check if temp protection is enabled, otherwise continue with odd step mov A, Temp_Prot_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, that may damage motor/esc + ; PWM limit is updated one unit at a time to avoid abrupt PWM changes + ; resulting in current spikes, that may damage motor/ESC. ; Compare pwm limit to setpoint clr C mov A, Pwm_Limit @@ -178,26 +192,26 @@ scheduler_steps_odd_temp_pwm_limit_dec: ; Decrease pwm limit dec Pwm_Limit - ; Now run speciffic odd scheduler step + ; 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 -; Now run speciffic odd scheduler step +; Run speciffic odd scheduler step scheduler_steps_odd_choose_step: - ; Check telemetry is enabled to produce telemetry frames + ; Check if extended telemetry is enabled, otherwise skip frame generation jnb Flag_Ext_Tele, scheduler_steps_odd_restart_ADC ; Get scheduler step mov A, Scheduler_Counter anl A, #MASK_STEP -scheduler_steps_odd_status_frame: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; [TELEMETRY] SEND STATUS FRAME ;**** **** **** **** **** **** **** **** **** **** **** **** **** +scheduler_steps_odd_status_frame: cjne A, #STEP1_STATUS_FRAME, scheduler_steps_odd_debug1_frame ; if (Demag_Detected_Metric_Max >= 120) @@ -239,10 +253,10 @@ scheduler_steps_odd_status_frame_max_loaded: ; Nothing else to do ret -scheduler_steps_odd_debug1_frame: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; [TELEMETRY] SEND DEBUG1 FRAME ;**** **** **** **** **** **** **** **** **** **** **** **** **** +scheduler_steps_odd_debug1_frame: cjne A, #STEP3_DEBUG1_FRAME, scheduler_steps_odd_debug2_frame ; Stub for debug 1 @@ -255,10 +269,10 @@ scheduler_steps_odd_debug1_frame: ; Nothing else to do ret -scheduler_steps_odd_debug2_frame: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; [TELEMETRY] SEND DEBUG2 FRAME ;**** **** **** **** **** **** **** **** **** **** **** **** **** +scheduler_steps_odd_debug2_frame: cjne A, #STEP5_DEBUG2_FRAME, scheduler_steps_odd_temperature_frame ; Stub for debug 2 @@ -271,10 +285,10 @@ scheduler_steps_odd_debug2_frame: ; Nothing else to do ret -scheduler_steps_odd_temperature_frame: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; [TELEMETRY] SEND TEMPERATURE FRAME ;**** **** **** **** **** **** **** **** **** **** **** **** **** +scheduler_steps_odd_temperature_frame: ; If step is not 1, 3 or 5 it has to be 7, so cjmp is not necessary ; cjne A, #STEP7_TEMPERATURE_FRAME, scheduler_steps_odd_restart_ADC @@ -290,10 +304,10 @@ IF MCU_TYPE == MCU_BB1 or MCU_TYPE == MCU_BB2 cjne @Temp1, #01h, scheduler_steps_odd_temperature_frame_power_rating_2s ENDIF -scheduler_steps_odd_temperature_frame_power_rating_1s: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ON BB51 and BB1, BB2 at 1S, all using internal 1.65V ADC reference ;**** **** **** **** **** **** **** **** **** **** **** **** **** +scheduler_steps_odd_temperature_frame_power_rating_1s: mov A, ADC0H jnz scheduler_steps_odd_temperature_frame_pr1s_temperature_above_0 @@ -345,12 +359,11 @@ 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 -; Now restart ADC conversion -scheduler_steps_odd_restart_ADC: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; START NEW ADC CONVERSION ;**** **** **** **** **** **** **** **** **** **** **** **** **** - ; Now restart ADC conversion +scheduler_steps_odd_restart_ADC: + ; Restart ADC conversion Restart_Adc ; Nothing else to do diff --git a/src/Modules/Settings.asm b/src/Modules/Settings.asm index fd585ef..69e8e70 100644 --- a/src/Modules/Settings.asm +++ b/src/Modules/Settings.asm @@ -27,13 +27,7 @@ ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** -;**** **** **** **** **** **** **** **** **** **** **** **** **** -; -; Set default parameters -; ; Sets default programming parameters -; -;**** **** **** **** **** **** **** **** **** **** **** **** **** set_default_parameters: mov Temp1, #_Pgm_Gov_P_Gain mov @Temp1, #0FFh ; _Pgm_Gov_P_Gain @@ -140,8 +134,9 @@ decode_demag_done: ;**** **** **** **** **** **** **** **** **** **** **** **** **** ; ; 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 +; depending on if an external voltage regulator is used or not. +; +; NOTE: For BB51, the 1s power rating code path is mandatory ; ;**** **** **** **** **** **** **** **** **** **** **** **** **** IF MCU_TYPE == MCU_BB1 or MCU_TYPE == MCU_BB2 @@ -207,6 +202,14 @@ ENDIF cjne @Temp1, #0FFh, decode_pwm_dithering mov Pwm_Braking_L, #0FFh ; Apply full braking if setting is max +;**** **** **** **** **** **** **** **** **** **** **** **** **** +; +; Dithering +; +; Depending on resolution, different dithering patterns are available. +; +;**** **** **** **** **** **** **** **** **** **** **** **** **** + decode_pwm_dithering: mov Temp1, #Pgm_Dithering ; Read programmed dithering setting mov A, @Temp1 diff --git a/src/Modules/Timing.asm b/src/Modules/Timing.asm index 86769a5..d12dea6 100644 --- a/src/Modules/Timing.asm +++ b/src/Modules/Timing.asm @@ -52,8 +52,8 @@ initialize_timing: ;**** **** **** **** **** **** **** **** **** **** **** **** **** calc_next_comm_period: ; Read commutation time - clr IE_EA - clr TMR2CN0_TR2 ; Timer2 disabled + clr IE_EA ; Disable all interrupts + clr TMR2CN0_TR2 ; Disable Timer2 mov Temp1, TMR2L ; Load Timer2 value mov Temp2, TMR2H mov Temp3, Timer2_X @@ -64,8 +64,9 @@ calc_next_comm_period_enable_timer2: setb TMR2CN0_TR2 ; Timer2 enabled setb IE_EA +; Divide time by 2 on 48MHz IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 - clr C ; Divide time by 2 on 48MHz + clr C rrca Temp3 rrca Temp2 rrca Temp1 @@ -87,8 +88,8 @@ IF MCU_TYPE == MCU_BB2 or MCU_TYPE == MCU_BB51 ENDIF mov Temp2, A ; Store commutation period in Temp2 (hi byte) - jnb Flag_High_Rpm, calc_next_comm_normal ; Branch normal rpm - ajmp calc_next_comm_period_fast ; Branch high rpm + jnb Flag_High_Rpm, calc_next_comm_normal ; Branch normal RPM + ajmp calc_next_comm_period_fast ; Branch high RPM calc_next_comm_startup: ; Calculate this commutation time @@ -143,8 +144,9 @@ calc_next_comm_normal: mov Temp4, Comm_Period4x_H clr C - mov A, Temp4 ; Is Comm_Period4x_H below 4? (above ~80k erpm) - subb A, #4 + mov A, Temp4 + + subb A, #4 ; Is Comm_Period4x_H below 4? (above ~80k erpm) jc calc_next_comm_div_16_4 ; Yes - Use averaging for high speeds subb A, #4 ; Is Comm_Period4x_H below 8? (above ~40k erpm) @@ -155,17 +157,15 @@ calc_next_comm_normal: ; Do not average very fast during initial run jb Flag_Initial_Run_Phase, calc_next_comm_div_8_2_slow +; Update Comm_Period4x from 1 new commutation period calc_next_comm_div_4_1: - ; Update Comm_Period4x from 1 new commutation period - ; Divide Temp4/3 by 4 and store in Temp6/5 Divide_By_4 Temp4, Temp3, Temp6, Temp5 sjmp calc_next_comm_average_and_update +; Update Comm_Period4x from 1/2 new commutation period calc_next_comm_div_8_2: - ; Update Comm_Period4x from 1/2 new commutation period - ; Divide Temp4/3 by 8 and store in Temp5 Divide_11Bit_By_8 Temp4, Temp3, Temp5 mov Temp6, #0 @@ -174,9 +174,8 @@ calc_next_comm_div_8_2: sjmp calc_next_comm_average_and_update +; Update Comm_Period4x from 1/2 new commutation period calc_next_comm_div_8_2_slow: - ; Update Comm_Period4x from 1/2 new commutation period - ; Divide Temp4/3 by 8 and store in Temp6/5 Divide_By_8 Temp4, Temp3, Temp6, Temp5 @@ -184,9 +183,8 @@ calc_next_comm_div_8_2_slow: sjmp calc_next_comm_average_and_update +; Update Comm_Period4x from 1/4 new commutation period calc_next_comm_div_16_4: - ; Update Comm_Period4x from 1/4 new commutation period - ; Divide Temp4/3 by 16 and store in Temp5 Divide_12Bit_By_16 Temp4, Temp3, Temp5 mov Temp6, #0 @@ -275,7 +273,7 @@ calc_next_comm_period_fast: subb A, #0 mov Temp4, A - ; Note: Temp2 is assumed to be zero (approx. Comm_Period4x_H / 4) + ; NOTE: Temp2 is assumed to be zero (approx. Comm_Period4x_H / 4) mov A, Temp1 ; Divide by 4 rr A rr A @@ -836,19 +834,24 @@ wait_for_comm_demag_metric_max_updated: jc wait_for_comm_wait ; Signal desync - setb Flag_Desync_Notify ; + setb Flag_Desync_Notify - ; Cut power if many consecutive demags. This will help retain sync during hard accelerations + ; Cut power if many consecutive demags are detected. + ; This will help retain sync during hard accelerations. All_Pwm_Fets_Off Set_All_Pwm_Phases_Off wait_for_comm_wait: - ; If it has not already, we wait here for the Wt_Comm_Start_ delay to elapse. + ; If it has not already, we wait for the Wt_Comm_Start_ delay to elapse. Wait_For_Timer3 - ; At this point Timer3 has (already) wrapped and been reloaded with the Wt_Adv_Start_ delay. - ; In case this delay has also elapsed, Timer3 has been reloaded with a short delay any number of times. - ; - The interrupt flag is set and the pending flag will clear immediately after enabling the interrupt. + ; At this point Timer3 has (already) wrapped and been reloaded with + ; the Wt_Adv_Start_ delay. + ; + ; In case this delay has also elapsed, Timer3 has been reloaded with a short + ; delay any number of times. + ; - The interrupt flag is set and the pending flag will clear immediately + ; after enabling the interrupt. mov TMR3RLL, Wt_Zc_Scan_Start_L ; Setup next wait time mov TMR3RLH, Wt_Zc_Scan_Start_H setb Flag_Timer3_Pending