www.gt4dc.co.uk
Maintain, Modify and DRIVE your GT-Four


It is currently Fri Apr 19, 2024 9:55 pm




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Mon Oct 24, 2005 12:24 am 
Offline
Junior WRC
User avatar

Joined: Thu Oct 06, 2005 12:28 pm
Posts: 701
Car Model: None
This whole text is 96 kb in size, smaller than most images.

The article I feel gives an insight into , behind the scenes of Mega squirt ecu , and what it can so do, its has most of the list functions, code routines etc below, etc.

If this is not the done thing, I will remove.


interested in further information follow the link



http://www.megasquirt.info/v22manual/mcode.htm#versions

MegaSquirt Embedded Code

This is a basic introduction to assembly language programming for the M68HC908GP32 microcontroller used in the MegaSquirt EFI system (not the MegaSquirt-II daughter card, for MS-II code documentation go here). It is not intended to tell you everything you need to know about programming CPU08 microcontrollers (A microcontroller is a complete computer system, including a CPU, memory, a clock oscillator, and I/O (input/output) on a single integrated circuit chip), and is not intended to be a comprehensive look at programming the MegaSquirt.

After reading this tutorial, and some of the above references above, you ought to be able to follow coding discussions on the MegaSquirt Forums.

MegaSquirt uses the Motorola 68HC908GP32 processor. This processor has both RAM memory and Flash memory. RAM memory is 'random access memory' that is lost when the power is shut down. Flash memory is retained even if the power is disconnected (this is called 'non-volatile'). MegaSquirt loads the code into flash, so that it is there when the processor boots up, but uses the RAM memory for many of the tables, etc. for faster and easier access. It does this by copying sections of the Flash memory into RAM on start-up.

The embedded code contains both the program (the instructions to run) and some default parameters. When you tune with MegaTune, you are changing values in RAM. Then when you click the 'Send to ECU' buttons, you are telling MegaSquirt to 'burn' portions of the RAM memory to the Flash memory, making them non-volatile.

The code is written in assembly language, a fairly low level (i.e. very close to what the machine understands) of programming that can be hard for humans to understand. In this document, we will cover some aspects of how the assembly language programs are written, edited, compiled, and loaded.

The computer expects the program to be a series of 8-bit values in memory. But the MegaSquirt code looks as if it were written to be read by fairly smart people, not digital computers. To run the code, the computer needs to load into its memory a file called an object code file. For the MegaSquirt microcontroller, the object code file is the S-record file called megasquirt.s19.

The P&E assembler software compiles the assembly language files in an object code file called megasquirt.s19. This S-record file is an ASCII text file that can be viewed by a text editor or word processor. This is not the program in binary form, but it is a text format that tells the bootloader where and what to write to the MegaSquirt's memory. You can read this file if you understand Hex and op-codes. You should not edit this files because the structure and content of the files are critical to the proper operation of the program.

Code Versions

The latest 'official' version of the embedded code is version 3.000, which was version 2.98 re-released as version 3.000. The changes to version 2.98/3.000 over 2.00 are:


;-----------------------
; Version 2.98
;-----------------------
; Modified boot_r12 file to raise the LVI trip point.
; Fill unused RAM locations with $32, an illegal opcode to force a reset. Done
; to prevent flash erasure if code ever gets into a runaway state - for protection only.
; Put in interlocks to prevent VE/Constant section flash erasure unless specifically
; invoked by a flash burn command.
; Put in Odd-fire RPM averaging (Willette) for odd-fire engines.
; Added new calculation structure to code - same calculation as HI-RES code, but results
; are in 0.1 millisecond units. Calculation overflow fixed.
; Flyback damping code installed - jumper port X0 for INJ1 and jumper port X1 for INJ2.
; Fixed display of WARMCOR variable (no flickering).
; Inhibit PWM mode while cranking.
; Made "ADC" into "ADD in ADC interrupt section (Tom D) to properly perform the sum
; without a carry.
; Perform 12 ms time compare for re-enabling of tach IRQ interrupt (fix for random tach problem) -
; original trial time of 20 ms too long (Magnus Bjelk fix - also for high/low byte check).
; Moved after-start enrichment to increment after "N" tach pulses have occurred,
; with N being the number of cylinders. This will lengthen the afterstart enrichment
; time by an amount scaled by the number of cylinders (Tom).
; Fix display of barometer correction (no screen flicker if 100% barometer is selected).
; Fixed IRQ counter to work properly for NCYL above 8 cylinders.

The version 2.98 code can be downloaded from the following links:

http://www.bgsoflex.com/v2.98/megasquirt.asm
http://www.bgsoflex.com/v2.98/megasquirt.h
http://www.bgsoflex.com/v2.98/boot_r12.asm
http://www.bgsoflex.com/v2.98/megasquirt.s19

In general, right click on the links as 'Save as', this avoids adding formatting, etc., that could corrupt the files.

You really only need the last file (megasquirt.s19) if you are not modifying the code.

If your microprocessor already has a bootloader (a special bit of code that allows uploading) on it, you can update code using the serial connection. Get Eric's program download.exe, included in the file tools.zip in the Files section of the MegaSquirt Forums. Unzip the file to a convenient directory. Instructions for using download.exe are in DOWNLOAD.TXT in the zip file. (You can also use hyperterminal or EasyTherm, instruction are here.)

If you are programming a blank chip, such as one you bough direct from Digi-Key, etc., it will not have the bootloader on it, and you will need a programmer to load code for the first time. There is more on that here.

Note that V2.98 is required if you are using the new FlyBack Board.

The newer versions of theMegaSquirt code are fully backwards compatible with the firmware and otherMegaSquirt specific software programs. All releases of the embedded software and tuning software are compatible in both directions. V1 (version 1.01) embedded works with the latest MegaTune and the old MegaTune releases work with V2 and V3 embedded code (but without access to newer features like priming pulse, flyback board, and Wide Band O2 support).

The hardware for both v1.01 and v2.2 boards looks the same to the CPU, so either code will work on either board.

Unless you have a specific reason to do otherwise, useV3.000 embedded code and the latest version of MegaTune, as they are the most robust. See theCommunication sectionof the FAQ for details on how to upgrade the firmware.

There are a number of other 'unofficial' versions of the code are out there for your MegaSquirt. See Colin Gebhart's guide for compatibility and files.

Here are main versions of code:


Standard code (versions 1.01, 2.00, and 2.98/3.000): Gives 0.1ms resolution. These were installed on the first [version 1.01] and second [version 2.00] group buy units.
Dual Table [DT] code: Guy Hill's code allows 2 tables to be programmed. Each can be alpha-n or speed-density. Perfect for staging with different sized injectors. Click the link for more information about the Dual Table code.
High Resolution [HR] code: Gives 0.005ms resolution, but you lose peak and hold injector current control so you will need a ballast resistor to run low impedance injectors.
Megasquirt'n'Spark-Extra code: A feature-rich enhancement based on standard MegaSquirt hardware that adds ignition support for several ignition modules, as well as dual 12x12 VE tables, AFR tables, etc., etc. It may require advanced technical knowledge to implement some options. (Here is a memory map showing how MSnS code uses the RAM and Flash, it is quite a bit more sophisticated than the official MegaSquirt code)
There are a number of other specialized versions of embedded code for MegaSquirt. See Colin Gebhart's guide for compatibility and files.

Assembly Language Files

There are a number of files that are used to program your MegaSquirt.

Unless you want to edit and recompile the source code, you can upgrade to any version of the code by uploading the corresponding .s19 file. If you want to edit the code, you need a number of files:

The .asm file is the human readable source code. Open it up with Notepad and look it over. You may not understand it but it is very well commented.

The .inc files are included by the compiler directed by command in the .asm file. In this case it is used to load tables. This can be read with notepad.

The .h file is called a header file. It contains 'defines' and 'equates' (constants). Open it up with Notepad.

The .s19 is called the 'source record' or S record for short. This is the result of running the .asm through the compiler. This is not the program in binary form but it is a text format that tells the loader where and what to write to the device's memory. You can read this file if you understand Hex and op-codes.

Each line of an S-record file is a record. Each record begins with a capital letter S followed by a code number from 0 to 9. The only code numbers that are important to us are S0, S1, and S9 because other S-number codes apply only to larger systems.

S0 is an optional header record that may contain the name of the file that humans can read.
S1 records are the main data records.
An S9 record is used to mark the end of the S-record file. For 8-bit microcontrollers, the information in the S9 record is not important, but an S9 record is required at the end of S-record files.
All of the numbers in an S-record file are hexadecimal. Hexadecimal is a base-16 system, and number are frequently written with a $ as a prefix (or sometimes by a small h sufix). Hexadecimal (often called simply 'hex') is a particularly convenient way of representing the binary numbers used in a computer.

(If you want to convince yourself that this makes things easier, try computing 312×45 in Roman numerals using paper and pencil. It would be CCCXII×XLV, the rest is left as an exercise for the reader!)

To a computer, using decimal is like us using Roman numerals.

Decimal Binary Hexadecimal
0 0000 0000 0
1 0000 0001 1
2 0000 0010 2
3 0000 0011 3
4 0000 0100 4
5 0000 0101 5
6 0000 0110 6
7 0000 0111 7
8 0000 1000 8
9 0000 1001 9
10 0000 1010 a
11 0000 1011 b
12 0000 1100 c
13 0000 1101 d
14 0000 1110 e
15 0000 1111 f
16 0001 0000 10
17 0001 0001 11
18 0001 0010 12
etc. etc. etc.


For example:


$ffff = 15×163 + 15×162 + 15×161 + 15×160
= 61440 + 3840 + 240 + 15
= 65535 (= 1111 1111 1111 1111 in binary)
and


$B9 = B×161 + 9×160
= 11×16 + 9×1
= 185 (= 1011 1001 in binary)
In MegaSquirt assembly code:

Hexadecimal numbers are represented by a dollar sign ($) preceding the number (sometimes a # sign is used to represent Hex such as in HTML, and in other formats an 'h' suffix may be used instead).
Binary numbers are represented by a percent sign (%) preceding the number.
Numbers that end with a T are explicitly in decimal format.
So $B9 = 185T = %10111001 in assembly language. We use which ever is most descriptive for the function we are performing. This will become clearer later.

The type field is S0, S1, or S9 for the S-record files we will use. The length field is the number of pairs of hexadecimal digits in the record excluding the type and length fields. The address field is the 16-bit address where the first data byte will be stored in memory. Each pair of hexadecimal digits in the machine code data field represents an 8-bit data value to be stored in successive locations in memory. The checksum field is an 8-bit value that represents the ones complement of the sum of all bytes in the S-record except the type and checksum fields. This checksum is used during loading of the S-record file to verify that the data is complete and correct for each record.

There are a number of assembly language files used to program the MegaSquirt. These include:


The megasquirt.asm file is the human readable source code. Open it up with Notepad and look it over. You may not understand all of it but it is very well commented. Note that the bootloader file boot_r12.asm is required to load the code necessary for the upgrading of the software through the serial port. boot_r12.asm can be 'included' in the megasquirt.asm code with a line like:
include boot_r12.asm
so that it doesn't need to be loaded separately to the 68HC908GP32.
The GP32.equ file, which is a general 68HC908GP32 file that set the assembler up to correctly address the I/O registers, etc. of the microcontroller. You can open it with notepad.
The *.inc files are included by the compiler directed by command in the .asm file. In this case it is used to load tables. This can be read with notepad.
The megasquirt.h file is called a header file. It contains 'defines' and 'equates' (constants). Open it up with notepad.
Programming References

This document is intended for those who wish to know enough about how the MegaSquirt is programmed to be able to delve into more technical documents like:


The CPU08 Central Processor Unit Reference Manual,
The 'official' 68HC908 manual - it tells you everything you want to know about the 68HC908 processor used in MegaSquirt (but not always in easy to understand terms). If you are going to make serious changes to the MS code that will require using the timers, or programming IO ports or interrupts, or anything fancy like that, then you'll need to read this.
The excellent on-line introduction to microcontrollers that uses 68HC908GP32 throughout. Lots of sample code, and more detailed explanations and examples for those new to assembly programming.
The downloadable HC08 examples and tutorials
If you are looking for general programming information, the Tech Books for Free site has a scattergun collection of programming resources, for all types of programming and application areas.

Here is some good stuff on hardware design.

www.andamooka.org/reader.pl?section=liec
And some more on programming: http://savannah.nongnu.org/download/pgubook/

Then you might want to look at the manual at http://e-www.motorola.com/files/microco ... PU08RM.pdf. (Note that this link may change. Search the Motorola site if you get a dead link.) This document covers the architecture, resets and interrupts, addressing modes, and instruction sets for theMegaSquirt processor.


For further reading, an on-line document covering many of the basic microcontroller concepts in great detail is at http://e-www.motorola.com/brdata/PDFDB/ ... HC05TB.pdf.

If you would like a textbook, an absolutely outstanding book on microcontrollers is Embedded Microprocessor Systems, by Jonathan Valvano, ISBN 0-534-36642-2. It doesn't have a lot of theory, just meat.

It ranks up there with Horowitz/Hill "Art of Electronics" and "Numerical Recipes". This one is destined to be a classic. It has info on programming Mot HC05/HC08/HC11/12 processors, and all of the hardware that people like us are interested (stepper motor driver circuits, sensor interfaces, etc). There is also a lot of information on algorithms like PID loops, how to make a real-time scheduler, etc. - things we are all interested in.

The front and rear covers have charts and tables on practical items (like different capacitor types, popular transistor types with relevant info, etc). Get this book and you will be able to make MegaSquirt circuit and software changes yourself. It is expensive at $107, but worth every dollar.

Get this book and you will be able to make MegaSquirt circuit and software changes yourself. It is expensive at $107.00, but worth every dollar.

Programming Software

To create modified code for MegaSquirt, you need to:


Download the source files. You need a number of files besides the megasquirt.asm to make a modified megasquirt.s19 file. These files are normally included in the ZIP file that contains the .ASM file, such as :
http://www.msefi.com/dload.php?action=file&file_id=82 (V3.000 code)
This ZIP file contains:

The megasquirt.asm file is the human readable source code.
Note that the bootloader file boot_r12.asm is required to load the code necessary for the upgrading of the software through the serial port.
The GP32.equ file, which is a general 68HC908GP32 file that set the assmebler up to correctly address the I/O registers, etc. of the microcontroller.
The *.inc files (barofactor.inc, kpafactor.inc, etc.) are included by the compiler directed by command in the .asm file. In this case it is used to load tables.
The megasquirt.h file is called a header file. It contains 'defines' and 'equates' (constants).[/quote] Most often, these files are contained in the .zip file with megasquirt.asm.

Download the compiler. You need the full P&E assembler/linker/simulator/IDE (version 1.50) which can be used to assemble, link, and program the MC68HC908GP32 part with the above files. Download the full P&E assembler/linker/simulator/IDE (version 1.50) which can be used to assemble, link, and program the MC68HC908GP32.

Extract the P&E Assembler tool set to a directory on your hard drive.(The software has a fairly short limit on the path to the executables directory, so don't bury it in a sub-sub-sub-sub... folder! Something like c:\ics08asm\*.* works well.)

Use the WinIDE (Windows Integrated Development Environment), which is included in the above zip file to modify the megasquirt.asm file to include your modifcations. Note that you have to set the Environment [under 'Setup Environment'] to match the directory to which you have installed the ZIP file so that WinIDE can find the compiler, simulator, etc..
'Open File' for the desired .asm file (megasquirt.asm) and make sure the associated files (*.inc, .h, Gp32.equ, etc.) are in the same directory. You can get these files from the above link.
Edit the file and save it under the same name (you can change the name, this will change the name of the compiled .s19 file that will be produced as well)
Assemble/Compile the code by clicking on the 'Assemble/Compile' button [leftmost], and the megasquirt.s19 file is created (unless you have errors, in which case you'll have to fix them!). The .s19 file has the same name as the .asm file by default.

Download the modified megasquirt.s19 file to the chip using the original bootloader, such as with download.exe or hyperterminal, or the Willette programmer and the prog08sz, which will be the third icon from the left, if you have set the environment to the defaults.
The tutorial covers mostly the coding aspect. Follow the links above to find out more about things like the bootloader, downloading code, etc. It is probably a good idea to get the above downloads now and install them, so you can see other examples, etc. With all that out of the way, lets get into the the discussion!

In this document, we will look in detail at some sections of the code from the megasquirt.asm file. The entire file will not be disected line by line [it's 39 pages, and is left as an exercise for the reader, as textbooks say!]

Why Assembly Language?

Why isn't MegaSquirt programmed in C++, or even BASIC? It could be, but only by making the code much larger and slower. Assembly language is the only programming scheme that has a one-to-one correspondence with the machine language operational codes the MegaSquirt's processor recognizes. What you program in assembly language is what the machine runs, nothing more.

Using other higher-level languages would add a great deal of rarely used, but sometime required code for nearly every line of code. Think of it like word processing. A basic ASCII file that contains the message "Thanks to Bruce Bowling and Al Grippo" is much smaller than the Word2000 document that says the same thing. If you want to be able to produce the message easily, in a formatted font, and have it shown in a variety of systems, you would use Word. However, if you want the most efficient package for the message, you would choose an ASCII file. The same reasoning applies to assembly language programming.

In MegaSquirt, it is important that the code be efficient, since we are asking it to do a lot of operations in a short time. Some of the instructions (also known as 'opcodes') will be almost obvious, like ADD for addition, and SUB for subtraction. Others, like TAX (transfer A to X), or DBNZ (Decrement and Branch if Not Zero) take more getting used to. All of the instructions are listed below, but we should cover a few topics before looking at those.

In order to understand the assembly language code, you need to be familiar with several concepts:

registers,
addressing memory,
instructions (a.k.a. opcodes),
interrupts and resets.
We will start with the first two concepts, and throw in the others as we examine examples from the MegaSquirt code.

Registers

The MC68HC908GP has five registers. These are temporary storage for intermediate memory addresses, calculations, and results. Because these registers are directly wired into the CPU, they do not have 'conventional' memory addresses like program or data. Instead they are referred to invoking by the appropriate instruction.

The registers are:


The accumulator (A) is a general-purpose 8-bit register. The central processor unit (CPU) uses the accumulator to hold operands and results of arithmetic and non-arithmetic operations.
The 16 bit index register (H:X), which allows the user to index or address a 64-Kbyte memory space. The concatenated 16-bit register is called H:X. The upper byte of the index register is called H. The lower byte of the index register is called X.
The 16 bit stack pointer (SP), which contains the address of the next location on the stack. The address in the stack pointer decrements as data is pushed onto the stack and increments as data is pulled from the stack. The SP always points to the next available (empty) byte on the stack. The stack pointer (SP) is used as a pointer to the next available location in a last-in-first-out (LIFO) stack. The stack can be thought of as a pile of cards, each holding a single byte of information. At any given time, the CPU can put a card on top of the stack or take a card off the stack. Cards within the stack cannot be picked up unless all the cards piled on top are removed first. This stack is used to hold return addresses while the CPU is executing a subroutine and holds the previous contents of all CPU registers while the CPU is executing an interrupt sequence. By recovering this information from the stack, the CPU can resume where it left off before the subroutine or interrupt was started. The reset stack pointer (RSP) instruction sets the least significant byte to $FF and does not affect the most significant byte.
The 16 bit program counter (PC), that contains the address of the next instruction or operand to be fetched. Normally, the address in the program counter automatically increments to the next sequential memory location every time an instruction or operand is fetched. Jump, branch, and interrupt operations load the program counter with an address other than that of the next sequential location.
The 8 bit condition code register (CCR) contains the interrupt mask and five flags that indicate the results of the instruction just executed. Bits five and six are permanently set to equal 1. For example, the CCR stores the result of CMP (compare) instructions, set bits indicating which of the compared memory locations was larger. This can then be used to perform conditional program branching.
Many instructions are unique to the particular register, but have familiar forms and mnemonics: for example, there is sta $xxxx for SToring the contents of the Accumulator in the memory location $xxxx, and sthx $xxxx for SToring the contents of the index register H:X in the memory location $xxxx. Other examples include lda and ldhx (for LoaDing the contents of a memory address into a particular register), and clra, clrh, and clrx to clear the respective values of the registers. Some instructions operate on more than one register: tax, for example, Transfers the contents of the Accumulator to the X byte of the index register.

Addressing Memory

The MegaSquirt's 68HC908GP32 processor has:


32K of FLASH memory, represented by addresses from $8000 to $FDFF,
512 bytes of RAM memory $0040 to $023F,
64 Bytes reserved for the I/O Registers $0000 to $003F
The set of addresses for the entire memory is called a memory map, and you can see the MegaSquirt's memory map here. The MegaSquirt program and any variables that are 'remembered' when MegaSquirt is shut down are stored in FLASH. An example is the Volumetric Efficiency (VE) table data. MegaSquirt handles the whole VE table in the following manner: when you turn on the MegaSquirt box, the embedded code copies the VE table from FLASH to RAM, and the MegaSquirt uses the VE values in RAM. When you are on the tuning page in MegaTune, you are poking numbers into RAM, and the MegaSquirt instantly uses the new value. There is a separate "burn" command which burns the values in RAM into FLASH, such that when you re-power the MegaSquirt, the new values are used. The VE values are stored in memory in a location defined as VETABLE.

Why not use the values directly from FLASH? There are two reasons: it can be slower because we might have to use longer memory addresses, and it is much more involved to write values back to FLASH. You can only write to FLASH by first erasing it. You can only erase flash in 128-byte chunks. So to change one value we would have to erase 128 bytes, then write 128 bytes, making at least an extra 254 steps (128 erases plus 128 writes minus the 2 we would have done any ways)!. As well, coded delays need to be built in because the FLASH writes are physically slower than writing to RAM. There are various tricks to minimize the number of erase/write cycles with queues and other techniques, but it is way too complicated for our application.

______________________________

Example 0
______________________________

Load Flash to RAM

Here are two sections of the megasquirt.asm code that show the transfer of the VE table from the FLASH memory to RAM and back. Don't worry about the details of these two snippets. They are shown here only to demonstrate how much more cumbersome writing to flash is than writing to RAM. As a result, it is much more efficient to do program calculations in RAM whenever possible.


Write from FLASH to VETABLE
XXVV:
lda VETABLE,x
sta VE,x
incx
cbeqx #$80,XXXV
bra XXVV

Write from VETABLE to FLASH
; Erase VE and Constants in FLASH - 128 byte erase ERASE_N_BURN:
ldhx #FLCR
lda #%00000010
sta ,x
lda FLBPR
sta VETABLE
lda #$0C
bsr DELAYE
lda #%00001010
sta ,x
lda #$F0
bsr DELAYE
bsr DELAYE
bsr DELAYE
bsr DELAYE
bsr DELAYE
lda #%00001000
sta ,x
lda #$06
bsr DELAYE
lda #$00000000
sta ,x
lda #$02
bsr DELAYE
bra VE_BURNER

DELAYE:
deca
bne DELAYE
rts

; Now Burn VE (you can only freakin burn 64 bytes at a time) VE_BURNER
lda #%00000001
sta ,x
lda FLBPR
sta VETABLE
lda #$0C
bsr DELAYVE
lda #%00001001
sta ,x
lda #$06
bsr DELAYVE
clrh
clrx

LOOP_TO_BURN_VE:
lda VE,x
sta VETABLE,x
lda #$22
bsr DELAYVE
incx
cpx #$40
beq SD1
bra LOOP_TO_BURN_VE

SD1:
ldhx #FLCR
lda #%00001000
sta ,x
lda #$06
bsr DELAYVE
lda #%00000000
sta ,x
lda #$01
bsr DELAYVE
bra BURN_C

DELAYVE:
deca
bne DELAYVE
rts



Notice in the above example how many instructions end in a, h, x, or hx. In every case, the commands perform some operation regarding the contents of the accumulator, the high byte (h) of the index register, the low byte (x) of the index register, or both bytes (h:x) of the index register respectively.

The address range $0000 to $00FF (i.e. 0 to 255) is called the direct page, base page or zero page of RAM, because the first two numbers (the high byte) are zero. On the MegaSquirt microcontroller, the lower part of the direct page always contains I/O and control registers ($0000 to $003F) and the upper part of the direct page ($0040 - $00FF) always contains RAM (which runs from $0040 - $023F). The direct page is important because most CPU08 instructions have a direct addressing mode variant whereby they can access operands in the direct page in one clock cycle less than in extended addressing mode. Furthermore the direct addressing mode instruction requires one less byte of code, saving memory space. Using the zero page as much as possible makes the code significantly more efficient and faster.

MegaSquirt's Volumetric Efficiency Table resides at $00A6 to $00E5, and we exceed the zero page at REQ_FUEL which lives at address $0100 (because we now require two bytes - $01 and $00 to address it). The last RAM variable, crankrpm lives at $01A5, leaving $0200-$01A6 = $5A = 90 bytes for the stack and FLASH burner code.

A few highly efficient instructions will only work with direct page operands. These are: BSET, BCLR, BRSET and BRCLR. The MOV instruction requires one of the operands to be in the direct page. Click here to see more details of the 68HC908 memory map.

The CPU08 has 16 different addressing modes. When an instruction doesn't need an operand, its addressing mode is referred to as inherent. An example is TAP (Transfer Accumulator to Condition Code Register). Since it is transferring data between the two specified registers, no memory addresses are needed.

A pound sign (#) before a number indicates an immediate operand. The default base is decimal. Hexadecimal numbers are represented by a dollar sign ($) preceding the number. Binary numbers are represented by a percent sign (%) preceding the number. Numbers that end with a T are explicitly in decimal format.

When the operand is immediate, the value is contained in the bytes immediately following the instruction. That is, the instruction is not followed by a memory location, it is followed by a number to be used for the instruction. In this case, the effective address of the instruction is specified by the # sign and implicitly points to the byte following the opcode. The immediate value is limited to either one or two bytes, depending on the size of the register involved in the instruction.

Where operands are not immediate in megasquirt.asm, they are generally assigned labels referring to specific memory locations in the megasquirt.h, boot_R12.asm, or GP32.equ files, and referred to by these labels in the code. For example, the contents of memory in the location labelled 'map' contains the Manifold Absolute Pressure ADC Raw Reading, and the contents of memory in the location labelled 'mat' holds the Manifold Air Temp ADC Raw Reading. Click here for more examples.

The directive EQU is used to associate a binary value with a label in the megasquirt.h file. The value may be either an 8-bit value or a 16-bit address value. This directive does not generate any object code. It is used by the assembler which keeps a cross reference list where it stores the binary equivalent of each label. When a label appears in the source program, the assembler looks in this cross reference table to find the binary equivalent. Each EQU directive generates an entry in this cross reference table.

The RMB (Reserve Memory Byte) directive is used to set aside space in RAM for program variables. The RMB directive does not generate object code but it normally generates an entry in the assembler’s internal cross reference table.

In the indexed addressing mode, the current value of the index register is added to a 0-, 1-, or 2-byte offset in the next 0, 1, or 2 memory locations after the instruction to form a pointer to the address of the operand in memory.

Relative addressing mode is used exclusively for conditional branch instructions. The byte after the opcode is a signed offset value between –128 and +127. If the condition of the branch is true, the offset is added to the program counter value to get the address where the CPU will fetch the next program instruction.

Generally, the number of bytes for the operand must match what the instruction expects. One exception to this is the 'page zero' mode, in which the upper byte (H) of a 16 bit register such as the index register is assumed to be zero, so that we can address the first 256 addresses by specifying just one byte (the lower byte {L}). This allows downwards compatibility with code for older processors and faster processing for those memory locations.

Interrupts and Resets


The CPU08 executes instructions sequentially, i.e. one after the other. With MegaSquirt, it is often necessary to execute sets of instructions in response to requests from various peripheral devices (such as the laptop, the sensors, etc.). These requests can come any time during the execution of the main program.

Resets and interrupts are both used to force a change to the current flow of the code, and redirect it it to known state (reset) or another bit of code (interrupt). These are both types of CPU08 'exceptions'. Entry to the appropriate service routine is called exception processing.

A reset is used to force the MCU system to a known memory address. Peripheral systems and many control and status bits are also forced to a known state as a result of reset. These internal actions occur as the result of any MCU reset:


All data direction registers cleared to 0 (input)
Stack pointer forced to $00FF
I bit in the CCR set to 1 to inhibit maskable interrupts
External interrupt latch cleared
STOP latch cleared
WAIT latch cleared
As the computer system leaves reset, the program counter (PC) is loaded with the address of the first instruction. This is called fetching the reset vector. At this point, the CPU begins to fetch and execute instructions, beginning at the address that was stored in the reset vector. Any of these conditions can cause the MC68HC908 to reset:


External, active-low input signal on the RESET pin,
Internal power-on reset (POR),
Internal computer operating properly (COP) watchdog timed out,
An attempt to execute an instruction from an illegal address.
The RESET Pin is a particular pin on the 68HC908 - pin #6. An external switch or circuit can be connected to this pin to allow a manual system reset.

A Power-On Reset reset occurs when a positive transition is detected on VDD. The power-on reset is used strictly for initial power-up.

Interrupts provide a way to suspend normal program execution temporarily so that the CPU08 can be freed to attend to these external requests. The CPU08 can process up to 128 separate interrupt sources including a software interrupt (SWI). Interrupts cause the processor registers to be saved on the stack and the interrupt mask (I bit) to be set, to prevent additional interrupts until the present interrupt is finished. The appropriate interrupt vector then points to the starting address of the interrupt service routine

Upon completion of the interrupt service routine, an RTI instruction (normally the last instruction of an interrupt service routine) causes the register contents to be recovered from the stack. Since the program counter is loaded with the value that was previously saved on the stack, processing continues from where it left off before the interrupt. The registers are restored from the stack in the opposite order they were saved.

Interrupts can be inhibited by setting the I bit in the condition code register (CCR) or by clearing individual interrupt enable control bits for each interrupt source.

The SoftWare Interrupt (SWI) is an executable instruction that produces an interrupt. The action of the SWI instruction is similar to the hardware interrupts. An SWI is executed regardless of the state of the interrupt mask (I bit) in the condition code register.

Reset and interrupt operations share the common concept of vector fetching to force a new starting point for further CPU08 operations.

Examples

Here are some code snippets from the MegaSquirt version 2.00 code. We'll go through each of these in turn, looking at them line-by-line to see what is going on.

______________________________


Example 1
______________________________


; Set up the port data-direction registers
lda #%00000000
sta ddrb ; Set as inputs (ADC will select which channel later)
lda #%00110000 ; Turn off injectors (inverted output)
sta portd

______________________________
On the first line, the ; character means everything that follows on that line is a comment, and will be ignored when the code is compiled. In this case, the comment is telling us that the purpose of the code that follows is to initialize the data-direction registers. Later in this segment, the ; character is used to make comments after an instruction, but still on the same line. The MegaSquirt code is very well commented, both for the general direction the code is following, and for what individual lines are doing.

On the second line, lda is the 'load the accumulator register from memory' instruction. The mnemonic is LoaD the Accumulator = LDA. It loads the contents of the memory location immediately following the instruction (#%00000000 = zero) into A (the accumulator).

#%00000000 is an immediate memory address mode binary value, i.e. the value of zero.

sta is the 'store the contents of the accumulator register in memory' instruction. It represents for SToreAccumulator. It loads the current contents of the accumulator into memory location 'ddrb'. The contents of A remain unchanged. 'ddrb' is a memory location. It is defined in GP32.equ as the Port B Data Direction Register.

So the first three lines do the following things:


tell the person looking at the code what the code is trying to do,
then loads the value #%00000000 (i.e. zero) into the accumulator,
and finally copies it to the ddrb (Port B Data Direction Register).
Similarly, the next two lines

loads the binary value #%00110000 (i.e. 48) into the accumulator,
and copies this value to the memory location portd (defined as the Port D Data Register in GP32.equ).
______________________________


Example 2
______________________________


; Set up the Real-time clock Timer (TIM2)
MOV #Timerstop,t2sc ; Stop Timer so it can be set up
mov #$00,T2MODH
mov #$B8,T2MODL ; set timer modulus register to 184 decimal
mov #T2SC0_No_PWM,T2SC0 ; make this normal port output (PWM MODE is #$5E)

______________________________
Here again we start with a comment (;) telling us what the code is trying to do. Then we have 4 mov instructions. mov A,B moves a byte of data from a source (A) address to a destination (B) address. Obviously, mov stands for MOVe. Data is examined as it is moved, and condition codes are set. Source data is not changed. The accumulator is not affected.



The first mov instruction moves the contents of #Timerstop to t2sc

The second mov instruction moves the immediate mode hexadecimal value #$00 (=zero) to T2MODH

The third mov instruction moves the immediate mode hexadecimal value #$B8 (=184) to T2MODL

The last mov instruction moves the contents of T2SCO_No_PWM to T2SCO
______________________________


Example 3
______________________________


; Set up SCI port
lda #$12 ; This is 9600 baud w/ the osc frequency selected
sta scbr
bset ensci,scc1 ; Enable SCI
bset RE,SCC2 ; Enable receiver
bset SCRIE,SCC2 ; Enable Receive interrupt
lda SCS1 ; Clear SCI transmitter Empty Bit
clr txcnt
clr txgoal

______________________________
Here again we start with a comment (;) telling us what the code is trying to do.

Then lda and sta are used to load the accumulator with the immediate value $12 and copy it to scbr (SCI Baud Rate Register).

We then get three bset instructions. bset n,M sets bit n (n = 7, 6, 5, … 2, 1, 0) of the contents of memory location. M can be any RAM or I/O register address in the $0000 to $00FF area of memory because direct addressing mode (a.k.a. 'zero page mode') is used. bset reads the specified 8-bit location, modifies the specified bit, and then writes the modified 8-bit value back to the memory location. bset was named to suggest BitSET.


In this case, the first bset sets scc1 (SCI Control Register 1), bit ensci (enable SCI bit) to 1. All other bits in scc1 are unaffected.
The second bset sets scc2 (SCI Control Register 2), bit RE (receiver enable bit) to 1. All other bits in scc2 are unaffected.
The last bset sets scc2 (SCI Control Register 2), bit SCRIE (SCI receive interrupt enable bit) to 1. All other bits in scc2 are unaffected.
Next the lda instruction is used to load the accumulator with the contents of SCS1 (SCI Status Register 1).

Finally, two clr instructions are used. clr replaces the contents of the specified memory address (txcnt {SCI transmitter count (incremented)}, txgoal {SCI number of bytes to transmit}) with zeros. clr is meant to imply CLeaR.

Most of the above addresses are defined in GP32.equ.

______________________________


Example 4
______________________________

Next we will examine the Exhaust Gas Oxygen Sensor Measurement Section of the megasquirt.asm code to see how EGO sensor correction to the pulse width is implemented. This code employs conditional program flow control (branching) instructions. These instructions generally begin with a 'b', such as blo or bhi.

The logical structure we want to produce in assembly language can be written in pseudo-code as:

Steps are the following:
If egodelta = 0 then goto skipo2
If RPM < RPMOXLIMIT then goto skipo2
If TPSAEN in ENGINE or TPSDEN in ENGINE are set, then goto skipo2
If coolant < egotemp then goto skipo2
If sech = 0 and secl < 30 seconds then got skipo2 (skip first 30 seconds)
If tps> 3.5 volts then goto skipo2


The above lines skip the O2 correction (by invoking the subroutine skipO2) if:

the O2 hasn't changed,
if the RPM is below the limit set by the tuning software,
if the TPS is moving rapidly,
if the coolant temperature is below the activation point,
if 30 seconds haven't elapsed,
or if the the throttle is open beyond the threshold.
The following lines set the actual correction factor.


If egocount > egocountcmp


Then
egocount = 0
If ego > 26 (counts, or 0.5 Volts) then (rich)


Then
tmp = egocurr - egodelta


if tmp < egolimit then goto VETABLELOOKUP


egocorr = tmp
goto VETABLELOOKUP


Else (lean)
tmp = egocorr + egodelta


if tmp > egolimit then goto VETABLELOOKUP


egocorr = tmp
goto VETABLELOOKUP


End if
End If

And the subroutine is:

subroutine skipo2:
.... egocorr = 100% ;i.e. no correction
.... goto VETABLELOOKUP


How is this logic implemented in assembly for the M68HC908? This is a much more complicated example than the previous snippets, but the structure is similar, and you will see how the LDA/CMP/BLO series of instructions (and branching variants) are used repeatedly to perform conditional tests of the current state of the engine. A few new instructions will be introduced as we go through the code. Note that every possible path through the code ends in a branch to the VETABLELOOKUP routine.


MAE:
lda egodelta LoaD the Accumulator with the value of egodelta
beq SKIPO2 beq is a program flow control instruction that tests the state of the Z bit (the second bit) in the CCR and causes a branch if Z is set. The Z bit of the CCR is the 'Zero Flag'. The CPU sets the zero flag when an arithmetic operation, logical operation, or data manipulation produces a result of $00. The mnemonic is Branch if EQual. So if egodelta=0 then goto skipO2
lda rpm LoaD the Accumulator with the value of rpm
cmp RPMOXLIMIT ; Low-end of RPM
cmp CoMPares the contents of the accumulator (rpm) to the contents of RPMLIMIT and sets condition codes in the CCR, which may then be used for arithmetic (signed or unsigned) and logical conditional branching. The contents of both the accumulator (rpm) and RPMLIMIT are unchanged. The first condition bit (C) is set = 1 if the unsigned value of the contents of memory is larger than the unsigned value of the accumulator, (i.e. RPMLIMIT is greater than rpm); cleared otherwise.
blo SKIPO2 blo is another branching instruction for program flow control that performs a conditional branch to an address (skipO2 in this case). If the BLO instruction is executed immediately after execution of a CMP instruction, the branch will occur if the unsigned binary number in the A, X, or H:X register was less than the unsigned binary number in memory. In this case, if rpm is less than RPMLIMIT, then branch to skipO2. Note that there is an analogous bhi instruction.
brset TPSAEN,ENGINE,SKIPO2 brset tests bit TPSAEN of location ENGINE and branches to SKIPO2 if the bit is set. brset uses direct addressing mode is used to specify the address of the operand. So instruction means 'if the acceleration bit of the engine status is set, skip the O2 correction'.
brset TPSDEN,ENGINE,SKIPO2 brset tests bit TPSDEN of location ENGINE and branches to SKIPO2 if the bit is set. brset uses direct addressing mode to specify the address of the operand. So this instruction means 'if the deceleration bit of the engine status is set, skip the O2 correction'.
lda coolant LoaD the Accumulator with the value in coolant
cmp egotemp cmp CoMPares the contents of the accumulator (coolant) to the contents of egotemp and sets condition codes, which may then be used for arithmetic (signed or unsigned) and logical conditional branching. The contents of both the accumulator and coolant are unchanged. The first condition bit (C) is set = 1 if the unsigned value of the contents of memory is larger than the unsigned value of the accumulator, (i.e. coolant is greater than egotemp); cleared otherwise.
blo SKIPO2 blo performs a conditional branch to an address (skipO2 in this case). Since the BLO instruction is executed immediately after execution of a CMP instruction, the branch will occur if the unsigned binary number in the Accumulator register (coolant) was less than the unsigned binary number in memory. In this case, if coolant is less than egotemp, then branch to skipO2. By now you might be beginning to see that the load/compare/branch structure (lda, cmp, blo (or bhi)) is both useful and frequently used!
lda tps Load the accumulator with the value in tps
cmp #$B2 cmp CoMPares the contents of the accumulator (tps) to the immediate value of $B2 (=178) and sets condition codes, which will be used by the next instruction for logical conditional branching. The contents of both the accumulator and coolant are unchanged. The first condition bit (C) is set = 1 if the unsigned value of the contents of memory is larger than the unsigned value of the accumulator, (i.e. tps is greater than 178); cleared otherwise.
bhi SKIPO2 bhi is another branching instruction for program flow control that performs a conditional branch to an address (skipO2 in this case). When the BHI instruction is executed immediately after execution of a CMP instruction, the branch will occur if the unsigned binary number in the accumulator register was greater than the unsigned binary number in memory. In this case, if tps is greater than $B2 (=178), then branch to skipO2.
lda sech LoaD the Accumulator with the value at sech.
bne chk_o2_lag ; if high seconds set then we can check o2
lda secl LoaD the Accumulator with the value at secl.
cmp #$1E ; 30 seconds threshold
blo SKIPO2 blo performs a conditional branch to skipO2 if secl is less than $1E (30 seconds), then branch to skipO2.
; Check if exceeded lag time - if so then we can modify egocorr
CHK_O2_LAG:
lda egocount LoaD the Accumulator with the value at egocount
cmp egocountcmp CoMPares the contents of the accumulator (egocount) to the immediate value of egocountcmp and sets condition codes
blo VETABLELOOKUP Branch to VETABLELOOKUP if egocount is less than egocountcmp.
; Check if rich/lean

clr egocount CLeaR the value of egocount
lda config13 ; Check if Narrow-band (bit=0) or DIY-WB (bit=1)
bit #$02 ; Use BIT instead of brset because outside of zero-page
bne WBO2TYPE ; Branch if the bit is set
NBO2TYPE:
lda ego LoaD the Accumulator with the value at ego
cmp VOLTOXTARGET CoMPare ego with VOLTOXTARGET and set the CCR register.
blo O2_IS_LEAN Branch to label O2_IS_LEAN if ego is less than VOLTOXTARGET.
bra O2_IS_RICH Branch to O2_IS_RICH if we haven't already branched somewhere else.
WBO2TYPE:
lda ego Load the accumulator with the value at ego.
cmp VOLTOXTARGET CoMPare VOLTOXTARGET to ego.
blo O2_IS_RICH if ego is less than VOLTOXTARGET branch to O2_IS_RICH
bra O2_IS_LEAN Otherwise, branch to O2_IS_LEAN
; rich o2 - lean out egocorr
O2_IS_RICH:
lda #$64 LoaD Accumulator with the value $64 (=100)
sub egolimit ; Generate the lower limit rail point
sta tmp2 STores the contents of the Accumulator ($64) in the location tmp2
lda egocorr LoaD Accumulator with the value at egocorr
sub egodelta SUBtracts the contents of egodelta from the value in the accumulator (egocorr) and places the result in the accumulator
sta tmp1 STores the contents of the Accumulator (= egocorr - egodelta) in the location tmp1
cmp tmp2 CoMPare the value of the accumulator to tmp2 and store the result in the CCR
blo VETABLELOOKUP ; railed at egolimit value
lda tmp1 LoaD Accumulator with the value at tmp1
sta egocorr STore the contents of the Accumulator in egocorr
bra VETABLELOOKUP BRAnch to VETABLELOOKUP
; lean o2 - richen egocorr
O2_IS_LEAN:
lda #$64 LoaD Accumulator with the value $64 (=100).
add egolimit ; Generate the upper limit rail point
ADDs the contents of egolimit to the contents of the accumulator ($64) and places the result in the accumulator
sta tmp2 STores the contents of the Accumulator (= egocorr - egodelta) in the location tmp2
lda egocorr LoaD Accumulator with the value at egocorr.
add egodelta ADDs the contents of egodelta to the contents of the accumulator (egocorr) and places the result in the accumulator
sta tmp1 STores the contents of the Accumulator (= egocorr + egodelta) in tmp1
cmp tmp2 CoMPares the accumulator (= egocorr + egodelta) to tmp2 (= egocorr - egodelta) and places the result in the CCR.
bhi VETABLELOOKUP ; railed at egolimit value
lda tmp1 LoaD Accumulator with the value at tmp1
sta egocorr STores the contents of the Accumulator (= tmp1) in egocorr
bra VETABLELOOKUP Otherwise, BRAnch to VETABLELOOKUP
; reset egocorr to 100%
SKIPO2: Routine to skip the O2 Correction code
lda #$64 LoaD Acculmulator with the value $64 (=100 decimal).
sta egocorr STores the contents of the Accumulator (= $64) in egocorr
bra VETABLELOOKUP Otherwise, BRAnch to VETABLELOOKUP

So our general method for understanding assembly files is to disect them line by line and see what's happening. Having handy access to the instuctions, variables, and reference manual helps. It also becomes much easier with a bit of practice, as patterns begin to emerge and less 'looking-up' is needed.

Serial Communications

The serial protocol(s) MegaSquirtand MegaTuneuse to communicate withMegaSquirt are listed below:


***************************************************************************
**
** SCI Communications
**
** Communications is established when the PC communications program sends
** a command character - the particular character sets the mode:
**
** "A" = send all of the realtime variables via txport.
** "V" = send the VE table and constants via txport (128 bytes)
** "W"+{offset}+{newbyte} = receive new VE or constant byte value and
** store in offset location
** "B" = jump to flash burner routine and burn VE/constant values in RAM into flash
** "C" = Test communications - echo back SECL
** "Q" = Send over Embedded Code Revision Number (divide number by 10 - i.e. $21T is rev 2.1)
**
***************************************************************************

You also need to set the serial port parameters to 9600, No Parity, 8 bit, 1 stopbit (i.e. 9600,N,8,1). This is done automatically by MegaTune.

Look at the MegaSquirt assembly code for complete details on the mode commands.

Ports

Ports are used by the processor to perform input and output. This can be anything from taking in the ignition signal, to going into bootloader mode, to sending and receiving data over the serial port.

The 68HC908 used in MegaSquirt has 5 ports:

PTA,
PTB,
PTC,
PTD, and
PTE.
Some of these have particular special functions built right in to the processor. For example:


PTA: PTA7–PTA0 are general-purpose, bidirectional I/O port pins. pins. Any or all of the port A pins can be programmed to serve as keyboard interrupt pins.
PTB: PTB7–PTB0 are general-purpose, bidirectional I/O port pins that can also be used for analog-to-digital converter (ADC) inputs.
PTC: PTC6–PTC0 are general-purpose, bidirectional I/O port pins.
PTD: PTD7–PTD0 are special-function, bidirectional I/O port pins. PTD0–PTD3 can be programmed to be serial peripheral interface (SPI) pins, while PTD4–PTD7 can be individually programmed to be timer interface module (TIM1 and TIM2) pins.
PTE: PTE0–PTE1 are general-purpose, bidirectional I/O port pins. These pins can also be programmed to be serial communications interface (SCI) pins.
Note that the ports have several pins, generally (but not always) 8, numbered 0 to 7. Also note that the above doesn't tell us if the pins are inputs or outputs. This is because we configure them to be inputs or outputs by using the data direction registers. A typical data direction register command looks like this:


; Set up the port data-direction registers
lda #%00000000
sta ddrb ; Set as inputs (ADC will select which channel later)

This sets all the PTB pins (ddrb) to be inputs (0). If we had set them to #%00001111, then PTA1, PTA2, PTA3, and PTA4 would be outputs (1), and the rest would be inputs.

The 68HC908 has another neat function for some pins configured as inputs - it has a built in 'pull-up' resistor that forces the input to be high or low, not floating.

For example, the pull-up register PTDPUE7–PTDPUE0 is the Port D Input Pullup Enable Bits. These writable bits are software programmable to enable pullup devices on an input port bit.

1 = Corresponding port D pin configured to have internal pullup
0 = Corresponding port D pin has internal pullup disconnected


Note that pull-up resistors are only applicable to inputs, they will NOT power an output pin.

In MegaSquirt, the CPU pins are configured as follows:


Pin Name I/O MegaSquirt Use
1 VDDA VSYN
2 VSSA GND
3 CGMXFC CLOCK
4 OSC1 CLOCK
5 OSC2 CLOCK
6 RST Reset

7 PTC0 Squirt-LED
8 PTC1 Accel-LED
9 PTC2 Warmup-LED
10 PTC3 N/C
11 PTC4 N/C

12 PTE0 out TxD (Serial transmit)
13 PTE1 in RxD (Serial receive)
14 IRQ1 in IGN

15 PTD0
16 PTD1 N/C
17 PTD2 N/C
18 PTD3 N/C
19 VSS
20 VDD
21 PTD4 out PWM0
22 PTD5 out PWM1

Analog/Digital Converters
23 PTB0 in MAP
24 PTB1 in IAT
25 PTB2 in CLT
26 PTB3 in TPS
27 PTB4 in BATT
28 PTB5 in EGO
29 PTB6 N/C
30 PTB7 N/C
31 VSSAD in GND
32 VDDAD VREF


KeyBoard Interrupts
33 PTA0 out Fuel Pump
34 PTA1 out FIdle
35 PTA2 N/C
36 PTA3 N/C
37 PTA4 N/C
38 PTA5 N/C
39 PTA6 N/C
40 PTA7 N/C

Search the source code for more details on how the data direction registers and pullup enable registers are set in the MegaSquirt code.

Code Change Examples


Cranking Speed Change: You may be cranking faster than the 'cranking enrichment' cut-off speed of 300 rpm, and running off of the VE table while cranking. This can make it difficult to start your engine.
The cranking speed can be changed in the code to suit your application quite easily. Find a section of the code that has the following lines:


CHK_FOR_WENRCH:
cmp #$03 ; Check if we are cranking
bhi WARM_UP_ENRICH

This is where the cranking rpm check occurs. If rpm exceeds 300 (indicated by #$03), then it branches to the warmup enrichment calculations, and assumes the engine is running. Change the $03 number to suit your cranking speed, and you've got your own custom code version with a higher cranking/running transition point.


MAP-based Open Loop: To change the MegaSquirt code to tell it to go open loop under boost, here's what you do:
Find the section of the code titled "MAE"

remark out the following lines by including the semicolon before it:


;lda tps
;cmp #$B2
;bhi SKIPO2

directly under that, add the following 3 lines:


lda kpa
cmp #90T
bhi SkipO2

Recompile the code, load it onto your processor and go...


Double Injector Resolution: Another example is changing to 0.05ms resolution in a quick and dirty hack:
In megasquirt.h change the line

Timergo equ %01010010 ;TSC to
Timergo equ %01010001 ;TSC

This changes the prescaler for the rtc from 4 to 2. Then in the 0.1ms interrupt code change

cmp #$64 ; If RPMPH is 100 ..... to
cmp #200T ; If RPMPH is 200 (or RPMPeriod = 2.5 sec)

and

cmp #$0A to
cmp #20T ; 20 1/20ths per ms

Recompile and send toMegaSquirt and you are ready to run. It's not very elegant but it works. Remember, max pulse width becomes 12.70ms and all displayed values in milliseconds in MegaTune will show double the real value. And all settings measured in milliseconds, including Req_Fuel, accel enrich, etc., will have to be doubled as well.



--------------------------------------------------------------------------------

Some MegaSquirt Variables

ACMULT = Acceleration cold multiplication factor (percent/100)
adsel = ADC Selector Variable
aircor = Air density correction is computed from MAT.
asecount = Counter value for after-start enrichment counter - every ignition
AWC = After-start number of cycles
AWEV = After-start Warmup Percent enrichment add-on value
baro = The barometric pressure as measured by MegaSquirt.
barocor = Barometer Lookup Correction - percent, based on the initial MAP sensor reading.
batt = Battery Voltage ADC Raw Reading - counts
BATTFAC = Battery Gamma Factor
clt = Coolant Temperature ADC Raw Reading - counts (0 - 255)
coolant = Coolant temperature in Degrees F plus 40 (allows -40 degress to fit in integer)
CWH = Crank Enrichment at 170 F
CWU = Crank Enrichment at -40 F
ddra = Port A Data Direction Register
ego = Exhaust Gas Oxygen ADC Raw Reading - counts
egocorr = This is the correction factor computed from O2 sensor readings.
egocount = Counter value for EGO step - incremented every ignition pulse
egotemp = Coolant Temperature where EGO is active
egocountcmp = Counter value where EGO step is to occur
egodelta = EGO Percent step size for rich/lean
egolimit = Upper/Lower EGO rail limit (egocorr is inside 100 +/- Limit)
engine = Variable bit-field to hold engine current status
FASTIDLE = Fast Idle Temperature
gammae = Total Gamma Enrichments - percent
InjOpen = Injector Open Time
InjOCFuel = PW-correlated amount of fuel injected during injector open
INJPWM = Injector PWM duty cycle at current limit
INJPWMT = Injector PWM millisec time at which to activate.
kpa = MAP value in units of KPa
KPARANGEVE = VE Table MAP Pressure Bins for 2_D interpolation
last_tps = TPS reading updated every 0.1 seconds
lmap = Manifold Absolute Pressure ADC last Reading
lmat = Manifold Air Temp ADC last Reading
lclt = Coolant Temperature ADC last Reading
ltps = Throttle Position Sensor ADC last Reading
lbatt = Battery Voltage ADC last Reading
lego = Last EGO ADC reading
map = Manifold Absolute Pressure ADC Raw Reading - kPa (0 - 255)
mat = Manifold Air Temp ADC Raw Reading - counts (0 - 255)
mms = 0.0001 second update variable
ms = 0.001 second increment
porta = Port A Data Register
portb = Port B Data Register
portc = Port C Data Register
PRIMEP = Priming pulses (0.1 millisec units)
pulseigncount = Ignition pulse counter
pw = The injector pulse width being used by MS to squirt fuel into your motor.
pwcalc = Computed pulse width - move into variable PW at pulse time
pw = Injector squirt time in 1/10 milliseconds (0 to 25.5 millisec) - applied
pw2= The other PW comparison (injector #2)
pwrun1 = Pulse width timing variable 1 - from 0 to 25.5ms
pwrun2 = Pulse width timing variable 2 - from 0 to 25.5ms
REQ_FUEL = Fuel Constant
RPMOXLIMIT = Minimum RPM where O2 Closed Loop is Active
rpm = Computed engine RPM - rpm/100
rpmch = Counter for high part of RPM
rpmcl = Counter for low part of RPM
rpmpl = Low part of RPM Period
rpmk = Constant for RPM = 12,000/ncyl - downloaded constant
rpmph = High part of RPM Period
rpmphl = last rpmph value (for odd-fire)
rpmpll = last rpmpl value (for odd-fire)
RPMRANGEVE = VE table RPM Bins for 2-D interpolation
rxoffset = offset placeholder when receiving VE/constants vis. SCI
secl = Time in seconds since MegaSquirt last booted. Low seconds - from 0 to 255, then rollover.
sech = High seconds - rollover at 65536 secs (1110.933 minutes, 18.51 hours)
squirt = Event variable bit field for Injector Firing.
tenth = 1/10th second
tmp1,...,tmp19 = Temporary storage.
tps = Throttle Position Sensor ADC Raw Reading - counts, represents 0 - 5 volts
tpsaccel = The acceleration enrichment.
tpsaclk = TPS enrichment timer clock in 0.1 second resolution
TPSAQ = TPS acceleration amount (fn TPSDOT) in 0.1 ms units
tpsacold = Cold acceleration amount (at -40 degrees) in 0.1 ms units
TPSASYNC = ***** TPS Acceleration clock value
TPSDQ = Deacceleration fuel cut
tpsfuelcut = TPS Fuel Cut (percent).
tpsthresh = Accel TPS DOT threshold
txcnt = SCI transmitter count (incremented)
txgoal = SCI number of bytes to transmit
txmode = Transmit mode flag
T1SCX_NO_PWM = No PWM
VE = 64 bytes for VE Table
vecurr = The current computed VE value determined by look up in the VETABLE using RPM and MAP.
VOLTOXTARGET = O2 sensor flip target value
warmcor = The warmup correction factor applied due to startup and coolant temperature status.
WWU = Warmup bins(fn temp)

Instruction Set

ADC = Add with Carry
ADD = Add without Carry
AIS = Add Immediate Value (Signed) to Stack Pointer
AIX = Add Immediate Value (Signed) to Index Register
AND = Logical AND
ASL = Arithmetic Shift Left
ASR = Arithmetic Shift Right
BCC = Branch if Carry Bit Clear
BCLR n = Clear Bit n in Memory
BCS = Branch if Carry Bit Set
BEQ = Branch if Equal
BGE = Branch if Greater Than or Equal To
BGT = Branch if Greater Than
BHCC = Branch if Half Carry Bit Clear
BHCS = Branch if Half Carry Bit Set
BHI = Branch if Higher
BHS = Branch if Higher or Same
BIH = Branch if IRQ Pin High
BIL = Branch if IRQ Pin Low
BIT = Bit Test
BLE = Branch if Less Than or Equal To
BLO = Branch if Lower
BLS = Branch if Lower or Same
BLT = Branch if Less Than
BMC = Branch if Interrupt Mask Clear
BMI = Branch if Minus
BMS = Branch if Interrupt Mask Set
BNE = Branch if Not Equal
BPL = Branch if Plus
BRA = Branch Always
BRA = Branch Always
BRCLR n = Branch if Bit n in Memory Clear
BRN = Branch Never
BRSET n = Branch if Bit n in Memory Set
BSET n = Set Bit n in Memory
BSR = Branch to Subroutine
CBEQ = Compare and Branch if Equal
CLC = Clear Carry Bit
CLI = Clear Interrupt Mask Bit
CLR = Clear
CMP = Compare Accumulator with Memory
COM = Complement (One’s Complement)
CPHX = Compare Index Register with Memory
CPX = Compare X (Index Register Low) with Memory
DAA = Decimal Adjust Accumulator
DAA = Decimal Adjust Accumulator (Continued)
DBNZ = Decrement and Branch if Not Zero
DEC = Decrement
DIV = Divide
EOR = Exclusive-OR Memory with Accumulator
INC = Increment
JMP = Jump
JSR = Jump to Subroutine
LDA = Load Accumulator from Memory
LDHX = Load Index Register from Memory
LDX = Load X (Index Register Low) from Memory
LSL = Logical Shift Left
LSR


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 9:01 am 
Offline
Club Staff
User avatar

Joined: Wed Jul 13, 2005 5:10 pm
Posts: 1953
Location: Sunny Fareham, UK
Car Model: ST205
Jon - some interesting stuff...mainly aimed at the more geeky natured people! 8)

imho - it often seems a step up in knowledge to install and get an aftermarket ECU running, this seems yet another step up from that, which is good!

It seems that you can really get down and dirty with this ECU, and the open source element of this project is to its credit.

I've got to say thought that most of the hex, variables etc is not in everyones day to day job and some people may think it's all gobblegook! :D

Noticed from another post from you that you mentioned the ability to monitor and then do something with the knock signal - with a cursory scan of the above variables I didn't see a knock one?

How is the datalogginf done? Via software on the laptop? Maybe I should just read the Megasquirt website!

_________________
Kris
95 ST205 - slept for 10 years, now waking up...
Avensis
http://www.gtfours.co.uk
_______________________________________
Turbocharging - the replacement for displacement


Last edited by Kris on Mon Oct 24, 2005 1:36 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 24, 2005 10:55 am 
Offline
Junior WRC
User avatar

Joined: Thu Oct 06, 2005 12:28 pm
Posts: 701
Car Model: None
Hi Kris

The MS has a datalogger, ouput via the serial port to laptop.

the use of the dl1 for all other inputs to be logged

The ms Knock system, comes under the MegasquirtnSpark-extra , thats why you would not see entry in the above list

http://www.servicetronics.co.uk/knocksystem.htm


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 


Who is online

Users browsing this forum: No registered users and 19 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group