BLHeli icon indicating copy to clipboard operation
BLHeli copied to clipboard

a bug with calc_next_comm_timing_fast

Open garlinplus opened this issue 3 years ago • 10 comments

calc_next_comm_timing_fast: ; Calculate new commutation time mov Temp3, Comm_Period4x_L ; Comm_Period4x(-l-h) holds the time of 4 commutations mov Temp4, Comm_Period4x_H mov A, Temp4 ; Divide by 2 4 times swap A mov Temp7, A mov A, Temp3 swap A anl A, #0Fh orl A, Temp7 mov Temp5, A

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Comm_Period4x/16 is stored in temp5 with above code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

clr	C
mov	A, Temp3				; Subtract a fraction
subb	A, Temp5
mov	Temp3, A
mov	A, Temp4				
subb	A, #0
mov	Temp4, A

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 15*Comm_Period4x/16 is stored in temp5 with above code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

clr	C
mov	A, Temp1
rrc	A					; Divide by 2 2 times
clr	C
rrc	A

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Tcomm/4 is object that the code want to calculate,and newest commutation period is stored in temp1 and temp2. In the calc_next_comm_timing_fast label, high rpm flag is set,and Temp2 is less than 2,but it's not zero. So in above code,the result with Temp1 right shifted 2 is not Tcomm / 4. There is a bug! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

mov	Temp1, A
mov	A, Temp3				; Add the divided new time
add	A, Temp1
mov	Temp3, A
mov	A, Temp4
addc	A, #0
mov	Temp4, A
mov	Comm_Period4x_L, Temp3	; Store Comm_Period4x_X
mov	Comm_Period4x_H, Temp4



clr	C
mov	A, Temp4				; If erpm below 156k - go to normal case
subb	A, #2
jc	($+4)

clr	Flags1.HIGH_RPM 		; Clear high rpm bit

; Set timing reduction
mov	Temp1, #2
mov	A, Temp4				; Divide by 2 4 times
swap	A
mov	Temp7, A
mov	Temp4, #0
mov	A, Temp3
swap A
anl	A, #0Fh
orl	A, Temp7
mov	Temp3, A
clr	C
mov	A, Temp3
subb	A, Temp1
mov	Temp3, A
jc	load_min_time_fast		; Check that result is still positive

clr	C
subb	A, #1
jnc	calc_new_wait_times_fast_done	; Check that result is still above minumum

garlinplus avatar Sep 08 '22 07:09 garlinplus

Good catch, I think you are right. Although I believe some of your comments are not accurate.

Wouldn't this fix it:?

	clr	C
	mov	A, Temp3				; Subtract a fraction
	subb	A, Temp5
	mov	Temp3, A
	mov	A, Temp4				
	subb	A, #0
	mov	Temp4, A

	; Incorrect, need to consider LSB of Temp2
	;clr	C
	; Corrected, storing LSB of Temp2 in C
	mov A, Temp2
	rrc A

	mov	A, Temp1
	rrc	A					; Divide by 2 2 times
	clr	C
	rrc	A
	mov	Temp1, A
	mov	A, Temp3				; Add the divided new time
	add	A, Temp1
	mov	Temp3, A
	mov	A, Temp4
	addc	A, #0
	mov	Temp4, A
	mov	Comm_Period4x_L, Temp3	; Store Comm_Period4x_X
	mov	Comm_Period4x_H, Temp4

sskaug avatar Sep 08 '22 18:09 sskaug

Good catch, I think you are right. Although I believe some of your comments are not accurate.

Wouldn't this fix it:?

	clr	C
	mov	A, Temp3				; Subtract a fraction
	subb	A, Temp5
	mov	Temp3, A
	mov	A, Temp4				
	subb	A, #0
	mov	Temp4, A

	; Incorrect, need to consider LSB of Temp2
	;clr	C
	; Corrected, storing LSB of Temp2 in C
	mov A, Temp2
	rrc A

	mov	A, Temp1
	rrc	A					; Divide by 2 2 times
	clr	C
	rrc	A
	mov	Temp1, A
	mov	A, Temp3				; Add the divided new time
	add	A, Temp1
	mov	Temp3, A
	mov	A, Temp4
	addc	A, #0
	mov	Temp4, A
	mov	Comm_Period4x_L, Temp3	; Store Comm_Period4x_X
	mov	Comm_Period4x_H, Temp4

