Instructions to change fuel maps on 14CUX Griffith, Chimaera

Instructions to change fuel maps on 14CUX Griffith, Chimaera

Author
Discussion

danbourassa

246 posts

138 months

Wednesday 8th January 2014
quotequote all
stevesprint said:
Dan, Colin and Robert have you been hit by the USA big freeze?? If so we hope you all are ok including your Rover V8 powered vehicles.
Best Wishes, Steve
It's not too bad here in southern NH right now at 5 degrees F. It's -10 F in International Falls, Minnesota (they hold the record for the 48 states at -55 F). I wonder how many Rover V8's they have there.

danbourassa

246 posts

138 months

Wednesday 8th January 2014
quotequote all
For Dave and others interested in the 14CUX code rebuild project, I have put a folder called OriginalCode here:

https://drive.google.com/?tab=wo&authuser=0#fo...

There is a batch file to automate the build process. This is to be run under Windows from a command window (console or DOS box). If you prefer Linux, Colin is working on a makefile to replace the batch file. This will build up to 10 different LR or TVR tunes. Thanks to Steve Sprint for supplying many of these. Since this phase of the project is just to duplicate factory code from a set of source files, part of the build process is to do a binary comparison of the result with a reference binary.

Once we start modifying the software, there are many advantages to being able to build from source files. We can bypass the A/C or heated screen code if we don't have these features. There is obsolete and development code that should be deleted. I'm personally looking forward to deletion of Fascist code (fuel map lock, road speed limit). Bypassing the road speed sensor check at high RPM is especially important if you run closed loop. We can also reassign the unused ADC inputs to other uses.

I have no idea how many will be interested in this; although, for me, it's great indoor fun when it's 5 degrees F outside. If there is enough interest, we may want to make it a separate thread. The Motorola 6803 is as simple as it gets for an 8-bit microprocessor, so if you have any interest at all, this is a great way to start. There is a DataSheets folder on the drive with PDFs for the 6803. All comments, questions and (most) complaints are welcome.

davep

1,143 posts

285 months

Wednesday 8th January 2014
quotequote all
Thanks for that Dan. Works for me. Could do with some 'how to' support documentation though. Hope things warm up soon.

stevesprint

Original Poster:

1,116 posts

180 months

Wednesday 8th January 2014
quotequote all
Dan
Impressive very impressive, you’ve written 11 to 12 thousand lines of code plus provided us with the data, makefile/build files and a free assembler. I’ve successfully run buildall and all the bins were created with no error or differences. I’m looking forward to getting my hands dirty and will start by creating a data_R2967_??.asm for Precat Griffs 400 and 430.

I’m sure you can tell I’m seriously interested in this project but my 14cux play time is limited at the moment as I’m currently working on my Griff. One of my projects is fitting the correct 14cux lambda sensors plus a wideband sensor. So I hope to be ready for more 14cux action in a month. In the mean time I will keep an eye on the forum.

Its incredible you can now recreate the bins.

Thanks again, Steve

davep

1,143 posts

285 months

Wednesday 8th January 2014
quotequote all
Agree with you Steve. Dan has done a fantastic job of defining, detail commenting and annotating the bare Assembler code into meaningful ASM modules - a real labour of love I think.

danbourassa

246 posts

138 months

Thursday 9th January 2014
quotequote all
I was going to emphasize that there is no original development work here but Dave beat me to it. The source code is the result of disassembling a PROM binary. Commenting it and getting it to rebuild still represents 8 years of work (off and on, of course). We used DASMx (Ver 1.4) to disassemble it, which is available free. Dave has used it.

Colin deserves the credit for the changeover to CRASM. I had been using the Motorola assembler MASM (not to be confused with the Microsoft x86 assembler also called MASM) but it was feature poor and had no explicit GPL. CRASM is packaged with Linux and is superior, although it didn't initially work correctly for the 6803. He contacted the original developer in France who basically said "Monsieur, you are now the stuckee." So, Colin had to do some development to both get it to work for the 6803 and get it to work under Windows.

stevesprint

Original Poster:

1,116 posts

180 months

Thursday 9th January 2014
quotequote all
Dave and Dan.
The penny has dropped, but Dan you had to go through, understand and comment over 10,000 lines of assembler code and separate out the code paths for the different tunes. Sounds like you made the most of the freezing weather to finish off your years of work. I’ve had a quick look and although I don’t understand assember I do understand your comments enough to have ago at creating data_R2967_??.asm for Precat Griffs, which is effectively what I ran in the autumn. With that in mind I hope Colin would be kind enough to display the checksum in RoverGauge. Dave do you have a 400 or 430??

