mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-20 00:32:11 +08:00
35bd9d9fb3
e92e74311 whitespace after comma 5d33ec0f1 two spaces before inline comment 73685b609 fix linter complaint about whitespace around operators b15edbc1b fix linter complaint about inline comment whitespace 4ac30725b clean up blank lines 0430bfa5c run pre commit in ci (#268) 2ade6eeba Subaru DBC update (#242) d1185a53e Toyota ACC_CONTROL PERMIT_BRAKING and ACCEL_CMT_ALT speculated definition (#258) e6766bbbb Update SCC ECU Messages for OP Long Dev. (#267) b49b9ee75 Add DAW (#175) 3b5cccba0 Fixed up cell voltage readings and added more commands (#220) 8b0449327 Mazda: add missing static bits, tidy up endianness (#263) 124719992 Add BSD_RCTA to Subaru Global (#244) af1821f84 fix endianness in signal from new hyundai message 7ef41084b Add gas/brake message for hyundai EVs, from @TK211X 472aabb4f Subaru preglobal update (#260) 45c0d9ecc fix lta message (#262) 11343c108 Library cleanup (#261) 67d70cb86 Fix Toyota message size git-subtree-dir: opendbc git-subtree-split: e92e74311a7ed66922629bec4b8cee7c8db1b9f0
127 lines
4.4 KiB
Python
Executable File
127 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from __future__ import print_function
|
|
import os
|
|
import sys
|
|
|
|
import jinja2
|
|
|
|
from collections import Counter
|
|
from opendbc.can.dbc import dbc
|
|
|
|
def process(in_fn, out_fn):
|
|
dbc_name = os.path.split(out_fn)[-1].replace('.cc', '')
|
|
#print("processing %s: %s -> %s" % (dbc_name, in_fn, out_fn))
|
|
|
|
template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc")
|
|
|
|
with open(template_fn, "r") as template_f:
|
|
template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True)
|
|
|
|
can_dbc = dbc(in_fn)
|
|
|
|
# process counter and checksums first
|
|
msgs = [(address, msg_name, msg_size, sorted(msg_sigs, key=lambda s: s.name not in ("COUNTER", "CHECKSUM")))
|
|
for address, ((msg_name, msg_size), msg_sigs) in sorted(can_dbc.msgs.items()) if msg_sigs]
|
|
|
|
def_vals = {a: sorted(set(b)) for a, b in can_dbc.def_vals.items()} # remove duplicates
|
|
def_vals = sorted(def_vals.items())
|
|
|
|
if can_dbc.name.startswith(("honda_", "acura_")):
|
|
checksum_type = "honda"
|
|
checksum_size = 4
|
|
counter_size = 2
|
|
checksum_start_bit = 3
|
|
counter_start_bit = 5
|
|
little_endian = False
|
|
elif can_dbc.name.startswith(("toyota_", "lexus_")):
|
|
checksum_type = "toyota"
|
|
checksum_size = 8
|
|
counter_size = None
|
|
checksum_start_bit = 7
|
|
counter_start_bit = None
|
|
little_endian = False
|
|
elif can_dbc.name.startswith(("vw_", "volkswagen_", "audi_", "seat_", "skoda_")):
|
|
checksum_type = "volkswagen"
|
|
checksum_size = 8
|
|
counter_size = 4
|
|
checksum_start_bit = 0
|
|
counter_start_bit = 0
|
|
little_endian = True
|
|
elif can_dbc.name.startswith(("subaru_global_")):
|
|
checksum_type = "subaru"
|
|
checksum_size = 8
|
|
counter_size = None
|
|
checksum_start_bit = 0
|
|
counter_start_bit = None
|
|
little_endian = True
|
|
elif can_dbc.name.startswith(("chrysler_")):
|
|
checksum_type = "chrysler"
|
|
checksum_size = 8
|
|
counter_size = None
|
|
checksum_start_bit = 7
|
|
counter_start_bit = None
|
|
little_endian = False
|
|
else:
|
|
checksum_type = None
|
|
checksum_size = None
|
|
counter_size = None
|
|
checksum_start_bit = None
|
|
counter_start_bit = None
|
|
little_endian = None
|
|
|
|
# sanity checks on expected COUNTER and CHECKSUM rules, as packer and parser auto-compute those signals
|
|
for address, msg_name, msg_size, sigs in msgs:
|
|
dbc_msg_name = dbc_name + " " + msg_name
|
|
for sig in sigs:
|
|
if checksum_type is not None:
|
|
# checksum rules
|
|
if sig.name == "CHECKSUM":
|
|
if sig.size != checksum_size:
|
|
sys.exit("%s: CHECKSUM is not %d bits long" % (dbc_msg_name, checksum_size))
|
|
if sig.start_bit % 8 != checksum_start_bit:
|
|
sys.exit("%s: CHECKSUM starts at wrong bit" % dbc_msg_name)
|
|
if little_endian != sig.is_little_endian:
|
|
sys.exit("%s: CHECKSUM has wrong endianess" % dbc_msg_name)
|
|
# counter rules
|
|
if sig.name == "COUNTER":
|
|
if counter_size is not None and sig.size != counter_size:
|
|
sys.exit("%s: COUNTER is not %d bits long" % (dbc_msg_name, counter_size))
|
|
if counter_start_bit is not None and sig.start_bit % 8 != counter_start_bit:
|
|
print(counter_start_bit, sig.start_bit)
|
|
sys.exit("%s: COUNTER starts at wrong bit" % dbc_msg_name)
|
|
if little_endian != sig.is_little_endian:
|
|
sys.exit("%s: COUNTER has wrong endianess" % dbc_msg_name)
|
|
# pedal rules
|
|
if address in [0x200, 0x201]:
|
|
if sig.name == "COUNTER_PEDAL" and sig.size != 4:
|
|
sys.exit("%s: PEDAL COUNTER is not 4 bits long" % dbc_msg_name)
|
|
if sig.name == "CHECKSUM_PEDAL" and sig.size != 8:
|
|
sys.exit("%s: PEDAL CHECKSUM is not 8 bits long" % dbc_msg_name)
|
|
|
|
# Fail on duplicate message names
|
|
c = Counter([msg_name for address, msg_name, msg_size, sigs in msgs])
|
|
for name, count in c.items():
|
|
if count > 1:
|
|
sys.exit("%s: Duplicate message name in DBC file %s" % (dbc_name, name))
|
|
|
|
parser_code = template.render(dbc=can_dbc, checksum_type=checksum_type, msgs=msgs, def_vals=def_vals, len=len)
|
|
|
|
with open(out_fn, "w") as out_f:
|
|
out_f.write(parser_code)
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
print("usage: %s dbc_directory output_filename" % (sys.argv[0],))
|
|
sys.exit(0)
|
|
|
|
dbc_dir = sys.argv[1]
|
|
out_fn = sys.argv[2]
|
|
|
|
dbc_name = os.path.split(out_fn)[-1].replace('.cc', '')
|
|
in_fn = os.path.join(dbc_dir, dbc_name + '.dbc')
|
|
|
|
process(in_fn, out_fn)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|