AFR enhancements: patch routines for Z32

Discuss possible software enhancements/changes here.

Moderator: Matt

Post Reply
RomChip200
 

Posts: 426
Joined: Mon May 11, 2009 7:58 pm
Location: FRANCE

AFR enhancements: patch routines for Z32

Post by RomChip200 »

Here is a routine that enhances the AFR correction performed by Z32 ECU. It's 47P10 image based.
What does it do:
1) OEM narrowbands are used to get richness measurements but don't apply AFR correction all the time
2) when driving, mainly when cruising, the (calculated) injection times are not corrected by the narrowbands (it's equivalent to have the lambda sensors removed or disabled)
3) in idle, correction applies (purpose is to target 14.7 AFR whatever the idle state is (A/C on or off)
4) Balancing of engine banks injection times is done (mainly when cruising), purpose is to target the same AFR ratios on both banks (I crosscheck this using my widebands). Basically in a VG30DETT, driver side (exhaust) is always a bit leaner (exhaust) ) than passenger side. Cyclinders 1/3/5 have a fuel pressure drop compared to cylinders 2/4/6.
5) AFR correction tables are extended in rpm range and TP load range. Basically, this gives you some indications of lean spots.
6) Consult registers table is modified to be able to track the correction factors (I use Nistune to log that).

Attached file for source and patch bin file (only changed locations are different of 0xFF).

Code: Select all




flags		EQU	0x0040
sio_flags1	EQU	0x0041
sio_flags	EQU	0x0043
act_mask2	EQU	0x00DD 


flags6		EQU	0x0055
engine_temp_initial EQU 0x145D
engine_temp	EQU     0x140C
sflag1_copy	EQU	0x00D2
afr_var42	EQU	0x16A5
afr_var24	EQU	0x16A7  
afr_bank2_coef  EQU	0x149F
afr_bank1_coef  EQU 	0x14A1
inj_tot_latency	EQU	0x1430
acc_coefx100	EQU	0x14B5
inj_bb1		EQU	0x1413 14
inj_bb2		EQU	0x1415 16
afr_bank1_max	EQU	0x1435                        ; ...
afr_bank2_max	EQU	0x1437
speed		EQU	0x1407

mul16_D_X	EQU	0x8000
mul16_D_P1	EQU	0x8002
mul16_A_P1	EQU	0x802C 
interp_16	EQU	0x80EF
 
afr_const24	EQU     0xFEE7
afr_const50	EQU	0xFEE8 
fb_control      EQU     0xFF91
AFR_min_coef:   EQU	0xF407                          
AFR_max_coef:   EQU	0xF408

rpm		EQU	0x140A 0B
rpm_ref		EQU	0x164D
maf		EQU	0x1408 09
lambda_left	EQU	0x15DA
lambda_right	EQU	0x15D9
battery		EQU	0x0092
throttle1	EQU	0x14A7
fuel_temp	EQU	0x1428
digital1	EQU	0x153C
inj_bbb2    	EQU	0x156E 6F
inj_bbb1	EQU	0x1570 71
ign_timing  	EQU	0x1410
idle_air	EQU	0x14E1 
afr_left	EQU	0x1625
afr_right	EQU	0x1626
afr_learn_left  EQU	0x1623
afr_learn_right	EQU	0x1624
digital2	EQU	0x00F0
digital3	EQU	0x00F1
mr_fc_mnt	EQU	0x153D
tp_filt		EQU	0x148C 
tp		EQU	0x1417 18
tp1		EQU	0x151F 20
timing_offset2  EQU	0x1614 15
knock_value	EQU	0x1610 11


ram2_checksum	EQU	0x16A0
off_372		EQU	0x16A1 A2
word_398	EQU	0x16DE DF
cnt_counter5	EQU	0x147F 


inj_counter2	EQU	0x147A 
byte_6135   	EQU	0xFF02 
byte_6136	EQU	0xFF04 
rpm_d4_lo	EQU	0x146A 
rpm_lo		EQU	0x144A 
tp2		EQU	0x1505 
inj_pulse_coef	EQU	0x142E 2F 