Colin thanks for porting CRASM from Linux to Windows and adding 6803 support, your months/years of hard work means I can compile the bins on my windows pc in seconds.

Thanks again, Steve

Edited by stevesprint on Thursday 9th January 08:43

cmb

103 posts

176 months

Friday 10th January 2014
quotequote all
The original developer of CRASM is Léon Bottou, who I believe had actually been in the States for a while by the time I contacted him. Indeed, when I wrote to him with a question about a possible bug, he pointed out that it had been 25 years since he wrote CRASM so the nuances of the code weren't exactly fresh in his mind smile Since I've been a CRASM maintainer, I've done a couple of releases that address bugs and stability issues.

The 14CUX firmware build procedure is kinda geared toward a Linux environment because I never use Windows (apart from doing the Win32 RoverGauge builds.) However, since the build uses all open-source tools, we've been able to make it work under Windows as well. We've been managing the firmware source in a private Git repository so far, but I'd like to move it to a public repo fairly soon so that people are able to pull down the very latest changes if they're so inclined.

If anyone is interesting in buying a PROM programmer, I can strongly recommend the Batronix BX32 Baputo II. It's made in Germany, well-built, and has freely-downloadable software available for Windows, Mac OS X, and four different flavors of Linux.

Steve, when you say that you'd like to see the checksum displayed in RoverGauge, are you referring to the checksum fixer byte? (That's probably more useful than the checksum itself, which is normally just 0x01.) I'll plan to add a display for this, as well as for the "Ident" byte that sometimes changes independently of the tune revision number.

stevesprint

Original Poster:

1,116 posts

180 months

Saturday 11th January 2014
quotequote all
cmb said:
Since I've been a CRASM maintainer, I've done a couple of releases that address bugs and stability issues.

The 14CUX firmware build procedure is kinda geared toward a Linux environment because I never use Windows (apart from doing the Win32 RoverGauge builds.) However, since the build uses all open-source tools, we've been able to make it work under Windows as well. We've been managing the firmware source in a private Git repository so far, but I'd like to move it to a public repo fairly soon so that people are able to pull down the very latest changes if they're so inclined.
Colin, you have done all this for the 14cux, their is no end to your list of talents.

cmb said:
Steve, when you say that you'd like to see the checksum displayed in RoverGauge, are you referring to the checksum fixer byte? (That's probably more useful than the checksum itself, which is normally just 0x01.) I'll plan to add a display for this, as well as for the "Ident" byte that sometimes changes independently of the tune revision number.
Sorry yes the checksum fixer so we can see what variant of 2967 is running.
The Ident would also be very useful so we could change it to something more meaning full.

stevesprint

Original Poster:

1,116 posts

180 months

Saturday 18th January 2014
quotequote all
I've finally had a chance to create a 430 PreCat assember data file for Dan's rebuild project. It's available from www.stevesprint.com/remap-14cux , it also includes the build batch file, test reference bin and the full ready to use bin. It uses TVR's later code, Revision 2967, merged with all the 430 fuel data. The new 430 bin file Dan's rebuild project generates is exactly the same as the bin I previously hand created and ran faultlessly during the autumn.

Dan
It might be a good idea if you update my prom on your google drive with www.stevesprint.com/remap-14cux/TVR_R2967_with_430... as I’ve reset the Revision number to 2967 and the ID to 4300. Please note the lower half is padded with FF’s as on other TVR R2967 proms and the upper half matches exactly to the rom image generated from data_R2967_AA.asm.

Also Dan, I hope you don’t mind I’ve added a link on my remap-14cux web page to your 14cux google drive.

danbourassa

246 posts

138 months

Saturday 18th January 2014
quotequote all
stevesprint said:
Dan
It might be a good idea if you update my prom on your google drive with www.stevesprint.com/remap-14cux/TVR_R2967_with_430... as I’ve reset the Revision number to 2967 and the ID to 4300. Please note the lower half is padded with FF’s as on other TVR R2967 proms and the upper half matches exactly to the rom image generated from data_R2967_AA.asm.
Done.
stevesprint said:
Also Dan, I hope you don’t mind I’ve added a link on my remap-14cux web page to your 14cux google drive.
Not at all.

