Source code for fcp.generator

import os
from copy import deepcopy
from pprint import pprint
from datetime import datetime
from typing import *

from .spec import Signal, Message, Device, Common, Spec, make_sid


[docs]def date(): return str(datetime.now())
[docs]def decode_signature(device, message, signal): id = make_sid(device.id, message.id) return f"decode_{id}_{signal.name}"
[docs]def decode_signal_sig(device, message, signal): return f"{signal.type} {decode_signature(device, message, signal)} (CANdata msg);"
[docs]def msg_struct_sig(device, message): return f"msg_{device.name}_{message.name}_t"
[docs]def device_struct_sig(device): return f"dev_{device.name}_t"
[docs]def spec_struct_sig(spec): return "can_t"
[docs]def build_msg_sig(device): for message in device.msgs.values(): message.type = msg_struct_sig(device, message)
[docs]def multiplexor(signal, message): if signal.mux == "" or signal.mux == None: signal.mux_str = "" return sig = message.get_signal(signal.mux) signal.mux_str = f"[{sig.max_value - sig.min_value + 1}]"
[docs]def dst_type_decide(signal: Signal): if signal.scale != 1: return "float" if signal.type == "signed": if signal.length <= 8: return "int8_t" elif signal.length <= 16: return "int16_t" elif signal.length <= 32: return "int32_t" elif signal.length <= 64: return "int64_t" if signal.length <= 8: return "uint8_t" elif signal.length <= 16: return "uint16_t" elif signal.length <= 32: return "uint32_t" elif signal.length <= 64: return "uint64_t"
[docs]def enum_endianess(signal): if signal.byte_order == "big_endian": return "BIG" else: return "LITTLE"
[docs]def enum_type(signal): return signal.type.upper()
[docs]def build_devices(spec, device, tpl): mux_counts = 0 f_msgs : List[Message] = [msg for msg in device.msgs.values() if msg.frequency != 0] for message in device.msgs.values(): message.multiplexor = "" message.mux_count = 0 message.full_id = make_sid(device.id, message.id) for signal in message.signals.values(): signal.dst_type = dst_type_decide(signal) signal.enum_endianess = enum_endianess(signal) signal.enum_type = enum_type(signal) multiplexor(signal, message) if signal.mux != "": message.multiplexor = signal.mux if signal.mux_count != 1: message.mux_count = signal.mux_count for f_msg in f_msgs: if f_msg.mux_count != 0: mux_counts += 1 build_msg_sig(device) device.signature = device_struct_sig(device) h = tpl.render("h.jinja", device=device, date=date(), mux_counts = mux_counts, f_msgs=f_msgs) c = tpl.render("c.jinja", device=device, date=date(), f_msgs = f_msgs, mux_counts = mux_counts, ) return [(device.name+"_can.h", h), (device.name+"_can.c", c)]
[docs]def build_can_ids(spec, tpl): for device in spec.devices.values(): device.signature = device_struct_sig(device) spec.signature = spec_struct_sig(spec) build_msg_sig(spec.common) spec.common.signature = device_struct_sig(spec.common) logs = list(sorted(spec.logs.values(), key=lambda x: x.id)) can_ids_h = tpl.render("can_ids_h.jinja", devices=sorted(spec.devices.values(), key=lambda x: x.id), spec=spec, logs=logs, date=date(), ) can_ids_c = tpl.render("can_ids_c.jinja", devices=sorted(spec.devices.values(), key=lambda x: x.id), spec=spec, logs=logs, date=date(), ) return [("can_ids.c", can_ids_c), ("can_ids.h", can_ids_h)]
[docs]def build_common(spec, tpl): mux_counts = 0 for message in spec.common.msgs.values(): sigs = message.signals for signal in message.signals.values(): if signal.mux_count != 0: mux_counts += 1 signal.dst_type = dst_type_decide(signal) signal.enum_endianess = enum_endianess(signal) signal.enum_type = enum_type(signal) multiplexor(signal, message) build_msg_sig(spec.common) spec.common.signature = device_struct_sig(spec.common) common_c = tpl.render("common_c.jinja", spec=spec, date=date(), mux_counts=mux_counts) common_h = tpl.render("common_h.jinja", spec=spec, date=date(), mux_counts=mux_counts) return [("common.c", common_c), ("common.h", common_h)]
[docs]def build_enums(spec, tpl): enums_h = tpl.render("enums_h.jinja", spec=spec, date=date()) return [("can_enums.h", enums_h)]