# CAN Protocol Reference The AddVantage PPG uses **J1939** protocol over CAN bus at **250 kbit/s** to receive engine data from the ECU. ## Overview J1939 is a higher-layer protocol built on CAN 2.0B (29-bit identifiers). The 29-bit arbitration ID contains: | Bits | Field | Description | |------|-------|-------------| | 28-26 | Priority | 0-7 (lower = higher priority) | | 25-24 | Reserved | Usually 0 | | 23-16 | PGN (high) | Parameter Group Number | | 15-8 | PGN (low) | | | 7-0 | Source Address | Transmitting ECU address | ## Extracting PGN from CAN ID ```c uint32_t extract_pgn(uint32_t can_id) { // Mask off priority and source address uint32_t pgn = (can_id >> 8) & 0x3FFFF; // For PDU1 format (PS < 240), PS is destination address if (((pgn >> 8) & 0xFF) < 240) { pgn &= 0x3FF00; // Mask off PS field } return pgn; } ``` ## Supported PGNs ### EEC1 (61444) - Electronic Engine Controller 1 Primary engine parameters. Transmitted at 10-100ms intervals. | Byte | Parameter | Resolution | Range | |------|-----------|------------|-------| | 0 | Engine Torque Mode | 4 bits | 0-15 | | 1 | Driver Demand Torque | 1%/bit - 125 | -125 to 125% | | 2 | Actual Engine Torque | 1%/bit - 125 | -125 to 125% | | 3-4 | Engine Speed | 0.125 RPM/bit | 0-8031.875 RPM | | 5 | Source Address | - | 0-255 | | 6-7 | Starter Mode | - | - | **Parsing Engine Speed (RPM):** ```c uint16_t speed_raw = data[3] | (data[4] << 8); uint16_t rpm = (uint16_t)(speed_raw * 0.125); ``` **Parsing Torque (%):** ```c int8_t torque = data[2] - 125; // Range: -125% to +125% ``` ### ET1 (65262) - Engine Temperature 1 Engine temperature sensors. Transmitted at 1000ms intervals. | Byte | Parameter | Resolution | Range | |------|-----------|------------|-------| | 0 | Engine Coolant Temp | 1°C/bit - 40 | -40 to 210°C | | 1 | Fuel Temp | 1°C/bit - 40 | -40 to 210°C | | 2-3 | Engine Oil Temp | 0.03125°C/bit - 273 | -273 to 1735°C | | 4-5 | Turbo Oil Temp | 0.03125°C/bit - 273 | -273 to 1735°C | | 6 | Engine Intercooler Temp | 1°C/bit - 40 | -40 to 210°C | | 7 | Engine Intercooler Thermostat | 0.4%/bit | 0-100% | **Parsing Coolant Temperature:** ```c int16_t coolant_temp = data[0] - 40; // Range: -40°C to +210°C ``` ### LFE (65266) - Fuel Economy Fuel consumption data. Transmitted at 100ms intervals. | Byte | Parameter | Resolution | Range | |------|-----------|------------|-------| | 0-1 | Fuel Rate | 0.05 L/h per bit | 0-3212.75 L/h | | 2-3 | Instantaneous Fuel Economy | 1/512 km/L per bit | 0-125.5 km/L | | 4-5 | Average Fuel Economy | 1/512 km/L per bit | 0-125.5 km/L | | 6 | Throttle Position | 0.4%/bit | 0-100% | | 7 | Reserved | - | - | **Parsing Fuel Rate:** ```c uint16_t fuel_raw = data[0] | (data[1] << 8); float fuel_rate_lph = fuel_raw * 0.05; // Liters per hour ``` ### ETC2 (61445) - Electronic Transmission Controller 2 Transmission data (optional). | Byte | Parameter | Resolution | Range | |------|-----------|------------|-------| | 0 | Selected Gear | - | -125 to 125 | | 1-2 | Current Gear Ratio | 0.001/bit | 0-64.255 | | 3 | Current Gear | - | -125 to 125 | | 4-5 | Transmission Range | 2 bits per state | - | ## Error Values J1939 uses special values to indicate errors or unavailable data: | Value | Meaning | |-------|---------| | 0xFE | Parameter error | | 0xFF | Not available | | 0xFFFE (16-bit) | Parameter error | | 0xFFFF (16-bit) | Not available | Always check for these values before using data: ```c if (data[0] != 0xFF) { coolant_temp = data[0] - 40; } else { // Data not available } ``` ## CAN Hardware Configuration The SKEAZ128 MSCAN peripheral is configured for: - **Bit Rate:** 250 kbit/s - **Sample Point:** ~75% - **Bus Timing:** Prescaler depends on bus clock ### Filter Configuration The firmware accepts all J1939 messages (no filtering). In a production system, you may want to filter for specific PGNs: ```c // Example: Accept only EEC1, ET1, LFE CAN1_SetAcceptanceFilter(PGN_EEC1 << 8, 0x00FFFF00); CAN1_SetAcceptanceFilter(PGN_ET1 << 8, 0x00FFFF00); CAN1_SetAcceptanceFilter(PGN_LFE << 8, 0x00FFFF00); ``` ## Wiring Standard CAN bus wiring: | Pin | Function | Color (typical) | |-----|----------|-----------------| | CAN_H | CAN High | Yellow | | CAN_L | CAN Low | Green | | GND | Ground | Black | **Termination:** 120Ω resistor between CAN_H and CAN_L at each end of the bus. ## Debugging with PCAN Use the CAN viewer tool to monitor live data: ```bash python tools/can_viewer.py ``` Or validate CAN data against ECU telemetry: ```bash python tools/can_validate.py --duration 10 --tolerance 5 ``` ## Message Timing Expected message rates from a typical diesel ECU: | PGN | Rate | Use Case | |-----|------|----------| | EEC1 | 10-20ms | Engine speed control | | ET1 | 1000ms | Temperature monitoring | | LFE | 100ms | Fuel calculation | The PPG samples CAN data continuously and uses the most recent values for fuel calculations.