davep

1,143 posts

285 months

Saturday 15th February 2014
quotequote all
This thread is worth keeping alive so:

In addition to building project files using Dan’s Original Code source I’ve been annotating the text listing of a Griffith 430 BV EPROM mainly to determine reasons for over-fuelling. The first major variable I’ve looked at is:

Open/Closed Loop and CO Trim Voltage
Taking Dan’s original explanation as a start point: “Each of the six fuel map code areas (0-limpHomeMode, 1, 2, 3, 4 and 5) includes an ADC Multiplex table. Also the open loop maps (1, 2 and 3) have a 10-bit convert on channel 9 (the AFM CO trim voltage). The closed loop maps do not have this, although adjusting it will still have an effect. The measured value is stored in the location that is normally used for storing long term trim.”

A 430 BV uses Fuel Map 2 so is open loop and has the 09 – AFM CO Trim Value function, the measured value for which is stored in the Long Term Trim location. Now, if for some reason the system goes into the Limp Home Mode, Fuel Map 0 and its ADC table are used and the system goes into closed loop. As a result there is no CO Trim check so I assume there is an attempt to set Long Term Trim values according to closed loop processing. But at the next ADC check of the FA – Tune Resistor value, the system will immediately revert to open loop, Fuel Map 2 and the CO Trim value will be reinserted, assuming the reason/fault condition for going into Limp Home Mode is cleared.

Could this ‘switching between open and closed loop processing’ be a cause for over-fuelling on pre-cat (or de-catted Green tune) cars, especially if there is an intermittent fault on any of the other controlling variables? Would an open loop Limp Home Map/ADC table help?


Edited by davep on Saturday 15th February 12:43

danbourassa

246 posts

138 months

Saturday 15th February 2014
quotequote all
Dave,
This is giving me a lot to think about. First, I don't think the fuel map can change while the engine is running without setting Fault Code 21. If this fault is not being set, uncontrolled map changing is probably not the problem.

Even if the map was changing, the CO trim value stored in the long term locations would normally reduce fuel. This value would be less than $8000 (the neutral or mid-point value). The file is mafTrim.asm for those interested. If the value is over a certain threshold, $FFFF is substituted, which would increase fuel. But now we are talking about the combination of two unlikely failures.

You can make an easy code change to rule this out. Replace the two lines of code storing the CO trim value with four NOPs. Do a binary compare after the change to make sure only 5 bytes changed (DD 42 DD 46 becomes 01 01 01 01 plus the new checksum fixer). This will leave the long term values uncorrupted in the event of a map change.

-Dan

robertf03

59 posts

202 months

Wednesday 19th February 2014
quotequote all
I've been out of the loop for a while, but I've finally got some motivation thanks to my 4.6 I installed


Colin and Dan,

I'm looking through the ignition interrupt to try to put some real world values against the numbers in the fuel map. I'm banging my head against the assembler language and hopefully you can shed some light. Does the final value get placed in ocr1high at the end of the bank timer routine? Is the value just a counter for every tick of the microprocessor to decrease and then shut off the output pin? I could not find the code that does the decrement. While walking through it, it looks like its easy to max out the 16 bit value. I was looking at 3360, 2000 RPM at ~38% load for a fuel table value of 95dec and a comp value of $54DD

95 table value
380 X4
8255500 mult by scalar
16511000 doubled
FBF018




Here are my rough notes while I was trying to make some sense of it:



.LE921 interpolated fuel value stored uncompensated. 16 bit stored @ 00CE . No multiplier used, max of FF?
Either filter or skip, 00CE is stored in D (AB register) Value reflects 8 bit values from fuel table * 256 ?
Based on phase 1 comp notes at range $1400 to $FF00.

compensation begis

multiply by compensation factor @ x00ca/cb
  • *** What makes up ca/cb? ****

EX Load and RPM have table value of 95 (3360 map 5, 2000 RPM ~38% load)
if filtering is skipped or engine is in steady state it should be $5F00.

multiply by X00CA and get ?
Multiply by 4, $FFFF max
Multiply by Scalar $54DD
Double Value, limit to $FF00


Phase 2 Compensation
Value is stored in X00CC/CD if running at lambda 1 add 0 to 00CC, store in 00cc

phase 3 likely to skip to phase 4

phase 4 add voltage adjustment from $0055 Need to research to see actual value. Assuming 0 for now with healthy alternator