inj_b1		EQU	0x1456
inj_b2		EQU	0x1458  
inj_flags	EQU	0x0051 
flags3		EQU	0x0056 
inj_bank1	EQU	0x004D 
inj_bank2	EQU	0x004F 
inj_global_mask	EQU	0x005C 

warmup_counter	EQU	0x1432
engine_temp2	EQU	0x00B6 
inj_temp_coef	EQU	0x1431  
inj_temp_coef_map EQU	0xFE20
byte_6134	EQU	0xFF82 


afr_bank1_map 	EQU	0x1700

afr_flags_left	EQU	0x0053
afr_flags_right EQU	0x00CE
afr_flags	EQU	0x00D1
afr_flags1	EQU	0x00CF

afr_var20	EQU	0x15CF
afr_var31	EQU	0x149C 
afr_counter4	EQU	0x1440 
afr_counter7	EQU	0x00B4 
afr_counter10	EQU	0x1406
  

; ************ New variables  *************** 

; inj_base ==> inj_bb1 ==> inj_b1
inj_base	EQU	0x15BE BF
inj_bb1_nocorrect EQU	0x15C0 C1
inj_bb2_nocorrect EQU	0x15C2 C3
inj_b1_temp	 EQU	0x15C4 C5       ; temporary values in inj_knock_enrichment
inj_b2_temp	 EQU	0x15C6 C7
inj_b1_nocorrect EQU	0x15C8 C9
inj_b2_nocorrect EQU	0x15CA CB



inj_b1_balance	EQU	0x16EE EF
inj_b2_balance	EQU	0x16F6 F7



; ************ New defines  *************** 

AFRmeasure_warm		EQU	50+25	25°C	
AFRmeasure_cold 	EQU	50+50	50°C
AFRcorrect_thres	EQU	50+150  150 °C (150°C means never)
engine_temp_initial_thres EQU	50+10   10°C       
max_TP_AFR_correction EQU 	85      TP

; ******************************************
		 


	org 0x0000
	fcb 0xFF		 dummy


; ******************************************
PATCHS
; ******************************************

	org afr_const24
	fcb AFRmeasure_cold

	org afr_const50
	fcb AFRmeasure_warm

	org fb_control
	fcb AFRcorrect_thres
		
	
	
	org AFR_min_coef
	fcb 90       Minimum AFR coef
	
	org AFR_max_coef
	fcb 110      Maximum AFR coef

	org  0x8FAD
	jsr reset_afr_learn_maps

	org  0x9514
	jsr reset_afr_learn_maps


; ******************************************

	org 0xFBA0 
afr_tp_scale       fcb  5,8,11,15,19,23,27,32

	org 0xFBA8 
afr_rpm_scale      fcb  16,24,40,48,56,64,76,88  800,1200,2000,2400,2800,3200,3800,4400


; to be able to log afr, "knock variables" are migrated to inj_bbbX
	org 0xEA00 
register_table     
		fdb rpm                       ; Register 0                                                   ; Register 0
	        fdb rpm+1                     ; Register 1
 
;        	fdb rpm_ref                   ; Register 2
;	        fdb rpm_ref+1                 ; Register 3
 		fdb inj_b1_balance       	
		fdb inj_b2_balance		
		
;		fdb maf                       ; Register 4
;	        fdb maf+1                     ; Register 5
		fdb afr_bank2_coef
		fdb afr_bank1_coef

         	fdb $FFFF
	        fdb $FFFF
         	fdb engine_temp               ; Register 8

;	      	fdb lambda_left               ; Register 9
;  		fdb lambda_right              ; Register A
		fdb afr_bank1_max
		fdb afr_bank2_max
		
		fdb speed                     ; Register B
  		fdb battery                   ; Register C
    		fdb throttle1                 ; Register D
      		fdb $FFFF

;		fdb fuel_temp                 ; Register F
		fdb timing_offset2	      ; instantaneous knock on accel

	        fdb $FFFF
		fdb $FFFF
         	fdb $FFFF
	        fdb digital1                  ; Register 13
         	fdb inj_bbb2                  ; Register 14
	        fdb inj_bbb2+1                ; Register 15

         	fdb ign_timing                ; Register 16

