CAN nodes fail in a way that no bench test catches. The node joins the bus, exchanges a few frames with a USB-CAN dongle on the desk, and then goes silent in the vehicle at the first temperature or cable-length change. The firmware is fine. The bit timing is marginal.
The PIC18F4480 is a 16 KB part — 8,192 instruction words — with 768 bytes of SRAM, 256 bytes of data EEPROM, 36 I/O pins, eleven channels of 10-bit ADC, two comparators, and one ECAN module compliant with CAN 2.0B. It shares DS39637 with the 28-pin 2480 and the 32 KB 2580 and 4580.
Bit Timing Is Arithmetic, Not a Constant
The ECAN module does not have a “500 kbit/s” setting. It has a bit time expressed in time quanta, and a time quantum derived from the oscillator:
“ TQ = 2 x (BRP + 1) / FOSC bit time = (1 + PropSeg + PhaseSeg1 + PhaseSeg2) x TQ “
Those four segments are written into BRGCON1, BRGCON2 and BRGCON3 by the init code. The values are const data in flash, and they are computed for one specific oscillator frequency — usually in a comment like “40 MHz, 500 kbit/s, 80% sample point”.
Load that image onto a board with a different crystal, or onto a board where the PLL multiplier is configured differently, and the arithmetic no longer holds. The node still transmits. It still receives short frames from a tolerant neighbour. What it does not survive is a long cable, a second node with a slightly different timing, or a temperature that pulls the oscillator.
CAN tolerates about one percent total timing error across a network. A clone that is two percent out works on a two-node bench and fails on a twelve-node bus.
The Filters Are Runtime State
The ECAN block on this family has three transmit buffers, two receive buffers, six acceptance filters and two acceptance masks. The masks and filters are registers in RAM, written by init code, not stored as a table the module reads on its own.
That has a consequence worth stating plainly: a partially recovered image can produce a node that transmits correctly and *receives everything*. With filters left at their reset state, every frame on the bus is accepted into the two receive buffers. The application then processes messages meant for other nodes, and the symptom is not “no communication” — it is “the actuator responds to the wrong command”, which is much worse to diagnose.
The filter map is a design decision encoded in the image: which IDs this node listens for, which it ignores, which it acknowledges. If the recovered file is missing the block that contains the filter setup, the node is not a copy of the original. It is a new device that happens to share a PCB.
A Sequence That Catches Both Problems
1. Read the config block first. 0x300000–0x30000B plus 0x3FFFFE and 0x3FFFFF. The oscillator selection in CONFIG1H determines whether the timing constants are even reachable. 2. Identify the oscillator on the board. Crystal frequency and load capacitors, or the internal oscillator setting. This is a photograph, not a measurement. 3. Disassemble the CAN init routine. Look for three writes to consecutive BRGCON addresses. That is the timing setup, and the three bytes tell you the intended FOSC. 4. Verify by traffic, not by power. A node that powers up proves nothing. A node that exchanges its normal frame set with a second real node for an hour proves something.
Step 3 is the one that distinguishes a competent delivery from a file dump. If the disassembly shows the timing registers written from values computed at runtime rather than from constants, the image depends on a measurement the original firmware took — and the replacement has to reproduce it.
When the Array Is Closed
If all four blocks are set, the programming interface returns nothing usable and the route runs through the die, which is the invasive extraction path. The recovered image is then checked against the same map: reset vector, block boundaries, configuration words, and — for a CAN node — a disassembly of the filter and timing setup before anything is programmed.
The device ID at 0x3FFFFE distinguishes a 4480 from a 4580 or a 2680. The 16 KB image is a subset of the 4580’s 32 KB one, so a file from the smaller part runs on the larger — occasionally useful when sourcing.
The chip extraction analysis route is worth taking when the product is safety-related, because the acceptance test is behavioural rather than a byte comparison — and a byte comparison cannot tell you that a filter mask is wrong.
Send the marking photograph, the board photograph and the crystal frequency. Those three settle the scope faster than the part number, and the services page lists what each route covers.