Toyota GR86, 86, FR-S and Subaru BRZ Forum & Owners Community - FT86CLUB

Toyota GR86, 86, FR-S and Subaru BRZ Forum & Owners Community - FT86CLUB (https://www.ft86club.com/forums/index.php)
-   Software Tuning (https://www.ft86club.com/forums/forumdisplay.php?f=88)
-   -   Open Source Flex Fuel (https://www.ft86club.com/forums/showthread.php?t=94751)

ztan 09-13-2015 05:52 AM

Open Source Flex Fuel
 
***It works***

I filled up at a United station close next to work yesterday and they now have E85 supply there which they didn't have 6 months ago, and do not advertise it on their website.

Having implemented Hybrid Speed Density and Boost Limit Fuel Cut for my car, this is a logical next project which I'll develop openly and collaboratively until we have a solution or I lose interest or my car.

I do this for a hobby, so it need not be said, but ***TRY EVERYTHING AT YOUR OWN RISK*** My time is my own to waste on this project and I do not earn money as a tuner - having said this, I'm happy to take donations via PayPal at esltan@yahoo.com if you find any of the info that I've posted useful.

To do:
Source Hardware: tips at http://www.ecmtuning.com/wiki/ethanolsensorparts
Define Flex Fuel Sensor input method - Posts #3, #5, #11

Develop code to:
Hook the sensor routine - Post #14
Read and scale input to E% - Post #15
Scale PI and GDI separately or together based on E% - Post #31
Scale cranking PW based on E% - Post #32 (v.1), #46 (v.2), #49 (v.3)
Interpolate fuel and timing based on E% - Post #36 (fuel), Post #42(timing)
Apply scaling to display multiplier - Post #50

Extras:
Send E% data to PLX gauge - Post #11, #48
TRAC switch double click to turn off traction control or default to TRAC off - Post #30

email me if you want a copy of any of my files along the way.

ztan 09-13-2015 05:58 AM

Flex Fuel Hardware + Controller.
 
Starting reference: http://www.ecmtuning.com/wiki/ethanolsensorparts

The most commonly available Flex Fuel sensor around the market are the GM ones that send a 50Hz square wave out at E0 and 150Hz out at E100. 190Hz is output for water contamination.

We can buy a controller off the shelf to read the square wave frequency and convert it to a voltage signal that the ECU can read easily: available from any one of the vendors at the moment - saves a lot of time, but where's the fun in that? Alternates are to make our own frequency to voltage controller box or code the ECU to do the frequency analysis internally.

ztan 09-13-2015 06:11 AM

Sensor input connection to ECU
 
5 Attachment(s)
Having seen the E85 at the station yesterday, I went back home and pored over the wiring diagrams and the car.

The two commonly used sensor inputs are the rear oxygen sensor (O2S2) and the Evap pressure sensor. ECU pins as per diagram below (the wiring manual has the connectors as if you were looking end on at the harness plug - they are mirror-imaged when you look at them plugged in to the ECU.

I had a look at the connector AD2 (which is more accessible than the ECU) which joins the ECU to the fuel pump and Evap cannister harness: the wires were not there for the Evap cannister (A01G ROM). It turns out that I am in luck and the ECU does not interrogate Evap Pressure in my A01G car, so I don't need to compensate for losing the signal.

Moving on to connector A35 on the ECU, pin 20 was empty and I decided to hook a wire up to it. Pulled the connector out - it turns out that I could use the Molex pin from a scrap IDE type ribbon cable on this. To do this, lift the retainer on the IDE plug with a pick and pull the connector out. The A35 connector has a horizontal locking tab in the middle - that needs to be pulled out about 2mm, then the IDE Molex pin slides all the way down the barrel and does not come out when the locking tab is replaced. See last picture for new wire placement.

steve99 09-13-2015 06:28 AM

@ztan have you seen this thread opensource ethanol analyser

http://www.ft86club.com/forums/showthread.php?t=79865

ztan 09-13-2015 06:55 AM

Sensor input RAM address
 
A while ago, I had a look at the A01G disassembly to chase down a RAM value for MAF Voltage.

I had listed a whole bunch of potential RAM addresses from disassembling the sensor pull routines still available and did some logging with them all to trace the Evap pressure sensor ADC pin.

Logging all these for A01G:

Evap pressure sensor from 20(A35) voltage 16 bit value is stored at FFF842F8 and the float value sits at FFF87C7C after scaling.

Scaling:
Multiplier at 0011CC38: 137.62
Offset at 0011CC3C: 253.90

Without a connection to a sensor, the voltage is pulled up and logs ~5V (~940mmHg).

O2S2 from 21(A34) sends a 16 bit voltage value to FFF842FA.

I have not verified for other ROMs but the RAM addresses for the sensor pull bit of code tend to be uniform between calibration IDs that I've looked at.
If I'd known that the Evap pressure sensor line was unused in my car prior to installing my wideband, and knew I already had the RAM address sitting in a file to test, I'd have routed it there.

steve99 09-13-2015 08:24 AM

I wonder if its possible to hijack the ECU routine that sends the instantaneous L/100km to the dash display and send the ethanol content instead ?

slowest86 09-13-2015 12:58 PM

This would be awesome!

ztan 09-14-2015 07:46 AM

ECU to measure frequency
 
I've been looking at the ECU datasheet to see if there is a way to use the counter in the ECU to directly measure pulse width off a square wave using the advanced timer unit (ATU III).

Unfortunately, the Evap line 20(A35) connects to the A/D converter at AN_B43 and I can't see that it has a trigger for the ATU directly.

Does anyone know of which pins in the ECU connectors are available to trigger the timer, or does anyone have a disused ECU to post to Australia which I can disassemble to try to trace one? Even a bricked one ok as I just need to trace connector pins to the chip.

ztan 09-25-2015 09:41 AM

So I bricked my ECU testing a routine that would read frequency over the ADC line. Didn't check my programming work thoroughly by running each step through HEW as I have in the past. Part of the routine made a bad call and sent my ECU into a loop as soon as the sensor scan routine is run (almost immediately).

Lesson learned with a new idea - it would be easy enough when testing any new routine to switch into it via defogger switch: if it hangs, the ECU will still communicate for a re-flash with defogger switch off.

Have a new ECU in from dealer recoded to my keys. Will resume this project when a suitable unbrick solution available - I'll start that thread.

bee_are_zee 09-25-2015 10:57 AM

Wow. Sorry to hear that. I would offer help, but am light years behind you on messing with the ecu.

ztan 10-24-2015 10:59 PM

1 Attachment(s)
Having gotten my bricked ECU to talk on the bench again (but not 100% functional) using SHBoot, time to get back up developing.

The Evap sensor routine that I hooked polls the sensor at 60-80ms intervals - too slow to use to read frequency properly in the 50-150Hz range that the GM FlexFuel sensor uses - will convert to 0-5V output to make this work easier on the Evap A35-20 input.

Having a PLX DM6 gauge for wideband display, I decided to use an Arduino Nano ($3 on eBay) to do the following:

1. Read Hz signal from FlexFuel sensor

2. Output 0-5V signal to ECU. The Evap pin is pulled up to 5V without anything attached, so I have initially coded E0 to send 5V and E100 to send 0V

3. Output serial PLX iMFD packet to PLX daisy chain (using Fuel Level sender ID code as I could not find any device ID for a Flex Fuel sensor for the DM6). This needs to be the terminal device in the PLX chain and will display E% as "Fuel Level" on the gauge.

4. Flex fuel sensor can be calibrated using pure gasoline and E85 inputting the frequency reads into the E0 and E85 values in the code before sending to Arduino. The Continental 13577429 sensor that I have reads 55 Hz with gasoline and 131 Hz with E85. I also have a couple of Chinese made 13577379 eBay sensors which have linear output but calibrations are off (80 Hz with gasoline, 150Hz with E85) if anyone wants a cheap working sensor with calibration data, PM me.

Frequency read is based on FreqMeasure library at PJRC

Arduino code and Nano circuit diagram (it all works):
Code:

//Flex Fuel sensor code
//Input frequency on pin 8 - pulled up to 5V through 1.8K resistor
//V_out pin 3 - 0-5V output through 1.8K resistor with 10uf capacitor to ground
//PLX iMFD serial packet on Tx pin 0 through 3.3V TTL voltage divider (3.3K/6.8K)

#include <Arduino.h>
#include <FreqMeasure.h>

double sum = 0;
int count = 0;
int ethanol_int, V_out_int;
float freq, ethanol, V_out, E_scalar;
float E0 = 50; //calibration data for pure gasoline
float E85 = 135; //calibration data for E85
long P0, P1, Pdelta;
byte PLXpacket[7] {0x80, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40};

//PLX iMFD packet, sent every 100ms:
//0x80      Start byte
//0x00 0x11 Sensor device fuel level
//0x00      Sensor instance
//0x00 0x00 Sensor value (integer, unscaled)
//0x40      Stop byte

void setup()
{
  pinMode (3, OUTPUT);
  FreqMeasure.begin();
  Serial.begin(19200);
  P0 = millis();
  E_scalar = (E85 - E0) / 85;
}

void loop()
{
  if (FreqMeasure.available())
  {
    // average several readings together
    sum = sum + FreqMeasure.read();
    count = count + 1;
    if (count > 30)
    {
      freq = FreqMeasure.countToFrequency(sum / count);
      sum = 0;
      count = 0;
    }
  }

  ethanol = (freq - E0) / E_scalar; //scale frequency to E% interpolating E0 and E85 values
  if (ethanol > 100)
  {
    ethanol = 100;
  }
  if (ethanol < 0)
  {
    ethanol = 0;
  }
  ethanol_int = (int)ethanol;

  V_out = 5 - (0.05 * ethanol);
  V_out = 51 * V_out; //scale to 255
  V_out_int = (int)V_out; //convert to integer for analogWrite

  analogWrite(3, V_out_int); //output V_out as PWM voltage on pin 3

  P1 = millis(); //send PLX packet on Tx pin every 100ms
  Pdelta = P1 - P0;
  if (Pdelta >= 100)
  {
    P0 = P1;
    PLXpacket[5] = ethanol_int; //set data byte in PLX packet to E%
    Serial.write(PLXpacket, 7);
  }
}


DustinS 10-26-2015 11:56 AM

Awesome Work! Glad to hear you got the ECU up and (sorta) running. Excited for the results.

myioz86 10-27-2015 08:52 PM

Keep up the good work Ztan have been watching your work for a while now . p.s thanks for the help you gave Shiv with my tune.

ztan 11-03-2015 07:18 AM

Hooking new code into existing routines.
 
This is an example of how to hook code into an existing routine. Not 100% elegant, but there is plenty of free space to work with in our ECUs so I haven't optimized it for space.

Be careful when using the delayed slot instructions (jsr, rts, bra...) if you have any delayed instructions that reference addresses, the results can be quite screwy. The 32 bit instructions instructions in a delayed slot also are not reliable. Use of jsr/n, rts/n makes code more reliable, even though it takes up an extra clock cycle.

Example:

In the A01G ROM, the routine at 2B0E8 in the stock ROM scales sensor voltage data in fr4 according to multiplier and offset (Throttle angle, Accelerator angle, Batt Voltage, MAP sensor, Evap Pressure sensor)
Evap pressure sensor data is read when r6 = 06 and r13 = 0B.
At the end of this block of code, the program then branches to 2B100 with the scaled value stored in fr9.

Code:

ROM:0002B0E8            loc_2B0E8:                              ; CODE XREF: Scale_16_bit_sensor_data_in_table
ROM:0002B0E8 46 08                      shll2  r6              ; Shift Logical Left 2
ROM:0002B0EA 46 00                      shll    r6              ; Shift Logical Left
ROM:0002B0EC D2 21                      mov.l  #off_10E0C, r2  ; Move Immediate Long Data
ROM:0002B0EE 60 63                      mov    r6, r0          ; Move Data
ROM:0002B0F0 06 2E                      mov.l  @(r0,r2), r6    ; Move Long Data
ROM:0002B0F2 F0 68                      fmov.s  @r6, fr0        ; Floating-point move single precision: Multiplier value
ROM:0002B0F4 72 04                      add    #4, r2          ; Add binary
ROM:0002B0F6 06 2E                      mov.l  @(r0,r2), r6    ; Move Long Data
ROM:0002B0F8 F9 68                      fmov.s  @r6, fr9        ; Floating-point move single precision: Offset value
ROM:0002B0FA A0 01                      bra    loc_2B100      ; Branch
ROM:0002B0FC F9 4E                      fmac    fr0, fr4, fr9  ; Floating-point multiply and accumulate: fr9 = fr0(multiplier)*fr4(sensor voltage)+fr9(offset)

This substitute code loads a ROM address for a new subroutine in a patch of empty ROM in place of the old sensor scaling, returning with a sensor value in fr9 before branching to 2B100:

Code:

ROM:0002B0E8            loc_2B0E8:                              ; CODE XREF: sub_2B0A2
ROM:0002B0E8 D2 03                      mov.l  #sub_B97C0, r2  ; Move Immediate Long Data
ROM:0002B0EA 42 4B                      jsr/n  @R2 ; sub_B97C0 ; Jump to Subroutine with No delay slot
ROM:0002B0EC A0 08                      bra    loc_2B100      ; Branch
ROM:0002B0EE 00 09                      nop                    ; No Operation
ROM:0002B0EE            ; ---------------------------------------------------------------------------
ROM:0002B0F0 FF FF FF FF+                .datab.l 2, h'FFFFFFFF
ROM:0002B0F8 00 0B 97 C0 off_2B0F8:      .data.l sub_B97C0      ; DATA XREF: sub_2B0A2:loc_2B0E8
ROM:0002B0FC FF FF                      .datab.b 2, h'FF

The new subroutine at B97C0 replicates the original routine, checks if the Evap sensor is being evaluated; returns immediately if not, and runs on to new code otherwise before returning.

Code:

ROM:000B97C0            sub_B97C0:                              ; CODE XREF: sub_2B0A2
ROM:000B97C0                                                    ; DATA XREF: sub_2B0A2:loc_2B0E8
ROM:000B97C0 4F 22                      sts.l  pr, @-r15      ; Store System Register Long
ROM:000B97C2 46 08                      shll2  r6              ; Shift Logical Left 2
ROM:000B97C4 46 00                      shll    r6              ; Shift Logical Left
ROM:000B97C6 02 10 0E 0C                movi20  #off_10E0C, r2  ; 20-bit immediate data transfer
ROM:000B97CA 60 63                      mov    r6, r0          ; Move Data
ROM:000B97CC 06 2E                      mov.l  @(r0,r2), r6    ; Move Long Data
ROM:000B97CE F0 68                      fmov.s  @r6, fr0        ; Floating-point move single precision: Multiplier value
ROM:000B97D0 72 04                      add    #4, r2          ; Add binary
ROM:000B97D2 06 2E                      mov.l  @(r0,r2), r6    ; Move Long Data
ROM:000B97D4 F9 68                      fmov.s  @r6, fr9        ; Floating-point move single precision: Offset value
ROM:000B97D6 F9 4E                      fmac    fr0, fr4, fr9  ; Floating-point multiply and accumulate: fr9 = fr0(multiplier)*fr4(sensor voltage)+fr9(offset)
ROM:000B97D8 60 D3                      mov    r13, r0        ; Move Data
ROM:000B97DA 88 0B                      cmp/eq  #h'B, r0        ; Compare: Equal: if sensor value being returned is Evap (r13 = 0B), the T bit is set
ROM:000B97DC 8B 2F                      bf      loc_B983E      ; Branch if False:  Branch to return to stack after restoring pr

ROM:000B97DE Write new routines in here... then return to stack after restoring pr (at B983E in this case)

............

ROM:000B983E            loc_B983E:                              ; CODE XREF: sub_B97C0
ROM:000B983E 4F 26                      lds.l  @r15+, pr      ; Load to System Register Long
ROM:000B9840 00 6B                      rts/n                  ; Return from Subroutine with No delay slot


ztan 11-11-2015 08:19 AM

Coding for Ethanol based scalings
 
1 Attachment(s)
Coding for Ethanol based scalings (A01G ROM base)

The code below returns and stores a few values based on ethanol content; will describe how to modify ROM and do cranking comp to use these later on:

The clutch switch has been added to use as a failsafe in case the code added after is no good for testing purposes so fewer ECUs get bricked - the code only executes if clutch is depressed. Change the "branch if true" instruction at B97E6 to "00 09" (nop) to turn this switch off.

Initially the ethanol value in fr9 in passed to fr4 and this value is limited by the Check_Bounds routine at 011260 (max value in fr6 and min value in fr5)

The value returned in fr0 (Ethanol content) is stored to RAM_Ethanol and a Fuelling Multiplier is looked up from that table (E0=1.00, E85=1.40 in linear scale)

This value is used to multiply the PI Injector Flow Scaling BRZ value for Port injector operation and a GDI multiplier that works on GDI pressure multiplier tables A and B (I call this GDI multiplier C).

An interpolating value is then looked up in a table to scale between 2 Primary OL fuelling tables (E0=0.00, E85=1.00).

A further interpolating value is looked up for use between 2 base timing tables (E0=0.00, E85=1.00) which are then added to the Knock Correction advance table which remains un-modified. This interpolation value is multiplied by the AVCS active value (0.00 = AVCS not active (looks up Base Timing A), 1.00 = AVCS active (looks up Base Timing B) to use the E0 map as a AVCS inactive map also.

Theoretical table values input in image below. Please feel free to contribute data to discussion as to how best to scale these multipliers or interpolants to hit optimal fuelling and MBT with the 12.5:1 compression ratios with or without boost.


Code:

000B97DE
000B97DE            Check_Clutch:
000B97DE 02 80 93 9B                movi20  #RAM_Clutch_SW, r2
000B97E2 60 20                      mov.b  @R2, r0
000B97E4 88 00                      cmp/eq  #0, r0          ; Clutch out = 0 (A33-15=12V)
000B97E4                                                    ; Clutch depressed = 1 (A33-15=GND)
000B97E6 89 2A                      bt      loc_B983E
000B97E8
000B97E8            FlexFuel_Scalings:
000B97E8 F4 9C                      fmov    fr9, fr4
000B97EA F5 8D                      fldi0  fr5
000B97EC D2 39                      mov.l  #Check_Bounds, r2
000B97EE D6 36                      mov.l  #Ethanol_Max, r6
000B97F0 42 0B                      jsr    @R2 ; Check_Bounds
000B97F2 F6 68                      fmov.s  @r6, fr6
000B97F4 D8 2C                      mov.l  #RAM_Ethanol, r8
000B97F6 F8 0A                      fmov.s  fr0, @R8
000B97F8 02 10 13 88                movi20  #Pull_2D_A, r2
000B97FC F1 0C                      fmov    fr0, fr1
000B97FE F4 1C                      fmov    fr1, fr4 ; Pull_2D_A
000B9800 D4 38                      mov.l  #Ethanol_Fuelling_Comp_Table, r4
000B9802 42 4B                      jsr/n  @R2 ; Pull_2D_A
000B9804 D4 29                      mov.l  #RAM_Fuelling_Multiplier, r4
000B9806 F4 0A                      fmov.s  fr0, @r4
000B9808 D6 30                      mov.l  #Injector_Flow_Scaling_BRZ, r6
000B980A F6 68                      fmov.s  @r6, fr6
000B980C F6 02                      fmul    fr0, fr6
000B980E D4 28                      mov.l  #RAM_Flex_PI_Scaling, r4
000B9810 F4 6A                      fmov.s  fr6, @r4
000B9812 D6 2F                      mov.l  #GDI_Pressure_Multiplier_C, r6
000B9814 F6 68                      fmov.s  @r6, fr6
000B9816 F6 02                      fmul    fr0, fr6
000B9818 D4 26                      mov.l  #RAM_Flex_GDI_Mult_C, r4
000B981A F4 6A                      fmov.s  fr6, @r4
000B981C 02 10 13 88                movi20  #Pull_2D_A, r2
000B9820 D4 31                      mov.l  #Ethanol_Fuelling_Interp_Table, r4
000B9822 42 0B                      jsr    @R2 ; Pull_2D_A
000B9824 F4 88                      fmov.s  @R8, fr4
000B9826 D4 25                      mov.l  #RAM_Flex_Fuelling_Interpolant, r4
000B9828 F4 0A                      fmov.s  fr0, @r4
000B982A D4 30                      mov.l  #Ethanol_Timing_Interp_Table, r4
000B982C 02 10 13 88                movi20  #Pull_2D_A, r2
000B9830 42 0B                      jsr    @R2 ; Pull_2D_A
000B9832 F4 88                      fmov.s  @R8, fr4
000B9834 D4 22                      mov.l  #RAM_Flex_Timing_Interpolant, r4
000B9836 D2 23                      mov.l  #RAM_AVCS_Timing_Interp, r2
000B9838 F2 28                      fmov.s  @R2, fr2
000B983A F2 02                      fmul    fr0, fr2
000B983C F4 2A                      fmov.s  fr2, @r4
000B983E
000B983E            loc_B983E:                              ; CODE XREF: sub_B97C0
000B983E                                                    ; sub_B97C0
000B983E 4F 26                      lds.l  @r15+, pr
000B9840 00 6B                      rts/n

000B98A4 FF F8 93 9B off_B98A4:      .data.l RAM_Clutch_SW  ; DATA XREF: sub_B97C0:Check_Clutch
000B98A8 FF F8 D4 10 off_B98A8:      .data.l RAM_Ethanol    ; DATA XREF: sub_B97C0
000B98AC FF F8 D4 14 off_B98AC:      .data.l RAM_Fuelling_Multiplier
000B98AC                                                    ; DATA XREF: sub_B97C0
000B98AC                                                    ; sub_B97C0
000B98B0 FF F8 D4 18 off_B98B0:      .data.l RAM_Flex_PI_Scaling ; DATA XREF: sub_B97C0
000B98B4 FF F8 D4 1C off_B98B4:      .data.l RAM_Flex_GDI_Mult_C ; DATA XREF: sub_B97C0
000B98B8 FF F8 D4 20 off_B98B8:      .data.l RAM_Flex_Crank_Comp ; DATA XREF: sub_B97C0
000B98BC FF F8 D4 24 off_B98BC:      .data.l RAM_Flex_Fuelling_Interpolant
000B98BC                                                    ; DATA XREF: sub_B97C0
000B98C0 FF F8 D4 28 off_B98C0:      .data.l RAM_Flex_Timing_Interpolant
000B98C0                                                    ; DATA XREF: sub_B97C0
000B98C0                                                    ; sub_B97C0
000B98C4 FF F8 AD B8 off_B98C4:      .data.l RAM_AVCS_Timing_Interp
000B98C4                                                    ; DATA XREF: sub_B97C0
000B98C8 00 0B 98 DC off_B98C8:      .data.l Ethanol_Max    ; DATA XREF: sub_B97C0
000B98CC 00 10 C6 80 off_B98CC:      .data.l Injector_Flow_Scaling_BRZ
000B98CC                                                    ; DATA XREF: sub_B97C0
000B98D0 00 10 C6 14 off_B98D0:      .data.l GDI_Pressure_Multiplier_C
000B98D0                                                    ; DATA XREF: sub_B97C0
000B98D4 00 01 12 60 off_B98D4:      .data.l Check_Bounds    ; DATA XREF: sub_B97C0
000B98D4                                                    ; sub_B97C0
000B98D8 FF FF FF FF                .data.l h'FFFFFFFF
000B98DC 42 AA 00 00 Ethanol_Max:    .float 85.0            ; DATA XREF: sub_B97C0
000B98DC                                                    ; ROM:off_B98C8
000B98E0 00 0B 99 10 off_B98E0:      .data.l Ethanol_Cranking_Comp_Table
000B98E0                                                    ; DATA XREF: sub_B97C0
000B98E4 00 0B 99 24 off_B98E4:      .data.l Ethanol_Fuelling_Comp_Table
000B98E4                                                    ; DATA XREF: sub_B97C0
000B98E8 00 0B 99 38 off_B98E8:      .data.l Ethanol_Fuelling_Interp_Table
000B98E8                                                    ; DATA XREF: sub_B97C0
000B98E8                                                    ; sub_B97C0
000B98EC 00 0B 99 4C off_B98EC:      .data.l Ethanol_Timing_Interp_Table
000B98EC                                                    ; DATA XREF: sub_B97C0


thambu19 11-11-2015 10:21 AM

@ztan
Any reason you chose to use the DI fuel pressure signal instead of the injector PW to mass scaling like you plan to do for PFI?

Kodename47 11-11-2015 10:53 AM

Quote:

Originally Posted by thambu19 (Post 2448071)
@ztan
Any reason you chose to use the DI fuel pressure signal instead of the injector PW to mass scaling like you plan to do for PFI?

Because it's probably the simplest way and is in effect doing the same thing. Have you looked at how to change direct injection PW yet?

ztan 11-11-2015 06:14 PM

Quote:

Originally Posted by thambu19 (Post 2448071)
@ztan
Any reason you chose to use the DI fuel pressure signal instead of the injector PW to mass scaling like you plan to do for PFI?

The logic behind GDI quantity is not entirely teased out, but the value that I chose for GDI scaling is a single one that acts on both GDI pressure multiplier tables.

Previous open source E85 implementations have multiplied the result in the GDI pressure multiplier tables A and B (Axes are engine load and fuel pressure) to come up with a value that, I understand, approximates DI quantity. I did disassemble the ROM to find the derivation of the axes in another post: http://www.ft86club.com/forums/showthread.php?p=2387636

The value from the GDI pressure multipliers A and B then gets multiplied by a scaling factor (GDI pressure multiplier C which I am using to scale for E85). I believe that this is the scaling factor that changes the number from a fuel quantity to a pulsewidth value.

This raw DI pulsewidth value is then passed to the GDI flow rate table which is what is used to finalize the DI pulsewidth (compensations for quantity on one axis and fuel pressure on the other).

thambu19 11-11-2015 06:41 PM

Quote:

Originally Posted by ztan (Post 2448568)
The logic behind GDI quantity is not entirely teased out, but the value that I chose for GDI scaling is a single one that acts on both GDI pressure multiplier tables.

Previous open source E85 implementations have multiplied the result in the GDI pressure multiplier tables A and B (Axes are engine load and fuel pressure) to come up with a value that, I understand, approximates DI quantity. I did disassemble the ROM to find the derivation of the axes in another post: http://www.ft86club.com/forums/showthread.php?p=2387636

The value from the GDI pressure multipliers A and B then gets multiplied by a scaling factor (GDI pressure multiplier C which I am using to scale for E85). I believe that this is the scaling factor that changes the number from a fuel quantity to a pulsewidth value.

This raw DI pulsewidth value is then passed to the GDI flow rate table which is what is used to finalize the DI pulsewidth (compensations for quantity on one axis and fuel pressure on the other).

Awesome! Thanks for taking the time to explain it. So with this changed we do not have to rescale the MAF for E85 if I am not mistaken.
From experience the MBT spark timing does not shift so much for E85 to command any attention. It is just the actual spark timing that shifts. Some OEMs have MBT spark timing as a table in the ECU which makes it easy for tuners to tune for E85 because you just have to make the Base spark = MBT spark.

steve99 11-11-2015 07:58 PM

@ztan

So theoreticly on an A01G rom i could test this without a flex kit by making up a simple circuit to feed in 0 to 5 volts onto the evap input pin.

Or just a switchable voltage divider with say 0 ,2.5 and 5 v and effectivly map switch between E85 e40 and petrol.

assume you have added an extra Base TimingB and OL fuel map somewhere ?

Shiv@Openflash 11-12-2015 12:28 AM

ztan is a freakin' rock star :party0030:

ztan 11-12-2015 03:18 AM

Quote:

Originally Posted by steve99 (Post 2448676)
@ztan

So theoreticly on an A01G rom i could test this without a flex kit by making up a simple circuit to feed in 0 to 5 volts onto the evap input pin.

Or just a switchable voltage divider with say 0 ,2.5 and 5 v and effectivly map switch between E85 e40 and petrol.

assume you have added an extra Base TimingB and OL fuel map somewhere ?

Yes.
All to be revealed after more testing etc... but in short:

Base Timing A only gets used when AVCS off. FFF8ADB8 reads 0 when inactive (after ECU reset for a couple of minutes) and 1.0 when AVCS active. The value at FFF8ADB8 is use to interpolate between Base Timing A and Base Timing B. My plan is to hijack Base Timing A as E0 and Base Timing B as E85.

Primary OL Fueling map is added to by the OL Fueling additive map on the basis of IAM value (no additive applied when IAM = 1.0, full additive when IAM=0.0). I am going to assume, rightly or wrongly, that folks who are applying this have the nouse to be monitoring IAM and that IAM will not drop far enough below 1.0 to require extra fuel. Hence I would plan to use Primary OL Fueling map for E85 and OL Fueling additive map for E0 with above interpolant values.

It would be quite easy to add in completely new tables for the above, but this is the way I am thinking.

ztan 11-12-2015 03:27 AM

Quote:

Originally Posted by thambu19 (Post 2448588)
Awesome! Thanks for taking the time to explain it. So with this changed we do not have to rescale the MAF for E85 if I am not mistaken.
From experience the MBT spark timing does not shift so much for E85 to command any attention. It is just the actual spark timing that shifts. Some OEMs have MBT spark timing as a table in the ECU which makes it easy for tuners to tune for E85 because you just have to make the Base spark = MBT spark.

No MAF rescaling needed - we have reasonably good fuel control, although a little more complex due to having DI and PI systems to understand, and there are a lot of compensations applied to these values which are not clearly defined.

Unfortunately MBT spark is not visible in the ROM that I can find. I assume Shiv's E85 NA ROM will be pretty close on the money and hopefully we get some more data on where MBT lies higher in the load range on boosted engines in the future.

steve99 11-12-2015 09:26 AM

@ztan

For E85 cranking @Wayno s tables are very reliable even on united E85

E85 Cranking changes

0C/32F stock values multiplied x 1.5
10C/50F stock values multiplied x 2.0
20C/68F stock values multiplied x 2.0
30C/86F stock values multiplied x 1.3
40C/104F stock values multiplied x 1.2
50C/122F stock values multiplied x 1.1
60C/140F stock values multiplied x 1.05


http://www.ft86club.com/forums/attac...1&d=1442118398



For Dash fuel display multiply be 33% ie same ratio as GDI pressure multiplier offset or PI injector scaling offset.

http://www.ft86club.com/forums/attac...1&d=1442115733

ztan 11-12-2015 04:23 PM

Quote:

Originally Posted by steve99 (Post 2449144)
@ztan

For E85 cranking @Wayno s tables are very reliable even on united E85

E85 Cranking changes

0C/32F stock values multiplied x 1.5
10C/50F stock values multiplied x 2.0
20C/68F stock values multiplied x 2.0
30C/86F stock values multiplied x 1.3
40C/104F stock values multiplied x 1.2
50C/122F stock values multiplied x 1.1
60C/140F stock values multiplied x 1.05

Thanks, and thanks for the donation mate.

My idea is to hijack the IAT cranking compensation table (returns 1.0 across the board for all IAT values) part of the routine and use that as an ECT cranking compensation. This sits just below the accel cranking compensation in the code (the latter table returns 0.0 when the accelerator is fully down when cranking and no fuel is delivered).

I am thinking:
We want a cranking multiplier of 1.0 with E0 and ECT compensation to be applied with higher E%, based on the Flex scaling multiplier.

One way to do the maths is to return a multiplier of 1.0+((Flex scaling multiplier - 1.0)*ECT cranking multiplier). At E85 with a Flex scaling multiplier of 1.4, this would give us a cranking multiplier of 1.4 at 20C with the table that I posted in post #15. A table value of 2.5 would return 2.0 as a cranking multiplier.

ztan 11-12-2015 04:27 PM

Quote:

Originally Posted by steve99 (Post 2449144)
For Dash fuel display multiply be 33% ie same ratio as GDI pressure multiplier offset or PI injector scaling offset.

http://www.ft86club.com/forums/attac...1&d=1442115733

This one is easy - get the normal table return and multiply it by the Flex scaling multiplier. The code would involve hooking the table lookup, scaling with multiplier and returning with all the values in the expected registers.

steve99 11-12-2015 09:24 PM

Quote:

Originally Posted by ztan (Post 2449587)
Thanks, and thanks for the donation mate.

My idea is to hijack the IAT cranking compensation table (returns 1.0 across the board for all IAT values) part of the routine and use that as an ECT cranking compensation. This sits just below the accel cranking compensation in the code (the latter table returns 0.0 when the accelerator is fully down when cranking and no fuel is delivered).

I am thinking:
We want a cranking multiplier of 1.0 with E0 and ECT compensation to be applied with higher E%, based on the Flex scaling multiplier.

One way to do the maths is to return a multiplier of 1.0+((Flex scaling multiplier - 1.0)*ECT cranking multiplier). At E85 with a Flex scaling multiplier of 1.4, this would give us a cranking multiplier of 1.4 at 20C with the table that I posted in post #15. A table value of 2.5 would return 2.0 as a cranking multiplier.

Their is also another Cranking compensation table relative to Intake Air Temp, in stock roms its all zero.

It might be easier to rescale and offset the IAT vs Cranking IPW table rarther than the cranking Vs Coolant tables.

have you seen kodename47 defs he has intergrated the opensource stuff with Ecutek stuff
http://www.ft86club.com/forums/showp...&postcount=411

ztan 11-12-2015 11:55 PM

Quote:

Originally Posted by steve99 (Post 2449939)
Their is also another Cranking compensation table relative to Intake Air Temp, in stock roms its all zero.

I use Kodename47s defs which get modified each time I disassemble something that makes more sense in my head. I haven't actually kept track of which tables I've altered and which I haven't...

That IAT cranking compensation table that reads 0.0 in Kodename47's def means 0% compensation applied. When looking at the disassembly and running that bit of code through the HEW simulator, that table returns a value of 1.0 (scaling factor 1.0 = 0% compensation). I changed my def to suit as well as started thinking in terms of scaling factors rather than % compensation.

Kodename47 11-13-2015 04:35 AM

Quote:

Originally Posted by ztan (Post 2450053)
When looking at the disassembly and running that bit of code through the HEW simulator, that table returns a value of 1.0 (scaling factor 1.0 = 0% compensation). I changed my def to suit as well as started thinking in terms of scaling factors rather than % compensation.

That's how ECUtek is and how I have my own, I much prefer it as a ratio/multiplier than a +/- % value. I just converted them too % as that's what seems to be common and everyone is used to.

As you say, it's also how the tables actually are in the ROMs so it's easier when looking through the likes of ScoobyROM or WInOLS to pick out the tables.

In case you didn't have it this is my up-to-date A01G with ratios and metric values.

ztan 11-15-2015 01:30 AM

TRAC switch doubleclick
 
2 Attachment(s)
Off topic, but related.

With the Arduino Nano going in as a FlexFuel Sensor controller, there is space for much more to be added on. I decided to make a doubleclick TRAC control switch so I don't have to hold down the TRAC switch down for 3+ seconds to turn if off. Simple code and adds 2 resistors and an NPN transistor to the circuitry.

If you want it on by default, set initial button state to 4, which acts as a doubleclick a certain time (TRAC_initializeDelay) after power on.

Why not the full pedal dance? Mine is a street car and we in Australia can't use the speeds on road which people have issues with VSC activating brakes at, requiring the pedal dance to be used or sent over CANBUS like with OFT. Out of interest, can anyone share the CAN sequence needed for pedal dance active?

Code, schematic, and picture of controller box with FlexFuel sensor leads, TRAC switch leads, PLX serial interface.

Updated Arduino code:
Code:

//Flex Fuel sensor code
//Input frequency on pin 8 - pulled up to 5V through 1.8K resistor
//V_out pin 3 - 0-5V output through 1.8K resistor with 10uf capacitor to ground
//PLX iMFD serial packet on Tx pin 0 through 3.3V TTL voltage divider (3.3K/6.8K)

//TRAC double click code
//Input switch on pin 6 - pulled up to 5V through 3.3K resistor
//Output on pin 10 through NPN transistor to take VSC connection to ground

#include <Arduino.h>
#include <FreqMeasure.h>

//FlexFuel sensor
double sum = 0;
int count = 0;
int ethanol_int, V_out_int;
float freq, ethanol, V_out, E_scalar;
float E0 = 50; //calibration data for pure gasoline
float E85 = 135; //calibration data for E85

//PLX data
long P0, P1, Pdelta;
byte PLXpacket[7] {0x80, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40};

//PLX iMFD packet, sent every 100ms:
//0x80      Start byte
//0x00 0x11 Sensor device fuel level
//0x00      Sensor instance
//0x00 0x00 Sensor value (integer, unscaled)
//0x40      Stop byte

//TRAC switch double click
bool TRAC_buttonMonitor = HIGH;
int debounce = 20;
int doubleClick = 200;
int longClick = 3500;
int TRAC_initializeDelay = 5000;
int TRAC_buttonState = 0; //initialize to 0 for normal operation, 4 for on by default after delay
long TRAC_buttonCounter = 0;


void setup()
{
  pinMode (3, OUTPUT);
  pinMode (10, OUTPUT);
  digitalWrite (10, LOW);
  pinMode (6, INPUT);

  FreqMeasure.begin();
  Serial.begin(19200);
  P0 = millis();
  E_scalar = (E85 - E0) / 85;
}

void loop()
{

  //Read FlexFuel sensor frequency
  if (FreqMeasure.available())
  {
    // average several readings together
    sum = sum + FreqMeasure.read();
    count = count + 1;
    if (count > 30)
    {
      freq = FreqMeasure.countToFrequency(sum / count);
      sum = 0;
      count = 0;
    }
  }

  //Convert frequency to E%

  ethanol = (freq - E0) / E_scalar; //scale frequency to E% interpolating E0 and E85 values
  if (ethanol > 100)
  {
    ethanol = 100;
  }
  if (ethanol < 0)
  {
    ethanol = 0;
  }
  ethanol_int = (int)ethanol;

  //FlexFuel voltage output

  V_out = 5 - (0.05 * ethanol);
  V_out = 51 * V_out; //scale to 255
  V_out_int = (int)V_out; //convert to integer for analogWrite

  analogWrite(3, V_out_int); //output V_out as PWM voltage on pin 3

  //PLX data packet

  P1 = millis(); //send PLX packet on Tx pin every 100ms
  Pdelta = P1 - P0;
  if (Pdelta >= 100)
  {
    P0 = P1;
    PLXpacket[5] = ethanol_int; //set data byte in PLX packet to E%
    Serial.write(PLXpacket, 7);
  }

  //TRAC switch doubleclick

  TRAC_buttonMonitor = digitalRead(6);
  switch (TRAC_buttonState)
  {
    case 0: //inactive

      if (TRAC_buttonMonitor == LOW)  // button pressed
      {
        digitalWrite (10, HIGH); //Transistor on
        TRAC_buttonState = 1; //increment state
      }
      break;

    case 1: //check for release
      if (TRAC_buttonMonitor == HIGH) //if button released
      {
        TRAC_buttonCounter = millis(); //start counter
        TRAC_buttonState = 2; //increment state
      }
      break;

    case 2: //wait for doubleClick
      if (TRAC_buttonMonitor == LOW && (millis() - TRAC_buttonCounter) > debounce && (millis() - TRAC_buttonCounter) < doubleClick) //second click registered
      {
        TRAC_buttonState = 3; //increment state
      }
      else if ((millis() - TRAC_buttonCounter) > doubleClick)
      {
        digitalWrite (10, LOW); //Transistor off
        TRAC_buttonState = 0; //reset state
      }
      break;

    case 3: //doubleClick made
      if ((millis() - TRAC_buttonCounter) > longClick)
      {
        digitalWrite (10, LOW); //Transistor off
        TRAC_buttonState = 0; //reset state
      }
      break;

    case 4: //initialize after delay by default
      if (millis() > TRAC_initializeDelay)
      {
        digitalWrite (10, HIGH); //Transistor on
        TRAC_buttonCounter = millis(); //start counter
        TRAC_buttonState = 3; //set state to doubleClick
      }
      break;
  }

}


ztan 11-18-2015 07:03 AM

Applying scalings to injector routines
 
Having calculated a fuelling multiplier based on E% and scaling the stock PI (Injector scaling BRZ) and DI (DI pressure multiplier C) multiplier values in the routine described above in post #15, we need to get these values read in the fueling routines.

In the previous code, the following values are shown in the data segment following the code:
Code:

000B98B0 FF F8 D4 18 off_B98B0:      .data.l RAM_Flex_PI_Scaling ; DATA XREF: sub_B97C0
000B98B4 FF F8 D4 1C off_B98B4:      .data.l RAM_Flex_GDI_Mult_C ; DATA XREF: sub_B97C0
000B98CC 00 10 C6 80 off_B98CC:      .data.l Injector_Flow_Scaling_BRZ
000B98CC                                                    ; DATA XREF: sub_B97C0
000B98D0 00 10 C6 14 off_B98D0:      .data.l GDI_Pressure_Multiplier_C
000B98D0                                                    ; DATA XREF: sub_B97C0

The PI injector scaling is at 10C680 and the DI multiplier is at 10C614

What we need to do is find where in the ROM these values exist to be referenced and change them to point to our Flex Fuel scalars in RAM (FFF8D418 for PI and FFF8D41C for DI).

This is as simple as searching for 0010C680 and replacing with FFF8D418 (6 instances) and 0010C614 and replacing with FFF8D41C (1 instance). All these instances are referenced by code appropriately:
Code:

Address      Function  Instruction                     
-------      --------  -----------                     
ROM:0003D260          .data.l Injector_Flow_Scaling_BRZ
ROM:0003F7FC          .data.l Injector_Flow_Scaling_BRZ
ROM:00058528          .data.l Injector_Flow_Scaling_BRZ
ROM:00058AF0 sub_585FC .data.l Injector_Flow_Scaling_BRZ
ROM:0007B938          .data.l Injector_Flow_Scaling_BRZ
ROM:000A779C sub_A7280 .data.l Injector_Flow_Scaling_BRZ

Address      Function Instruction                     
-------      -------- -----------                     
ROM:0005763C          .data.l GDI_Pressure_Multiplier_C


ztan 11-24-2015 05:39 AM

Cranking Compensations
 
Edit ***This v.1 code has not worked the way I thought - I get an appropriate multiplier and this does not get applied to the cranking fuel. Error due to delay in Arduino reading ethanol. v.2 code in Post #46, v.3 code in Post #49. ***

For this, we'll hijack the IAT cranking compensation lookup table which normally returns 1.0 for all IAT temperatures. There are two references to the IAT cranking compensation lookup table and we'll hook both to insert an ECT based cranking multiplier which is scaled by the Flex Fuelling multiplier.

Stock code location A:
Code:

ROM:00057880            loc_57880:                              ; CODE XREF: Cranking_Fuelling_Comp
ROM:00057880 D4 24                      mov.l  #stru_B424C, r4
ROM:00057882 D6 21                      mov.l  #Pull_2D_A, r6
ROM:00057884 46 0B                      jsr    @r6 ; Pull_2D_A
ROM:00057886 F4 EC                      fmov    fr14, fr4
ROM:00057888 3D 01 30 02                fmov.s  fr0, @((RAM_Cranking_Comp_Accel - RAM_Cranking_Comp),r13)
ROM:0005788C
ROM:0005788C            loc_5788C:                              ; CODE XREF: Cranking_Fuelling_Comp
ROM:0005788C D4 22                      mov.l  #Table_Cranking_Fuel_IPW_Compensation_IAT, r4
ROM:0005788E D6 1E                      mov.l  #Pull_2D_A, r6
ROM:00057890 46 0B                      jsr    @r6 ; Pull_2D_A
ROM:00057892 F4 FC                      fmov    fr15, fr4
ROM:00057894 3D 01 30 03                fmov.s  fr0, @((RAM_Cranking_Comp_IAT - RAM_Cranking_Comp),r13)
ROM:00057898 B0 05                      bsr    Apply_Cranking_Compensation
ROM:0005789A 64 E3                      mov    r14, r4
ROM:0005789C FD 0A                      fmov.s  fr0, @r13

ROM:00057918 00 0B 42 20 off_57918:      .data.l Table_Cranking_Fuel_IPW_Compensation_IAT
ROM:00057918                                                    ; DATA XREF: Cranking_Fuelling_Comp:loc_5788C

Flex Fuel Code Location A:
Code:

00057880            loc_57880:                              ; CODE XREF: Cranking_Compensations
00057880 D4 24                      mov.l  #off_B424C, r4
00057882 D6 21                      mov.l  #Pull_2D_A, r6
00057884 46 0B                      jsr    @r6 ; Pull_2D_A
00057886 F4 EC                      fmov    fr14, fr4
00057888 3D 01 30 02                fmov.s  fr0, @((RAM_Cranking_Comp_Accel - Cranking_Final),r13)
0005788C
0005788C            loc_5788C:                              ; CODE XREF: Cranking_Compensations
0005788C D2 22                      mov.l  #FlexFuel_Cranking_Comp, r2
0005788E 04 80 90 A4                movi20  #RAM_ECT, r4
00057892 42 4B                      jsr/n  @R2 ; FlexFuel_Cranking_Comp
00057894 3D 01 30 03                fmov.s  fr0, @((RAM_Cranking_Comp_Flex_Fuel - Cranking_Final),r13)
00057898 B0 05                      bsr    sub_578A6
0005789A 64 E3                      mov    r14, r4
0005789C FD 0A                      fmov.s  fr0, @((Cranking_Final - Cranking_Final),r13)

00057918 00 0B 98 70 off_57918:      .data.l FlexFuel_Cranking_Comp
00057918                                                    ; DATA XREF: Cranking_Compensations:loc_5788C

000B9870            FlexFuel_Cranking_Comp:                ; CODE XREF: Cranking_Compensations
000B9870                                                    ; Cranking_Compensations_0
000B9870                                                    ; DATA XREF: ...
000B9870 4F 22                      sts.l  pr, @-r15
000B9872 F4 48                      fmov.s  @r4, fr4        ; r4=ECT
000B9874 02 10 13 88                movi20  #Pull_2D_A, r2
000B9878 D4 19                      mov.l  #Ethanol_Cranking_Comp_Table, r4 ; Pull_2D_A
000B987A 42 4B                      jsr/n  @R2 ; Pull_2D_A
000B987C D4 0E                      mov.l  #RAM_Flex_Crank_Comp, r4
000B987E F5 9D                      fldi1  fr5
000B9880 D6 0A                      mov.l  #RAM_Flex_Fuelling_Multiplier, r6
000B9882 F4 68                      fmov.s  @r6, fr4
000B9884 F4 51                      fsub    fr5, fr4        ; fr4-1.0
000B9886 F5 4E                      fmac    fr0, fr4, fr5  ; 1+(crank_comp*(fuelling multiplier-1))
000B9888 F0 5C                      fmov    fr5, fr0
000B988A F4 0A                      fmov.s  fr0, @r4
000B988C 4F 26                      lds.l  @r15+, pr
000B988E 00 6B                      rts/n

Stock code location B:
Code:

ROM:00057F4C D4 18                      mov.l  #Table_Cranking_Fuel_IPW_Compensation_Accelerator, r4
ROM:00057F4E D2 17                      mov.l  #Pull_2D_A, r2
ROM:00057F50 42 0B                      jsr    @R2 ; Pull_2D_A
ROM:00057F52 F4 EC                      fmov    fr14, fr4
ROM:00057F54 FC 0C                      fmov    fr0, fr12
ROM:00057F56 D4 17                      mov.l  #Table_Cranking_Fuel_IPW_Compensation_IAT, r4
ROM:00057F58 D2 14                      mov.l  #Pull_2D_A, r2
ROM:00057F5A 42 0B                      jsr    @R2 ; Pull_2D_A
ROM:00057F5C F4 FC                      fmov    fr15, fr4
ROM:00057F5E FE 0C                      fmov    fr0, fr14

ROM:00057FB4 00 0B 42 20 off_57FB4:      .data.l Table_Cranking_Fuel_IPW_Compensation_IAT
ROM:00057FB4                                                    ; DATA XREF: sub_57F00

Flex Fuel Code Location B:
Code:

00057F4C D4 18                      mov.l  #Table_Cranking_Fuel_IPW_Compensation_Accelerator, r4
00057F4E D2 17                      mov.l  #Pull_2D_A, r2
00057F50 42 0B                      jsr    @R2 ; Pull_2D_A
00057F52 F4 EC                      fmov    fr14, fr4
00057F54 FC 0C                      fmov    fr0, fr12
00057F56 D2 17                      mov.l  #FlexFuel_Cranking_Comp, r2
00057F58 04 80 90 A4                movi20  #RAM_ECT, r4 ; FlexFuel_Cranking_Comp
00057F5C 42 4B                      jsr/n  @R2 ; FlexFuel_Cranking_Comp
00057F5E FE 0C                      fmov    fr0, fr14

00057FB4 00 0B 98 70 off_57FB4:      .data.l FlexFuel_Cranking_Comp
00057FB4                                                    ; DATA XREF: Cranking_Compensations_0

000B9870            FlexFuel_Cranking_Comp:                ; CODE XREF: Cranking_Compensations
000B9870                                                    ; Cranking_Compensations_0
000B9870                                                    ; DATA XREF: ...
000B9870 4F 22                      sts.l  pr, @-r15
000B9872 F4 48                      fmov.s  @r4, fr4        ; r4=ECT
000B9874 02 10 13 88                movi20  #Pull_2D_A, r2
000B9878 D4 19                      mov.l  #Ethanol_Cranking_Comp_Table, r4 ; Pull_2D_A
000B987A 42 4B                      jsr/n  @R2 ; Pull_2D_A
000B987C D4 0E                      mov.l  #RAM_Flex_Crank_Comp, r4
000B987E F5 9D                      fldi1  fr5
000B9880 D6 0A                      mov.l  #RAM_Flex_Fuelling_Multiplier, r6
000B9882 F4 68                      fmov.s  @r6, fr4
000B9884 F4 51                      fsub    fr5, fr4        ; fr4-1.0
000B9886 F5 4E                      fmac    fr0, fr4, fr5  ; 1+(crank_comp*(fuelling multiplier-1))
000B9888 F0 5C                      fmov    fr5, fr0
000B988A F4 0A                      fmov.s  fr0, @r4
000B988C 4F 26                      lds.l  @r15+, pr
000B988E 00 6B                      rts/n


thambu19 11-24-2015 08:04 AM

@ztan I wish I could help out but this is way over my league.. Keep up the great work!!!

ztan 11-30-2015 11:20 PM

Beta testing
 
2 Attachment(s)
It Works!!!

Early beta testing, still need to post up fuelling and timing interpolation code, verify reasonable use of multipliers.

Have filled up to E20 (up to E35 with E85 sitting in the tank before mixing in with residual fuel) and using a E85 multiplier of 1.35, trims look quite stable at present.

DannyQ86 11-30-2015 11:25 PM

Great job man, this is also way out of my league but great to have contributors like yourself and steve99 on this forum.

ztan 12-01-2015 04:49 AM

Flex Fuel Primary OL fuelling
 
1 Attachment(s)
This one is tricky.

I've used the routine for Primary OL enrichment lookup and assigned that to E85. The OL additive is a table that gets used normally when IAM < 1.0 and I've used that for an E0 table. The modified code is also a bit longer than the original and overlaps (by 2 bytes) a routine that is not used in stock A01G.

Stock code:
Code:

ROM:00061420 D6 67                      mov.l  #byte_114663, r6 ; Move Immediate Long Data
ROM:00061422 62 60                      mov.b  @r6, r2        ; r2=0
ROM:00061424 22 28                      tst    r2, r2          ; Test Logical
ROM:00061426 8B 3A                      bf      Not_Used        ; T
ROM:00061426
ROM:00061428 D6 66                      mov.l  #byte_10C319, r6 ; Move Immediate Long Data
ROM:0006142A 60 60                      mov.b  @r6, r0        ; r0=0
ROM:0006142C 88 5A                      cmp/eq  #h'5A, r0 ; 'Z' ; Compare: Equal
ROM:0006142E 89 18                      bt      Not_Used_1      ; Branch if True
ROM:0006142E
ROM:00061430 D4 65                      mov.l  #Table_Primary_Open_Loop_Fueling, r4 ; Move Immediate Long Data
ROM:00061432 D2 66                      mov.l  #Pull_3D_A, r2  ; Move Immediate Long Data
ROM:00061434 34 F1 70 01                fmov.s  @(4,r15), fr4  ; Floating-point move single precision
ROM:00061438 42 0B                      jsr    @R2 ; Pull_3D_A ; Jump to Subroutine
ROM:0006143A F5 F8                      fmov.s  @r15, fr5      ; Floating-point move single precision
ROM:0006143A
ROM:0006143C 3F 01 30 03                fmov.s  fr0, @(h'C,r15) ; Floating-point move single precision
ROM:00061440 D4 63                      mov.l  #Table_Primary_Open_Loop_Fueling_Additive, r4 ; Move Immediate Long Data
ROM:00061442 F7 F8                      fmov.s  @r15, fr7      ; Floating-point move single precision
ROM:00061444 34 F1 70 01                fmov.s  @(4,r15), fr4  ; Floating-point move single precision
ROM:00061448 D2 60                      mov.l  #Pull_3D_A, r2  ; Move Immediate Long Data
ROM:0006144A 42 0B                      jsr    @R2 ; Pull_3D_A ; Jump to Subroutine
ROM:0006144C F5 7C                      fmov    fr7, fr5        ; Floating-point move
ROM:0006144C
ROM:0006144E 3A 01 30 16                fmov.s  fr0, @((flt_FFF8A8FC - flt_FFF8A8A4),r10) ; Floating-point move single precision
ROM:00061452 F0 9D                      fldi1  fr0            ; fr0=1.0
ROM:00061454 F0 D1                      fsub    fr13, fr0      ; fr0=1.0-IAM
ROM:00061456 35 F1 70 03                fmov.s  @(h'C,r15), fr5 ; fr5= return from Primary OL table
ROM:0006145A 39 A1 70 16                fmov.s  @((flt_FFF8A8FC - flt_FFF8A8A4),r10), fr9 ; fr9=return from primary open loop additive table
ROM:0006145E A0 4D                      bra    loc_614FC      ; Branch
ROM:00061460 F5 9E                      fmac    fr0, fr9, fr5  ; fr5=fr0*fr9+fr5

Flex Fuel code:
Code:

00061420 D6 01                      mov.l  #RAM_Flex_Fuelling_Interpolant, r6
00061422 A0 05                      bra    loc_61430
00061424 F8 68                      fmov.s  @r6, fr8
00061424            ; ---------------------------------------------------------------------------
00061426 FF FF                      .data.w h'FFFF
00061428 FF F8 D4 24 off_61428:      .data.l RAM_Flex_Fuelling_Interpolant
00061428                                                    ; DATA XREF: sub_613A2
0006142C FF FF FF FF                .data.l h'FFFFFFFF
00061430            ; ---------------------------------------------------------------------------
00061430
00061430            loc_61430:                              ; CODE XREF: sub_613A2
00061430 D4 65                      mov.l  #Table_Primary_OL_Fueling_E85, r4
00061432 D2 66                      mov.l  #Pull_3D_A, r2
00061434 34 F1 70 01                fmov.s  @(4,r15), fr4  ; Load
00061438 42 0B                      jsr    @R2 ; Pull_3D_A
0006143A F5 F8                      fmov.s  @r15, fr5      ; RPM
0006143C 3F 01 30 03                fmov.s  fr0, @(h'C,r15) ; Primary OL Fuelling E85 result
00061440 D4 63                      mov.l  #Table_Primary_OL_Fueling_E0, r4
00061442 F7 F8                      fmov.s  @r15, fr7      ; RPM
00061444 34 F1 70 01                fmov.s  @(4,r15), fr4  ; Load
00061448 D2 60                      mov.l  #Pull_3D_A, r2
0006144A 42 0B                      jsr    @R2 ; Pull_3D_A
0006144C F5 7C                      fmov    fr7, fr5        ; RPM
0006144E 3A 01 30 16                fmov.s  fr0, @((RAM_Primary_OL_E0_Result - flt_FFF8A8A4),r10)
00061452 F0 9D                      fldi1  fr0            ; fr0=1.0
00061454 F0 81                      fsub    fr8, fr0        ; fr0=1.0-FF_interpolant
00061456 35 F1 70 03                fmov.s  @(h'C,r15), fr5 ; fr5= return from Primary OL E85 table
0006145A 39 A1 70 16                fmov.s  @((RAM_Primary_OL_E0_Result - flt_FFF8A8A4),r10), fr9 ; fr9=return from primary OL E0 table
0006145E F5 82                      fmul    fr8, fr5        ; fr5=Primary OL E85 * FF_Interpolant
00061460 A0 4C                      bra    loc_614FC
00061462 F5 9E                      fmac    fr0, fr9, fr5  ; (1-FF_interpolant)*(Primary_OL_E0) + (FF_interpolant*Primary_OL_E85)

Besides interpolating an enrichment factor between the two tables, a table header re-definition for the OL additive also needs to occur to change the offset value of the table.

Stock table defs:
Code:

ROM:000B5854 00 0D 00 17 Table_Primary_Open_Loop_Fueling:Table_Type <h'D, 0, h'17>
ROM:000B5854                                                    ; DATA XREF: sub_613A2
ROM:000B5854                                                    ; sub_613A2
ROM:000B5858 00 11 14 34                .data.l Primary_Open_Loop_Fueling_X_Axis
ROM:000B585C 00 11 14 68                .data.l Primary_Open_Loop_Fueling_Y_Axis
ROM:000B5860 00 11 14 C4                .data.l Primary_Open_Loop_Fueling
ROM:000B5864 04 00                      .data.w h'400
ROM:000B5866 00 00                      .data.w 0
ROM:000B5868 3C 00 00 00                .float 0.0078125
ROM:000B586C 00 00 00 00                .float 0.0

ROM:000B588C 00 0D 00 17 Table_Primary_Open_Loop_Fueling_Additive:Table_Type <h'D, 0, h'17>
ROM:000B588C                                                    ; DATA XREF: sub_613A2
ROM:000B588C                                                    ; sub_613A2:off_615D0
ROM:000B5890 00 11 16 04                .data.l unk_111604
ROM:000B5894 00 11 16 38                .data.l unk_111638
ROM:000B5898 00 11 16 94                .data.l Primary_Open_Loop_Fueling_Additive
ROM:000B589C 04 00                      .data.w h'400
ROM:000B589E 00 00                      .data.w 0
ROM:000B58A0 3C 00 00 00                .float 0.0078125
ROM:000B58A4 BF 80 00 00                .float -1.0

Modified table defs:
Code:

000B5854 00 0D 00 17 Table_Primary_OL_Fueling_E85:Table_Type <h'D, 0, h'17>
000B5854                                                    ; DATA XREF: sub_613A2:loc_61430
000B5854                                                    ; sub_613A2:off_615C8
000B5858 00 11 14 34                .data.l Primary_Open_Loop_Fueling_X_Axis
000B585C 00 11 14 68                .data.l Primary_Open_Loop_Fueling_Y_Axis
000B5860 00 11 14 C4                .data.l Primary_Open_Loop_Fueling
000B5864 04 00 00 00                .data.l h'4000000
000B5868 3C 00 00 00                .float 0.0078125
000B586C 00 00 00 00                .float 0.0

000B588C 00 0D 00 17 Table_Primary_OL_Fueling_E0:Table_Type <h'D, 0, h'17>
000B588C                                                    ; DATA XREF: sub_613A2
000B588C                                                    ; sub_613A2:off_615D0
000B5890 00 11 16 04                .data.l Primary_Open_Loop_Fueling_Additive_X_Axis
000B5894 00 11 16 38                .data.l Primary_Open_Loop_Fueling_Additive_Y_Axis
000B5898 00 11 16 94                .data.l Primary_Open_Loop_Fueling_Additive
000B589C 04 00 00 00                .data.l h'4000000
000B58A0 3C 00 00 00                .float 0.0078125
000B58A4 00 00 00 00                .float 0.0


slowest86 12-01-2015 07:14 AM

Awesome progress man. Keep up the good work!

Shiv@Openflash 12-02-2015 08:05 PM

Amazing!

solidONE 12-02-2015 10:17 PM

Gangster!

DustinS 12-10-2015 06:06 PM

Excited to see this so close. Great Job!!


All times are GMT -4. The time now is 07:32 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
User Alert System provided by Advanced User Tagging v3.3.0 (Lite) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.


Garage vBulletin Plugins by Drive Thru Online, Inc.