;	        fdb idle_air                  ; Register 17 AAC valve
		fdb knock_value	              ; continuous knock detected in gear

	        fdb $FFFF
		fdb $FFFF
         	fdb afr_left                  ; Register 1A
	        fdb afr_right                 ; Register 1B
         	fdb afr_learn_left            ; Register 1C
	        fdb afr_learn_right           ; Register 1D
         	fdb digital2                  ; Register 1E
          	fdb digital3                  ; Register 1F
	        fdb $FFFF
         	fdb mr_fc_mnt                 ; Register 21

	        fdb inj_bbb1                  ; Register 22
         	fdb inj_bbb1+1                ; Register 23
          	
          	fdb $FFFF
	        fdb $FFFF

;         	fdb $FFFF
;	        fdb $FFFF
		fdb tp1	      tp1 is real tp from AFM calculation, without any correction (e.g. ttpmin,ttpmax)
		fdb tp1+1


	org 0xEA50
activation_table
		fdb $101


	
; ****** in afr_control_compute ************************************

	org 0x8C05
loc_537
	tim %1,flags6                 ; Bit 0: throttle switch (1=idle)
                                      ; Bit 1: high octane
                                      ; Bit 2: neutral switch(1=neutral)
                                      ; Bit 3: power steering switch (1=on)
                                      ; Bit 4: A/C switch (1=on)
                                      ; Bit 7: gear engaged and high gear

; (...)
	org 0x8C2E 
loc_540                                          ; ...
 	ldaa engine_temp_initial      ; Initial engine temp+50 (°C)
        ldab engine_temp              ; Engine temp+50 (°C)
	cmpa #engine_temp_initial_thres
	bcc loc_5991

        cmpb afr_const24              ; warm start closed loop temp (above which we go into closed loop after a warm start)
        bcs loc_537
 
        bra loc_5992
 
	org 0x8C3F 
loc_5991                                         ; ...
;	cmpb fb_control               ; O2 sensor "ready" time (after warmup? seconds? minutes?)
					; fb_control is now used in inj_adjust_banks	
	cmpb afr_const50               ; O2 sensor "ready" time (after warmup? seconds? minutes?)
	bcs loc_537                               ; ...

	org 0x8C44                     
loc_5992  
        tim %10000,sflag1_copy      ; Static value: %11001001	


; ******************************************

	org 0x916C 
loc_638                                          ; ...
        tim %1,flags6                 ; Bit 0: throttle switch (1=idle)
                                      ; Bit 1: high octane
                                      ; Bit 2: neutral switch(1=neutral)
                                      ; Bit 3: power steering switch (1=on)
                                      ; Bit 4: A/C switch (1=on)
                                      ; Bit 7: gear engaged and high gear

; (...)
	org 0x9195 
loc_641                                          ; ...
	ldaa engine_temp_initial      ; Initial engine temp+50 (°C)
	ldab engine_temp              ; Engine temp+50 (°C)
	cmpa #engine_temp_initial_thres
	bcc loc_6067
 
	cmpb afr_const24              ; warm start closed loop temp (above which we go into closed loop after a warm start)
	bcs loc_638

	bra loc_6068
	
	org 0x91A6 
loc_6067                                         ; ...
;	cmpb fb_control               ; O2 sensor "ready" time (after warmup? seconds? minutes?)
					; fb_control is now used in inj_adjust_banks
	cmpb afr_const50               ; O2 sensor "ready" time (after warmup? seconds? minutes?)
	bcs loc_638

	org 0x91AB 
loc_6068                                         ; ...
        tim %10000,sflag1_copy      ; Static value: %11001001        

; ******************************************


	org 0x97F2  
	jsr inj_compute_banks

	org 0x845F                     
	jsr inj_knock_enrichment

	org 0x8462                     
	jsr inj_compute_output

	org 0x97FD
 	jsr inj_compute_warm

	org 0x9807                     
	jsr inj_compute_cold
 


