mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
Accelerate Hyundai CAN FD checksums
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import math
|
||||
from binascii import crc_hqx
|
||||
from typing import cast
|
||||
|
||||
import numpy as np
|
||||
from opendbc.car import CanBusBase, CanData
|
||||
from opendbc.car.common.conversions import Conversions as CV
|
||||
from opendbc.car.crc import CRC16_XMODEM
|
||||
from opendbc.car.hyundai.ioniq6_bsm import BlindspotStatus, FRONT_NEUTRAL_BODY, rear_body
|
||||
from opendbc.car.hyundai.values import CAR, HyundaiFlags
|
||||
|
||||
@@ -437,11 +437,7 @@ def create_adrv_messages(packer, CAN, frame, *, template=None, drive_gear=False,
|
||||
|
||||
|
||||
def hkg_can_fd_checksum(address: int, sig, d: bytearray) -> int:
|
||||
crc = 0
|
||||
for i in range(2, len(d)):
|
||||
crc = ((crc << 8) ^ CRC16_XMODEM[(crc >> 8) ^ d[i]]) & 0xFFFF
|
||||
crc = ((crc << 8) ^ CRC16_XMODEM[(crc >> 8) ^ ((address >> 0) & 0xFF)]) & 0xFFFF
|
||||
crc = ((crc << 8) ^ CRC16_XMODEM[(crc >> 8) ^ ((address >> 8) & 0xFF)]) & 0xFFFF
|
||||
crc = crc_hqx(d[2:] + (address & 0xFFFF).to_bytes(2, "little"), 0)
|
||||
if len(d) == 8:
|
||||
crc ^= 0x5F29
|
||||
elif len(d) == 16:
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import unittest
|
||||
|
||||
from opendbc.car.hyundai.hyundaicanfd import hkg_can_fd_checksum
|
||||
|
||||
|
||||
def reference_checksum(address, data):
|
||||
crc = 0
|
||||
for byte in (*data[2:], address & 0xFF, (address >> 8) & 0xFF):
|
||||
for bit in range(7, -1, -1):
|
||||
feedback = (crc >> 15) ^ ((byte >> bit) & 1)
|
||||
crc = (crc << 1) & 0xFFFF
|
||||
if feedback:
|
||||
crc ^= 0x1021
|
||||
return crc ^ {8: 0x5F29, 16: 0x041D, 24: 0x819D, 32: 0x9F5B}.get(len(data), 0)
|
||||
|
||||
|
||||
class TestCanfdChecksum(unittest.TestCase):
|
||||
def test_matches_bitwise_reference_and_preserves_input(self):
|
||||
addresses = (0, 1, 0x1234, 0x7FE, 0x7FF, 0x800, 0x801,
|
||||
0xFFFE, 0xFFFF, 0x10000, 0x10001,
|
||||
0x1FFFFFFE, 0x1FFFFFFF, 0x20000000,
|
||||
-1, -0x10001, (1 << 160) | 0x1234)
|
||||
for length in range(65):
|
||||
payloads = (bytes(length), b"\xff" * length,
|
||||
bytes((i * 37 + length * 13) & 0xFF for i in range(length)))
|
||||
for pattern, payload in enumerate(payloads):
|
||||
for address in addresses:
|
||||
expected = reference_checksum(address, payload)
|
||||
for container in (bytes, bytearray):
|
||||
with self.subTest(length=length, pattern=pattern, address=address, container=container.__name__):
|
||||
data = container(payload)
|
||||
self.assertEqual(hkg_can_fd_checksum(address, None, data), expected)
|
||||
self.assertEqual(data, payload)
|
||||
|
||||
def test_first_two_bytes_are_ignored(self):
|
||||
for length in range(65):
|
||||
payload = bytes((i * 29 + 17) & 0xFF for i in range(length))
|
||||
expected = reference_checksum(0x1234, payload)
|
||||
for prefix in (b"\x00\x00", b"\xff\xff", b"\x5a\xa5"):
|
||||
for container in (bytes, bytearray):
|
||||
with self.subTest(length=length, prefix=prefix, container=container.__name__):
|
||||
data = container(prefix[:min(2, length)] + payload[2:])
|
||||
self.assertEqual(hkg_can_fd_checksum(0x1234, None, data), expected)
|
||||
|
||||
def test_only_low_sixteen_address_bits_are_used(self):
|
||||
for length in range(65):
|
||||
payload = bytes((i * 19 + 3) & 0xFF for i in range(length))
|
||||
for low_address in (0, 0x7FF, 0x800, 0x1234, 0xFFFF):
|
||||
expected = reference_checksum(low_address, payload)
|
||||
for address in (low_address - (1 << 80), low_address | (1 << 160)):
|
||||
for container in (bytes, bytearray):
|
||||
with self.subTest(length=length, address=address, container=container.__name__):
|
||||
self.assertEqual(hkg_can_fd_checksum(address, None, container(payload)), expected)
|
||||
|
||||
def test_zero_payload_length_adjustments(self):
|
||||
for length, expected in ((0, 0), (1, 0), (2, 0), (8, 0x5F29),
|
||||
(16, 0x041D), (24, 0x819D), (32, 0x9F5B), (64, 0)):
|
||||
with self.subTest(length=length):
|
||||
self.assertEqual(hkg_can_fd_checksum(0, None, bytes(length)), expected)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "ec474989597c90246eef09acaacab24b8bbf68c04b1271dbac521e005b84082a", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "13836c06f15783e9b64f424907c835e5acde61997c1c6a106f8037ee6560fded", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user