store in 0082 and 00cc

get current counter value, add 19, add x0cc, store in 00ce store in ocr1high


danbourassa

246 posts

138 months

Wednesday 19th February 2014
quotequote all
Robert,

I may not have mentioned that I put some helpful Motorola documents here:

https://drive.google.com/?tab=wo&authuser=0#fo...

MC6803U4.pdf and M6800_AppManual_Mar75.pdf are very helpful.

The microprocessor runs at 1 MHz (4 MHz crystal divided by 4) as does its internal free running counter. As a result, the final fuel value that is written to the Output Compare Registers (ocr1 or ocr3 depending on bank) is in microSeconds. Note that each is a 16-bit register pair (ocrHigh/ocrLow) and the STD operation (STore Double) stores a 16-bit value in the register pair. The output signal is asserted when this value is written and the timer portion of the microprocessor takes care of the rest, so there is no decrement operation, as you pointed out.

The fuel value is actually checked for rollover (or overflow) at several points during the calculation process and clipped to $FFFF if rollover happened. Does this mean it's a real possibility or just careful coding by the developers? I don't know yet. I've been meaning to model the fuel calculation process for awhile now but I just haven't gotten to it. The max possible value of $FFFF would give approximately 65 mSecs. Land Rover states that the maximum actual value is about 9.0 mSecs at full load (ref. 1314CU_14CUX_Systems.pdf) but I don't believe this. At the very least, this would likely have been quoted for a stock L-R 3.9 engine, so 4.6 or TVR engines would certainly exceed this. Anyway, by my calculation, the engine RPM doesn't have to be very high for the available time to drop below 65 mSecs. I think that if the 14CUX works OK with a TVR 5.0 you should be fine with the 4.6. If you are doing your own chip for the 4.6, you could add a few lines of code to check for a maxed out value and set an unlikely fault code to let you know.

The voltage adjustment value is not zero but normally between 900 and 1000 decimal, although it's temporarily much higher during cranking and battery recovery. I don't know why they did it this way but the math expects this to be added to the final value.

I'll try to get back to doing at least an open-loop model of the fuel calculation. Snow has been a big distraction this winter. I have a pile in the driveway higher than my RR.

-Dan

robertf03

59 posts

202 months

Friday 21st February 2014
quotequote all
Thanks for that. I think my problem was I took the mpy16 function at face value.

I worked through it in excel and found the answer that it effectively divides the result by 2^16, then realized you had put it in the comments section. Hah, next time I'll read through all the notes before diving in halfway through the code. At least it gave me an excuse to sit on the patio with the laptop while enjoying a cigar.


robertf03

59 posts

202 months

Saturday 22nd February 2014
quotequote all
Ok, maybe this was obvious to some, but it looks like the scalar is the most important part of setting up these maps. I believe it is some mathmatical combo of target AFR and cylinder size

The actual fuel table appears just to be an adjustment of % load divided by fuel needed. It looks like it coincides with the engine sweet spot based on camshaft and heads

a quick table that divides the % of fuel (fuel cell value /256) / engine load based on MAF

Most of this was done looking at map 5, but it seems to follow with the others. Map 5 looks like the constant should be pretty close to engine size in liters * 5300

Some of the cells are more utility, as it will never be near 100% load below idle. I know that the 6th row column 1 is used for some odd things like errors based on looking through the code.


danbourassa

246 posts

138 months

Saturday 22nd February 2014
quotequote all
robertf03 said:
Ok, maybe this was obvious to some, but it looks like the scalar is the most important part of setting up these maps.
By scalar, do you mean the 16-bit fuel map multiplier? If so, then yes. I agree. It's the one value that changes most dramatically according to engine displacement. And it's the first thing I would change if I were adapting an existing chip to a 4.6. But it's also important to get the load indexing correct. I just posted a code model here:

https://drive.google.com/?tab=wo&authuser=0#fo...

This demonstrates how the MAF output is linearized for use in the row index calculation. It runs through the range of values and creates an output file that can be loaded into Excel (or a similar tool) for graphing and such. I calculated the linear MAF value 2 ways. The first is normal C and the second is a literal model of the 8-bit microprocessor. The two methods show a slight difference in the results. I attribute this to the limitations of the processor, specifically, the need to truncate multiplication results.