; ******************************************
END_PATCHS
; ******************************************

	org 0xFFFF
	fcb 0xFF	dummy, just to reach 0xFFFF size 	


; --------------------------------------------------------------------------------------------------
	org 0xE380
inj_compute_banks                                ; ...
                     tst inj_counter2
                     beq icb_1
 
                     dec inj_counter2
                     bra icb_6
     
icb_1:                                            ; ...
                     ldab byte_6135                ; Static value: 110
                     tim %100,afr_flags_left
                     beq icb_2
 
                     subb #5                       ; B=105
 
icb_2:                                            ; ...
                     cmpb engine_temp              ; Engine temp+50 (°C)
                     bcc icb_7
 
                     ldab #60
                     tim %100,afr_flags_left
                     beq icb_3
 
                     addb #4
 
icb_3:                                            ; ...
                     cmpb rpm_d4_lo                ; rpm_div_4_lo=lo(Engine speed/50)
                     bcs icb_7
 
                     ldab byte_6136
                     beq icb_5
 
                     tim %100,afr_flags_left
                     bne icb_4
 
                     addb #16
 
icb_4:                                            ; ...
                     cmpb rpm_lo                   ; rpm_lo=min(rpm,255)
                     bcc icb_7
 
 
icb_5:                                            ; ...
                     tim %100,afr_flags_left
                     bne icb_6
 
                     oim %100,afr_flags_left
                     ldaa #$32
                     staa inj_counter2
 
icb_6:                                            ; ...
                     ldx tp_filt                   ; Filtered tp
                     bra icb_8
 
 
icb_7:                                            ; ...
                     aim %11111011,afr_flags_left
                     ldx tp
 
icb_8:                                            ; ...
                     stx tp2
                     ldd inj_pulse_coef
                     jsr mul16_D_X                 ; P1=D=D*X
 
		     xgdx
		    
 		     stx inj_base

; Compute bank 1 ---------------------------------------------------
 
                     tim %1,flags6                ; Bit 0: throttle switch (1=idle)
                                                   ; Bit 1: high octane
                                                   ; Bit 2: neutral switch(1=neutral)
                                                   ; Bit 3: power steering switch (1=on)
                                                   ; Bit 4: A/C switch (1=on)
                                                   ; Bit 7: gear engaged and high gear
                     beq icb_11
 
                     ldd afr_var42
                     bra icb_12
 
 
icb_11:                                           ; ...
                     ldd afr_bank2_coef
 
icb_12:                                           ; ...
                     staa afr_learn_right
                     addd afr_bank1_max
                     sbca #100
                     jsr mul16_D_P1                ; P1=D=D*P1
 
                     addb inj_tot_latency
                     adca #0
                     addd acc_coefx100
                     std inj_bb1
 
; Compute bank 2 ---------------------------------------------------
 
                     tim %1,flags6                ; Bit 0: throttle switch (1=idle)
                                                   ; Bit 1: high octane
                                                   ; Bit 2: neutral switch(1=neutral)
                                                   ; Bit 3: power steering switch (1=on)
                                                   ; Bit 4: A/C switch (1=on)
                                                   ; Bit 7: gear engaged and high gear
                     beq icb_21
 
                     ldd afr_var24
                     bra icb_22
 
 
icb_21:                                           ; ...
                     ldd afr_bank1_coef
 
icb_22:                                           ; ...
                     staa afr_learn_left
                     addd afr_bank2_max
                     sbca #100
                     jsr mul16_D_X                 ; P1=D=D*X
 
                     addb inj_tot_latency
                     adca #0
                     addd acc_coefx100
                     std inj_bb2

#if 1

; Compute bank 1 with no closed loop correction but light correction for banks balancing  --------------
; we don't perform this light correction in idle to avoid any side-effect (e.g. cold startup)


                     tim %1,flags6                 ; Bit 0: throttle switch (1=idle)
                                                   ; Bit 1: high octane
                                                   ; Bit 2: neutral switch(1=neutral)
                                                   ; Bit 3: power steering switch (1=on)
                                                   ; Bit 4: A/C switch (1=on)
                                                   ; Bit 7: gear engaged and high gear
                     beq icb_26