Good,your code is right. what's wrong of my comment ?

garlinplus avatar Sep 09 '22 06:09 garlinplus

Not: "15Comm_Period4x/16 is stored in temp5 with above code". Should be "15Comm_Period4x/16 is stored in Temp4/3 with above code"

sskaug avatar Sep 09 '22 06:09 sskaug

yes,you are right.

garlinplus avatar Sep 09 '22 08:09 garlinplus

The question now, is what do we do about this? I feel it is not sufficient for generating a new revision (16.8), What about just generating an update to the current rev16.7? Not a clean way of doing revs - traceability will be lost - but maybe ok in this case?

sskaug avatar Sep 09 '22 17:09 sskaug

can calc_next_comm_normal,calc_next_comm_startup,and calc_next_comm_timing_fast has same next called function calc_new_wait_times_setup?

These three label all has same operation as followed: temp3/4 = Comm_Period4x >>4 if temp3/4 > 2 temp3/4 = temp3/4 - 2; end

if temp3/4 < 1 temp3/4 = 1 end

calc_new_wait_per_demag_done:
	; Set timing reduction
	mov	Temp7, #2
	; Load current commutation timing
	mov	A, Comm_Period4x_H		; Divide 4 times
	swap	A
	anl	A, #00Fh
	mov	Temp2, A
	mov	A, Comm_Period4x_H
	swap	A
	anl	A, #0F0h
	mov	Temp1, A
	mov	A, Comm_Period4x_L
	swap	A
	anl	A, #00Fh
	add	A, Temp1
	mov	Temp1, A

> 	clr	C
> 	mov	A, Temp1
> 	subb	A, Temp7
> 	mov	Temp3, A
> 	mov	A, Temp2				
> 	subb	A, #0
> 	mov	Temp4, A
> 	jc	load_min_time			; Check that result is still positive
> 
> 	clr	C
> 	mov	A, Temp3
> 	subb	A, #1
> 	mov	A, Temp4			
> 	subb	A, #0
> 	jnc	calc_new_wait_times_exit	; Check that result is still above minumum
> 
> load_min_time:
> 	mov	Temp3, #1
> 	clr	A
> 	mov	Temp4, A

; Fast calculation (Comm_Period4x_H less than 2)
calc_next_comm_timing_fast:			
	; Calculate new commutation time
	mov	Temp3, Comm_Period4x_L	; Comm_Period4x(-l-h) holds the time of 4 commutations
	mov	Temp4, Comm_Period4x_H
	mov	A, Temp4				; Divide by 2 4 times
	swap	A
	mov	Temp7, A
	mov	A, Temp3
	swap A
	anl	A, #0Fh
	orl	A, Temp7
	mov	Temp5, A
	clr	C
	mov	A, Temp3				; Subtract a fraction
	subb	A, Temp5
	mov	Temp3, A
	mov	A, Temp4				
	subb	A, #0
	mov	Temp4, A
	clr	C
	mov	A, Temp1
	rrc	A					; Divide by 2 2 times
	clr	C
	rrc	A
	mov	Temp1, A
	mov	A, Temp3				; Add the divided new time
	add	A, Temp1
	mov	Temp3, A
	mov	A, Temp4
	addc	A, #0
	mov	Temp4, A
	mov	Comm_Period4x_L, Temp3	; Store Comm_Period4x_X
	mov	Comm_Period4x_H, Temp4
	clr	C
	mov	A, Temp4				; If erpm below 156k - go to normal case
	subb	A, #2
	jc	($+4)

	clr	Flags1.HIGH_RPM 		; Clear high rpm bit