The row index calculation is done for 3 different RPMs. The row index calc also uses an offset and multiplier that come from the data section. Anything in the data section was probably understood by the original developers to be intended for application specific tuning, so it may be interesting to tweek these values in the model and note how the results change. If I remember correctly, Steve Sprint has already played with the multiplier, so, at least, the rest of us now have a tool to help us catch up. I included an example of the output file, so you can go right to that if you don't want to bother with the code.

Looking at the results, assuming I did this correctly, one thing confuses me. Using the multiplier value $B2 and 5102 RPM, the row index hits the limit at only about 4.1 volts at the MAF. That seems too soon to me. I recall previous discussions about running off the right side of the fuel map (RPM-wise), so I wouldn't be too surprised if we had a similar issue in the load direction.

spitfire4v8

4,004 posts

182 months

Saturday 22nd February 2014
quotequote all
The fuel map multiplier in my mind changes the time allocated to each bit (normally termed microseconds per bit in other aftermarket ecus). What I have been doing is to massage the fuel multiplier to get the fuelling correct at the richest point on full throttle power runs on the dyno with FF in the load sites passed through during the run, then leaving the multiplier alone and going back and correcting all the other fuel map sites to get the mixture where I want it.
In this way you can maximise the resolution of the fuel map which becomes important when you are dealing with small numbers in the fuel map around idle and trailing throttle.
The multiplier therefore does become engine size dependant because a big engine will draw more air, will require more fuel, or in the case of the multiplier part - more microseconds of fuel squirted per bit.

Make sense to anyone?

stevesprint

Original Poster:

1,116 posts

180 months

Sunday 23rd February 2014
quotequote all
davep said:
In addition to building project files using Dan’s Original Code source I’ve been annotating the text listing of a Griffith 430 BV EPROM mainly to determine reasons for over-fuelling.
Dave, I personally thought TVR deliberately setup the precats rich to make the engines run smoother. When I copied the 430 fuel tables into TVR 2967 and LR 3383 my AFR was exactly the same, which shows it’s not an issue caused by the old 2422 code. Furthermore when I reduced the hex values in the main fuel table the AFR did actually come down on the rolling road and may not of if it was constantly switching between maps 2 and 0.

It sounds like map 0 is the limp home map for closed loop only, also I’ve noticed my ecu always stays on map 2 even when I disconnect random sensors.

Dave, I wouldn’t worry to much about the old TVR 2422 code as my car runs much better on the later code and the most noticeable improvement is the idle is held slightly higher while coasting and finally drops to idle once stationary. This makes feathering the throttle at slow speed smoother. Interestingly the TVR 2422 code is identical to LR 2422 except 1 byte at address 2B8E, which I can’t workout as Dan has been working on the later and better code, and quite right too.

robertf03 said:
a quick table that divides the % of fuel (fuel cell value /256) / engine load based on MAF
Robert, fascinating equation, In theory could the equation be used in reverse to help set up a fuel table by calculating the hex value for each cell.

danbourassa said:
By scalar, do you mean the 16-bit fuel map multiplier? If so, then yes. I agree. It's the one value that changes most dramatically according to engine displacement.
I like the sounds of that as the 4.3’s have the largest fuel map multiplier and the same calc fuel table row as the 500's. hummm I wonder why – over fuelling to make them smoother.

danbourassa said:
Looking at the results, assuming I did this correctly, one thing confuses me. Using the multiplier value $B2 and 5102 RPM, the row index hits the limit at only about 4.1 volts at the MAF. That seems too soon to me.

The row index calculation is done for 3 different RPMs. The row index calc also uses an offset and multiplier that come from the data section. Anything in the data section was probably understood by the original developers to be intended for application specific tuning, so it may be interesting to tweek these values in the model and note how the results change. If I remember correctly, Steve Sprint has already played with the multiplier,
Yes I did because as on full load my active cell only occasionally hit the bottom row to which Dan kindly explained in detail how a portion of the bottom row could still be taken into account.

I’m curious that the 4 litres row index calc is B2 while the 4.3, 4.5 & 500 are the same 91 especially when Dan explained it can be any linear number. (Dan, you see I do pay attention in class, well some times.) The 4.3’s having the same Row scalar as the 500 does explain why my active cell barely hits the bottom row. I bet the active cell on a 500 on full throttle is is glued to the bottom row.


spitfire4v8 said:
Make sense to anyone?
Joolz, perfect sense.

It’s good you’ve proved the row index calc theory worked on your customers Griffith 500 with the larger AFM.