icb_25 	     				           
		     ldd #0x6400		   ; if idle or conditions not met
		        
		     ldx inj_base
		     jsr mul16_D_X                 ; P1=D=D*X
 
                     addb inj_tot_latency
                     adca #0
                     addd acc_coefx100
                     std inj_bb1_nocorrect
                     std inj_bb2_nocorrect   
		     bra icb_40

icb_26
		     ldaa afr_bank2_coef
		     suba #0x64
		     adda afr_bank1_max
		     suba #0x64
 		     ldab afr_bank1_coef
		     subb #0x64
		     addb afr_bank2_max
		     subb #0x64
 
		     sba		      ; A-B -> A
		     bpl icb_30
		     nega
		     
		     cmpa #5
		     bls icb_28
		     ldaa #5
icb_28
		     clrb
		     adda #0x64
		     std inj_b2_balance
		     ldaa #0x64
		     std inj_b1_balance
		     bra icb_35
icb_30
		     cmpa #5
		     bls icb_32
		     ldaa #5
icb_32
		     clrb
		     adda #0x64
		     std inj_b1_balance
		     ldaa #0x64
		     std inj_b2_balance
icb_35
		     ldd inj_b1_balance
		     cmpa inj_b2_balance	   ; balancing is meaningful only if driver side leaner than passenger side
		     bcs icb_25

                     ldx inj_base
		     jsr mul16_D_X                 ; P1=D=D*X
 
                     addb inj_tot_latency
                     adca #0
                     addd acc_coefx100
                     std inj_bb1_nocorrect

	      	     ldd inj_b2_balance

		     jsr mul16_D_X                 ; P1=D=D*X
 
                     addb inj_tot_latency
                     adca #0
                     addd acc_coefx100
                     std inj_bb2_nocorrect
		     
		     ldaa inj_b1_balance	    ; if  values are equal, we reset them as a marker in the log
		     eora inj_b2_balance
		     beq  icb_40
		     rts
icb_40
		     clr inj_b1_balance		   	
		     clr inj_b2_balance 
		     rts
#else

; Compute bank 1&2 with no correction ---------------------------------------------------
 
		     ldd #0x6400

                     ldx inj_base
		     jsr mul16_D_X                 ; P1=D=D*X
 
                     addb inj_tot_latency
                     adca #0
                     addd acc_coefx100
                     std inj_bb1_nocorrect
                     std inj_bb2_nocorrect   
		     rts
#endif		     

 
; End of function inj_compute_banks
 

; --------------------------------------------------------------------------------------------------
	org 0xE500
inj_knock_enrichment:                             ; ...
		     tim %10,flags6              ; Bit 0: throttle switch (1=idle)
                                                   ; Bit 1: high octane
                                                   ; Bit 2: neutral switch(1=neutral)
                                                   ; Bit 3: power steering switch (1=on)
                                                   ; Bit 4: A/C switch (1=on)
                                                   ; Bit 7: gear engaged and high gear
                     bne ike_1

; Cylinder bank 1 ----------------------------------------------------------
 
                     ldd inj_bb1
                     ;lsld
                     asld
		     subb inj_tot_latency
                     sbca #0
                     std inj_b1_temp
 
; Cylinder bank 2 ----------------------------------------------------------

                     ldd inj_bb2
                     ;lsld
		     asld
                     subb inj_tot_latency
                     sbca #0
                     std inj_b2_temp
                     aim %11101111,inj_flags
                     bra ike_2
 
ike_1:                                            ; ...
                     oim %10000,inj_flags
                     ldd inj_bb1
                     std inj_b1_temp
                     ldd inj_bb2
                     std inj_b2_temp
ike_2 
		     ldd inj_b1_temp	      ; store corrected values
		     std inj_b1
		     ldd inj_b2_temp
		     std inj_b2

; AFR not corrected values calculation
		     tim %10,flags6              ; Bit 0: throttle switch (1=idle)
                                                   ; Bit 1: high octane
                                                   ; Bit 2: neutral switch(1=neutral)
                                                   ; Bit 3: power steering switch (1=on)
                                                   ; Bit 4: A/C switch (1=on)
                                                   ; Bit 7: gear engaged and high gear
                     bne ike_5

