Coding
From BMWeb Wiki
How BMW's coding jobs talk to an E46 instrument cluster, what the factory coding tool does with the coding files, and the traps in them. Worked out by running BMW's own coding jobs and scripts offline against a simulated cluster, reading the factory tool, then on a car.
The E46 cluster on the wire
The cluster is a DS2 unit at address 0x80.
car
| Telegram data | Does |
|---|---|
00 | Identification. The coding index is the 6th data byte of the answer. |
06 03 00 hi lo n | Read n bytes of coding memory |
07 03 00 hi lo n data | Write them |
12 | Reset, so the cluster takes the new coding |
- The checksum is an XOR over the coding words, stored in its own word through a mask. The factory job computes it; a value worked out the same way matches the one stored in a real cluster. BMW data
- The write job reads its own write back and fails with ERROR_VERIFY when the bytes differ. BMW data
- The reset clears the clock. After coding, the display showing only a blank clock is the reset, not a coding fault. car
A real write
Changing the temperature unit from °F to °C on an order-coded car took 16 write telegrams through the factory script: the service-data groups, then the coding words 12 at a time, the checksum word, the reset, and a read to prove it. car
Key-coded and order-coded cars
A late E46 cluster is coded through the KOMBI46R description with one of two scripts, and the car decides which. BMW data
- Key-coded cars use A_KMB46.
- Order-coded cars use A_AKMB46. Their cluster's key-code block is blank
FFwith check characters. car - The cluster script always takes its "not yet coded" branch, because the status word it tests includes the checksum byte. With a plant number other than
0000it also runs the job C_ZEIT_RESET, so a tool should send0000unless it means that. - An order's time criterion picks the variant. In the order-coding tables, rows marked
ZorA #MMYYcarry a date, and continue on lines starting>>>. A 09/04 car resolves its cluster to coding index C08, KOMBI46R, A_AKMB46.
Coding files
- The file extension is the coding index in hex. Index 52 is
LSZ.C34. Diagnostic results give the index in decimal. BMW data - Masks are per byte. A function's mask has one entry for each byte it touches. Treating it as one mask for the whole value produced 233 false bit collisions across the files. BMW data
- Two-byte values are held by the module in address order. Parsing their hex as one number swaps the bytes. car
- String positions in BMW's scripts count from 0:
midstr(text, 0, 2)is the first two characters. BMW data
How a coding job is asked
The coding jobs (C_S_LESEN, C_C_LESEN, C_S_AUFTRAG and their relatives) take one buffer, and the module's job code reads it by offset. Measured by running the jobs, and read from the factory tool that builds it. BMW data
| Offset | Holds |
|---|---|
| 0 | Type: 1 for whole words (the mask all FF), 2 for one word with a partial mask |
| 1 | Word width, 1, 2 or 4 bytes |
| 2, 3 | Byte order and address mode |
| 9 up | The mask, one byte per byte of the word |
0x0D | Byte count, 16 bit (the body module's jobs read this) |
0x0F | Word count, 16 bit (the cluster's jobs read this) |
0x11 | Word address, 32 bit, little endian: the byte address divided by the word width, with the block number in the upper bytes |
0x15 | Data, then a closing 03 |
- The answer echoes the header. A read comes back as the same 21-byte header, the data and
03. A buffer one byte short of that is answered ERROR_BIN_BUFFER. - Type 2 is for clusters only. Of 313 coding job sets, only the cluster ones (C_KMB*, KOMBI46R, KOMBI85, C_SHD) accept a partial-mask word; the rest answer ERROR_DATA_TYPE. Everything else is written as whole words, which is why the factory tool reads the module first.
- Blocks are the address's upper bytes. A module that organises its coding memory in blocks (the body module, the light module, the parking aid, the airbag module) gets the block number folded into the word address: width × block × 256, so a 16-bit address overflows for the higher blocks. Each module's jobs pick the block out of the byte they expect (most from byte
0x12of the buffer, the ALC from two). The old09 <address / 20>write job only serves the body module's C01/C02 variants, whose coding is one 20-byte region; a C05/C06 car codes its body module through the ZKE5_S12 jobs. BMW data - Some blocks are the manufacturer's. A module refuses a coding job on its HERSTELLER and RESERVIERT blocks with ERROR_ECU_PARAMETER.
What the factory tool writes
Read from the factory coding tool itself, against the E46 coding files. BMW data
- The written set is the OR of every active function's mask with the
UNBELEGT1fill rows (UNBELEGT2gives the fill value). A byte whose mask is all set is sent as data, a partial one as a type-2 word, a clear one not at all. 115 of the 129 E46 descriptions come out fully covered, all type 1. - What it never writes: the cluster's coding date, VIN, key-code block and mileage bytes, two equipment bytes, and the airbag module's VIN and manufacturer data. A tool that writes the whole region sends them back as the module holds them.
- Values. A reset codes every function to its active value. A function with no decision and one possible value gets it; with several the tool stops with an error. A condition table (CVT) is strict: exactly one rule per group must hold, later entries overwrite earlier ones.
- Order to keywords. The option table (AT) has rows typed W, E, H, K, Z and A; Z and
A #MMYYrows carry a date and continue on>>>lines, and the order's time criterion picks among them. In the ZST table a module-field value is matched nibble by nibble with 0 as a wildcard, and an all-zero row matches everything. The condition expression grammar is NOT above AND above OR,,for OR and+for AND. - The module's selection table (SGET) takes the first row whose conditions hold. Its
S<id>entries are equipment keyword ids (on the E46, S37 is AUTOMATIK, S121 KMBI_CI_07).
Not settled yet
- Coding a block-addressed module with the rules above has been run offline against the jobs, not yet on a car.
- The equipment filter, which hides functions a car's options do not have, needs the option ids measured on a car.
- The option table's V and N dates and its
=conditions are read approximately; whether a date on such a row means on-or-after or before has not been checked against a car.
See also
- Diagnostics and the K line - How the E46-era units talk on the K line, what their answers mean, and what the cables and adapters in between can carry