| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | extern const uint16_t FLAG_VOLKSWAGEN_LONG_CONTROL; | ||
| 4 | const uint16_t FLAG_VOLKSWAGEN_LONG_CONTROL = 1; | ||
| 5 | |||
| 6 | static uint8_t volkswagen_crc8_lut_8h2f[256]; // Static lookup table for CRC8 poly 0x2F, aka 8H2F/AUTOSAR | ||
| 7 | |||
| 8 | extern bool volkswagen_longitudinal; | ||
| 9 | bool volkswagen_longitudinal = false; | ||
| 10 | |||
| 11 | extern bool volkswagen_set_button_prev; | ||
| 12 | bool volkswagen_set_button_prev = false; | ||
| 13 | |||
| 14 | extern bool volkswagen_resume_button_prev; | ||
| 15 | bool volkswagen_resume_button_prev = false; | ||
| 16 | |||
| 17 | |||
| 18 | #define MSG_LH_EPS_03 0x09F // RX from EPS, for driver steering torque | ||
| 19 | #define MSG_ESP_19 0x0B2 // RX from ABS, for wheel speeds | ||
| 20 | #define MSG_ESP_05 0x106 // RX from ABS, for brake switch state | ||
| 21 | #define MSG_TSK_06 0x120 // RX from ECU, for ACC status from drivetrain coordinator | ||
| 22 | #define MSG_MOTOR_20 0x121 // RX from ECU, for driver throttle input | ||
| 23 | #define MSG_ACC_06 0x122 // TX by OP, ACC control instructions to the drivetrain coordinator | ||
| 24 | #define MSG_HCA_01 0x126 // TX by OP, Heading Control Assist steering torque | ||
| 25 | #define MSG_GRA_ACC_01 0x12B // TX by OP, ACC control buttons for cancel/resume | ||
| 26 | #define MSG_ACC_07 0x12E // TX by OP, ACC control instructions to the drivetrain coordinator | ||
| 27 | #define MSG_ACC_02 0x30C // TX by OP, ACC HUD data to the instrument cluster | ||
| 28 | #define MSG_LDW_02 0x397 // TX by OP, Lane line recognition and text alerts | ||
| 29 | #define MSG_MOTOR_14 0x3BE // RX from ECU, for brake switch status | ||
| 30 | |||
| 31 | |||
| 32 | 4091 | static uint32_t volkswagen_mqb_meb_get_checksum(const CANPacket_t *to_push) { | |
| 33 | 4091 | return (uint8_t)GET_BYTE(to_push, 0); | |
| 34 | } | ||
| 35 | |||
| 36 | 8182 | static uint8_t volkswagen_mqb_meb_get_counter(const CANPacket_t *to_push) { | |
| 37 | // MQB/MEB message counters are consistently found at LSB 8. | ||
| 38 | 8182 | return (uint8_t)GET_BYTE(to_push, 1) & 0xFU; | |
| 39 | } | ||
| 40 | |||
| 41 | 4091 | static uint32_t volkswagen_mqb_meb_compute_crc(const CANPacket_t *to_push) { | |
| 42 | 4091 | int addr = GET_ADDR(to_push); | |
| 43 | 4091 | int len = GET_LEN(to_push); | |
| 44 | |||
| 45 | // This is CRC-8H2F/AUTOSAR with a twist. See the OpenDBC implementation | ||
| 46 | // of this algorithm for a version with explanatory comments. | ||
| 47 | |||
| 48 | 4091 | uint8_t crc = 0xFFU; | |
| 49 |
2/2✓ Branch 0 taken 28637 times.
✓ Branch 1 taken 4091 times.
|
32728 | for (int i = 1; i < len; i++) { |
| 50 | 28637 | crc ^= (uint8_t)GET_BYTE(to_push, i); | |
| 51 | 28637 | crc = volkswagen_crc8_lut_8h2f[crc]; | |
| 52 | } | ||
| 53 | |||
| 54 | 4091 | uint8_t counter = volkswagen_mqb_meb_get_counter(to_push); | |
| 55 |
2/2✓ Branch 0 taken 4026 times.
✓ Branch 1 taken 65 times.
|
4091 | if (addr == MSG_LH_EPS_03) { |
| 56 | 4026 | crc ^= (uint8_t[]){0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5}[counter]; | |
| 57 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 47 times.
|
65 | } else if (addr == MSG_ESP_05) { |
| 58 | 18 | crc ^= (uint8_t[]){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}[counter]; | |
| 59 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 31 times.
|
47 | } else if (addr == MSG_TSK_06) { |
| 60 | 16 | crc ^= (uint8_t[]){0xC4,0xE2,0x4F,0xE4,0xF8,0x2F,0x56,0x81,0x9F,0xE5,0x83,0x44,0x05,0x3F,0x97,0xDF}[counter]; | |
| 61 |
2/2✓ Branch 0 taken 22 times.
✓ Branch 1 taken 9 times.
|
31 | } else if (addr == MSG_MOTOR_20) { |
| 62 | 22 | crc ^= (uint8_t[]){0xE9,0x65,0xAE,0x6B,0x7B,0x35,0xE5,0x5F,0x4E,0xC7,0x86,0xA2,0xBB,0xDD,0xEB,0xB4}[counter]; | |
| 63 |
1/2✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
|
9 | } else if (addr == MSG_GRA_ACC_01) { |
| 64 | 9 | crc ^= (uint8_t[]){0x6A,0x38,0xB4,0x27,0x22,0xEF,0xE1,0xBB,0xF8,0x80,0x84,0x49,0xC7,0x9E,0x1E,0x2B}[counter]; | |
| 65 | } else { | ||
| 66 | // Undefined CAN message, CRC check expected to fail | ||
| 67 | } | ||
| 68 | 4091 | crc = volkswagen_crc8_lut_8h2f[crc]; | |
| 69 | |||
| 70 | 4091 | return (uint8_t)(crc ^ 0xFFU); | |
| 71 | } | ||
| 72 |