; Cylinder bank 1 ----------------------------------------------------------
 
                     ldd inj_bb1_nocorrect
                     ;lsld
                     asld
		     subb inj_tot_latency
                     sbca #0
                     std inj_b1_nocorrect
 
; Cylinder bank 2 ----------------------------------------------------------

                     ldd inj_bb2_nocorrect
                     ;lsld
		     asld
                     subb inj_tot_latency
                     sbca #0
                     std inj_b2_nocorrect
                     aim %11101111,inj_flags
                     rts
 
ike_5:                                            ; ...
                     oim %10000,inj_flags
                     ldd inj_bb1_nocorrect
                     std inj_b1_nocorrect
                     ldd inj_bb2_nocorrect
                     std inj_b2_nocorrect
		     rts		     
		     






; End of function inj_knock_enrichment


; --------------------------------------------------------------------------------------------------
	org 0xE580
inj_compute_output:
; in idle, we apply the AFR corrected values to target 14.7 only if real idle conditions are met


		     tim %1,flags6                ; Bit 0: throttle switch (1=idle)
                                                   ; Bit 1: high octane
                                                   ; Bit 2: neutral switch(1=neutral)
                                                   ; Bit 3: power steering switch (1=on)
                                                   ; Bit 4: A/C switch (1=on)
                                                   ; Bit 7: gear engaged and high gear
                     beq ico_00
	     
		     ldaa speed		           ; in real idle only if speed=0
		     bne ico_10
		     ldaa warmup_counter	   ; corrected values only if warmup_counter expired (0xFF)
		     coma
		     beq ico_02
		     bra ico_10
ico_00
		     ldaa engine_temp	           ; when driving, is temp threshold ok for correction ?
        	     cmpa fb_control
		     bcs ico_10		     
		     ldaa tp1		           ; when driving, is TP below TP threshold ?
	             cmpa #max_TP_AFR_correction
	             bcc ico_10

; Working with the corrected values here
ico_02
                     tim %100,flags3             ; Bit 0: PORT5 bit 4 inverted, if 0 then injection cut
                                                   ; Bit 2: Activated once every 2 IRQ2
                                                   ; Bit 3: Compute main maps
                                                   ; Bit 6: Activated once every 10 IRQ2
                                                   ; Bit 7: IRQ2 interrupt active
                     beq ico_4
 
                     tim %1,flags3                ; Bit 0: PORT5 bit 4 inverted, if 0 then injection cut
                                                   ; Bit 2: Activated once every 2 IRQ2
                                                   ; Bit 3: Compute main maps
                                                   ; Bit 6: Activated once every 10 IRQ2
                                                   ; Bit 7: IRQ2 interrupt active
                     beq ico_1
 
                     ldd #1
                     ldx #1
                     bra ico_3
 
 
ico_1:                                            ; ...
                     ldd inj_b1
                     ldx inj_b2
                     lsrd
                     lsrd
                     addd inj_b1
                     xgdx
                     lsrd
                     lsrd
                     addd inj_b2
                     sei
                     tim %10000,inj_flags
                     bne ico_2
 
                     aim %11011111,inj_flags
                     bra ico_3
 
 
ico_2:                                            ; ...
                     oim %100000,inj_flags
 
ico_3:                                            ; ...
                     std inj_bank2
                     stx inj_bank1
 
ico_4:                                            ; ...
                     cli
                     ldaa inj_global_mask
                     anda %10101
                     cmpa %10101
                     bne ico_5
 
                     clra
                     ldab inj_tot_latency
                     bra ico_6
 
 
ico_5:                                            ; ...
                     ldd inj_b1
 
ico_6:                                            ; ...
                     std inj_bbb1
                     ldaa inj_global_mask
                     anda %101010
                     cmpa %101010
                     bne ico_7
 
                     clra
                     ldab inj_tot_latency
                     bra ico_8
 
 
ico_7:                                            ; ...
                     ldd inj_b2
 