> 	; Set timing reduction
> 	mov	Temp1, #2
> 	mov	A, Temp4				; Divide by 2 4 times
> 	swap	A
> 	mov	Temp7, A
> 	mov	Temp4, #0
> 	mov	A, Temp3
> 	swap A
> 	anl	A, #0Fh
> 	orl	A, Temp7
> 	mov	Temp3, A
> 	clr	C
> 	mov	A, Temp3
> 	subb	A, Temp1
> 	mov	Temp3, A
> 	jc	load_min_time_fast		; Check that result is still positive
> 
> 	clr	C
> 	subb	A, #1
> 	jnc	calc_new_wait_times_fast_done	; Check that result is still above minumum
> 
> load_min_time_fast:
> 	mov	Temp3, #1

garlinplus avatar Sep 12 '22 07:09 garlinplus

There are some confusion about timer3 interrupt process function. Timer3 reload register TMR3RLL/TMR3RLH is reset value with 0xfffa. It means that when timer3's interrupt is triggered,it's reload register is set to 0xfffa. But in label of wait_advance_timing,setup_comm_wait and wait_for_comm_wait,the realod register of timer3 is set. Does it work?

;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Timer 3 interrupt routine
;
; No assumptions
; Requirements: Temp variables can NOT be used since PSW.x is not set
;               ACC can not be used, as it is not pushed to stack
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
t3_int:	; Used for commutation timing
	clr 	IE_EA			; Disable all interrupts
	anl	EIE1, #7Fh		; Disable timer 3 interrupts
	mov	TMR3RLL, #0FAh		; Set a short delay before next interrupt
	mov	TMR3RLH, #0FFh
	clr	Flags0.T3_PENDING 	; Flag that timer has wrapped
	anl	TMR3CN0, #07Fh		; Timer 3 interrupt flag cleared
	setb	IE_EA			; Enable all interrupts
	reti

 ;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Wait advance timing routine
;
; No assumptions
; NOTE: Be VERY careful if using temp registers. They are passed over this routine
;
; Waits for the advance timing to elapse and sets up the next zero cross wait
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
wait_advance_timing:	
	jnb	Flags0.T3_PENDING, ($+5)
	ajmp	wait_advance_timing

	; Setup next wait time
	mov	TMR3RLL, Wt_ZC_Tout_Start_L
	mov	TMR3RLH, Wt_ZC_Tout_Start_H
	setb	Flags0.T3_PENDING
	orl	EIE1, #80h	; Enable timer 3 interrupts
;**** **** **** **** **** **** **** **** **** **** **** **** ****
;
; Setup commutation timing routine
;
; No assumptions
;
; Sets up and starts wait from commutation to zero cross
;
;**** **** **** **** **** **** **** **** **** **** **** **** ****
setup_comm_wait:
	clr	IE_EA
	anl	EIE1, #7Fh		; Disable timer 3 interrupts
	mov	TMR3CN0, #00h		; Timer 3 disabled and interrupt flag cleared
	mov	TMR3L, Wt_Comm_Start_L
	mov	TMR3H, Wt_Comm_Start_H
	mov	TMR3CN0, #04h		; Timer 3 enabled and interrupt flag cleared95`
	; Setup next wait time
	mov	TMR3RLL, Wt_Adv_Start_L
	mov	TMR3RLH, Wt_Adv_Start_H
	setb	Flags0.T3_PENDING
	orl	EIE1, #80h		; Enable timer 3 interrupts
	setb	IE_EA			; Enable interrupts again
wait_for_comm_wait:
	jnb Flags0.T3_PENDING, ($+5)			
	ajmp	wait_for_comm_wait

	; Setup next wait time
	mov	TMR3RLL, Wt_Zc_Scan_Start_L
	mov	TMR3RLH, Wt_Zc_Scan_Start_H
	setb	Flags0.T3_PENDING
	orl	EIE1, #80h			; Enable timer 3 interrupts
	ret

garlinplus avatar Sep 12 '22 12:09 garlinplus

I'm not sure I understand what you point to above. But note that there is no longer any development on BLHeli_S. For new developments/optimizations please check out the Bluejay repo that is a further development of BLHeli_S.

sskaug avatar Sep 12 '22 16:09 sskaug

ok,thanks.

garlinplus avatar Sep 13 '22 02:09 garlinplus

@garlinplus Thanks for tracking this kind of bugs. Has you been able to test the fix? Do you think it could also affect Bluejay?

damosvil avatar Jan 02 '23 11:01 damosvil