ico_8:                                            ; ...
                     std inj_bbb2
                     rts

; Working with the NOT corrected values here
ico_10:
                     tim %100,flags3             ; Bit 0: PORT5 bit 4 inverted, if 0 then injection cut
                                                   ; Bit 2: Activated once every 2 IRQ2
                                                   ; Bit 3: Compute main maps
                                                   ; Bit 6: Activated once every 10 IRQ2
                                                   ; Bit 7: IRQ2 interrupt active
                     beq ico_44
 
                     tim %1,flags3                ; Bit 0: PORT5 bit 4 inverted, if 0 then injection cut
                                                   ; Bit 2: Activated once every 2 IRQ2
                                                   ; Bit 3: Compute main maps
                                                   ; Bit 6: Activated once every 10 IRQ2
                                                   ; Bit 7: IRQ2 interrupt active
                     beq ico_11
 
                     ldd #1
                     ldx #1
                     bra ico_33
 
 
ico_11:                                            ; ...
                     ldd inj_b1_nocorrect
                     ldx inj_b2_nocorrect
                     lsrd
                     lsrd
                     addd inj_b1_nocorrect
                     xgdx
                     lsrd
                     lsrd
                     addd inj_b2_nocorrect
                     sei
                     tim %10000,inj_flags
                     bne ico_22
 
                     aim %11011111,inj_flags
                     bra ico_33
 
 
ico_22:                                            ; ...
                     oim %100000,inj_flags
 
ico_33:                                            ; ...
                     std inj_bank2
                     stx inj_bank1
 
ico_44:                                            ; ...
                     cli
                     ldaa inj_global_mask
                     anda %10101
                     cmpa %10101
                     bne ico_55
 
                     clra
                     ldab inj_tot_latency
                     bra ico_66
 
 
ico_55:                                            ; ...
                     ldd inj_b1_nocorrect
 
ico_66:                                            ; ...
                     std inj_bbb1
                     ldaa inj_global_mask
                     anda %101010
                     cmpa %101010
                     bne ico_77
 
                     clra
                     ldab inj_tot_latency
                     bra ico_88
 
 
ico_77:                                            ; ...
                     ldd inj_b2_nocorrect
 
ico_88:                                            ; ...
                     std inj_bbb2
                     rts

 
; End of function inj_compute_output



; --------------------------------------------------------------------------------------------------
	org 0xE680
inj_compute_warm:                                 ; ...
                     tim %1,inj_flags
                     bne icg_1
 
                     clr warmup_counter
                     oim %1,inj_flags
 
icg_1:                                            ; ...
                     ldx tp
                     ldd inj_pulse_coef
                     jsr mul16_D_X                 ; P1=D=D*X
 
                     ldaa #130
                     jsr mul16_A_P1                ; P1=D=A*(P1+P2/256)
 
                     addb inj_tot_latency
                     adca #0
                     addd acc_coefx100
                     std inj_bb1
                     std inj_bb2
		     std inj_bb1_nocorrect
		     std inj_bb2_nocorrect
                     rts
 
; End of function inj_compute_warm


; --------------------------------------------------------------------------------------------------
	org 0xE700
inj_compute_cold:                                 ; ...
                     ldaa engine_temp2             ; engine_temp*1.6+0.5
                     ldx #inj_temp_coef_map
                     jsr interp_16                 ; X=table adress
                                                   ; A=value to look up
                                                   ; 
                                                   ; A=output value
 
                     staa inj_temp_coef
                     ldab rpm_lo                   ; rpm_lo=min(rpm,255)
                     cmpb #12
                     bls ice_3
 
                     cmpb #48
                     bcc ice_1
 
                     subb #12
                     ldaa #6
                     mul
                     negb
                     bra ice_2
 
 
ice_1:                                            ; ...
                     ldab byte_6134
 
ice_2:                                            ; ...
                     ldaa inj_temp_coef
                     mul
                     staa inj_temp_coef
 
ice_3:                                            ; ...
                     ldab warmup_counter
                     subb #10
                     bls ice_4
 
                     ldaa #20
                     mul
                     negb
                     addb #100
                     bra ice_5
 
 
ice_4:                                            ; ...
                     ldab #100
 
ice_5:                                            ; ...
                     ldaa inj_temp_coef
                     mul
                     xgdx
                     cpx inj_bb1
                     bcs ice_6
 
                     stx inj_bb1
		     stx inj_bb1_nocorrect
		     
 
ice_6:                                            ; ...
                     cpx inj_bb2
                     bcs ice_7
 
                     stx inj_bb2
		     stx inj_bb2_nocorrect
 
ice_7:                                            ; ...
                     rts
 
; End of function inj_compute_cold


; --------------------------------------------------------------------------------------------------
	org 0xE780
reset_afr_learn_maps
                     ldd #$6400
                     std afr_var42
		     std afr_var24
                     ldx #afr_bank1_map
loc_6115:                                         ; ...
                     std 0,x
                     inx
                     inx
                     cpx #afr_bank1_map+0x100
                     bne loc_6115
	
		     rts


	org 0xE7F0      to check potential overlap with the tpu_param_1 table
******************************
VERSION fcc  'AFR v16.4_0'
Attachments
AFR_test_v16.4.zip
(5.9 KiB) Downloaded 205 times
Eric
 

Posts: 227
Joined: Mon Jan 14, 2008 7:59 pm
Location: Holland
Contact:

Re: AFR enhancements: patch routines for Z32

Post by Eric »

thanks !

will give it a try on my 300, which I just got out of storage and MOT'ed for the summer :)
RomChip200
 

Posts: 426
Joined: Mon May 11, 2009 7:58 pm
Location: FRANCE

Re: AFR enhancements: patch routines for Z32

Post by RomChip200 »

Some people complain the no-closed loop area is getting affected by their O2 sensors.
This is normal behaviour from the ECU.
Refer to the routines posted above (basically I have patched the original ones and re-located them in another address range to achieve my purpose, I disabled any AFR correction (but not measurement) except in idle and for bank balancing).

afr_bank1_coef/afr_bank2_coef are applied across all the TP range and are deduced from the self-learn tables that are filled in themselves from the O2 sensors feedback. afr_bank1_coef/afr_bank2_coef are copied in afr_learn_left/afr_learn_right ==> they are the variables called AF Alpha Learn (LHS) / AF Alpha Learn (RHS), the consult regs you can monitor.
afr_var24/afr_var42 are 2 other correction factors that are used in idle.

So, inj_bb1/inj_bb2 are injection pulses for bank1 and bank2 corrected with O2 feedback (if conditions are met).
inj_bb1_nocorrect/inj_bb2_nocorrect are the same but without correction (I added these ones).

In inj_compute_output routine, you can notice I introduced a test to disable AFR correction if TP is above a certain value, inj_b1_nocorrect/inj_b2_nocorrect are used instead of inj_b1/inj_b2 for the final calculation of output pulses to injectors drivers. inj_b1_nocorrect/inj_b2_nocorrect derivate from inj_bb1_nocorrect/inj_bb2_nocorrect.

Code: Select all

ico_00
		     ldaa engine_temp	           ; when driving, is temp threshold ok for correction ?
        	     cmpa fb_control
		     bcs ico_10		     
		     ldaa tp1		           ; when driving, is TP below TP threshold ?
	             cmpa #max_TP_AFR_correction
	             bcc ico_10
(...)

; Working with the NOT corrected values here
ico_10:
                     tim %100,flags3  
(...)

Conclusion ?

If you have O2 feedback enabled and if your values in the closed-loop region are too rich, you will have some correction factors below 100% that will be applied to the no-closed loop region. This may affect driveability in the mid-TP range.
skidder
 

Posts: 13
Joined: Fri Apr 27, 2012 4:41 am

Re: AFR enhancements: patch routines for Z32

Post by skidder »

Hi Romchip.

How have you been able to access that source code? Did you manage to succesfully edit the AFR conditions.

I have an SR20det and i would be very interested in changing the MAX TP at which closed loop operation happens.

Thanks
Post Reply