From 7f519f76a8249a6d8295664407a12c6a1835d150 Mon Sep 17 00:00:00 2001 From: Steven Chow Date: Mon, 4 Nov 2024 00:55:48 +0000 Subject: [PATCH 1/3] modified generator --- libraries/codegen/bms_carrier_tx_all.c | 60 +++++++++++++++++++++ libraries/codegen/generator.py | 28 +++++++++- libraries/codegen/templates/_tx_all.c.jinja | 3 +- 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 libraries/codegen/bms_carrier_tx_all.c diff --git a/libraries/codegen/bms_carrier_tx_all.c b/libraries/codegen/bms_carrier_tx_all.c new file mode 100644 index 000000000..973102719 --- /dev/null +++ b/libraries/codegen/bms_carrier_tx_all.c @@ -0,0 +1,60 @@ +#include + +#include "can_board_ids.h" +#include "can_codegen.h" + +static CanMessage s_msg = { + .type = CAN_MSG_TYPE_DATA, +}; +static void prv_tx_can_message(CanMessageId id, uint8_t num_bytes, uint64_t data) { + s_msg.id.raw = id, + s_msg.dlc = num_bytes; + s_msg.data = data; + s_msg.extended = (s_msg.id.msg_id >= CAN_MSG_MAX_STD_IDS); + can_transmit(&s_msg); +} + +void can_tx_all() { + prv_tx_can_message( + SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_STATUS,7, + (uint64_t) g_tx_struct.battery_status_fault << 0 | + (uint64_t) g_tx_struct.battery_status_fault_val << 16 | + (uint64_t) g_tx_struct.battery_status_aux_batt_v << 32 | + (uint64_t) g_tx_struct.battery_status_afe_status << 48); + prv_tx_can_message( + SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_INFO,6, + (uint64_t) g_tx_struct.battery_info_fan1 << 0 | + (uint64_t) g_tx_struct.battery_info_fan2 << 8 | + (uint64_t) g_tx_struct.battery_info_max_cell_v << 16 | + (uint64_t) g_tx_struct.battery_info_min_cell_v << 32); + prv_tx_can_message( + SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_VT,8, + (uint64_t) g_tx_struct.battery_vt_voltage << 0 | + (uint64_t) g_tx_struct.battery_vt_current << 16 | + (uint64_t) g_tx_struct.battery_vt_temperature << 32 | + (uint64_t) g_tx_struct.battery_vt_batt_perc << 48); + prv_tx_can_message( + SYSTEM_CAN_MESSAGE_BMS_CARRIER_BATTERY_RELAY_INFO,1, + (uint64_t) g_tx_struct.battery_relay_info_state << 0); + prv_tx_can_message( + SYSTEM_CAN_MESSAGE_BMS_CARRIER_AFE1_STATUS,8, + (uint64_t) g_tx_struct.AFE1_status_id << 0 | + (uint64_t) g_tx_struct.AFE1_status_temp << 8 | + (uint64_t) g_tx_struct.AFE1_status_v1 << 16 | + (uint64_t) g_tx_struct.AFE1_status_v2 << 32 | + (uint64_t) g_tx_struct.AFE1_status_v3 << 48); + prv_tx_can_message( + SYSTEM_CAN_MESSAGE_BMS_CARRIER_AFE2_STATUS,8, + (uint64_t) g_tx_struct.AFE2_status_id << 0 | + (uint64_t) g_tx_struct.AFE2_status_temp << 8 | + (uint64_t) g_tx_struct.AFE2_status_v1 << 16 | + (uint64_t) g_tx_struct.AFE2_status_v2 << 32 | + (uint64_t) g_tx_struct.AFE2_status_v3 << 48); + prv_tx_can_message( + SYSTEM_CAN_MESSAGE_BMS_CARRIER_AFE3_STATUS,8, + (uint64_t) g_tx_struct.AFE3_status_id << 0 | + (uint64_t) g_tx_struct.AFE3_status_temp << 8 | + (uint64_t) g_tx_struct.AFE3_status_v1 << 16 | + (uint64_t) g_tx_struct.AFE3_status_v2 << 32 | + (uint64_t) g_tx_struct.AFE3_status_v3 << 48); +} \ No newline at end of file diff --git a/libraries/codegen/generator.py b/libraries/codegen/generator.py index 11a9cb167..c7f89528a 100644 --- a/libraries/codegen/generator.py +++ b/libraries/codegen/generator.py @@ -60,7 +60,7 @@ def check_yaml_file(data): def get_data(): boards = [] messages = [] - + messages_dict = {} for yaml_path in Path(__file__).parent.glob("boards/*.yaml"): # read yaml with open(yaml_path, "r") as f: @@ -94,7 +94,31 @@ def get_data(): "receiver": message["target"], }) - return {"Boards": boards, "Messages": messages} + messages_dict[message["id"]] = { + "id": message["id"], + "critical": message["critical"], + "name": message_name, + "signals": signals, + "sender": sender, + "receiver": message["target"], + } + + # print("Boards:") + # for board in boards: + # print(f" - {board}") + + # print("\nMessages:") + # for message in messages: + # print(f"Message Name: {message['name']}") + # print(f" ID: {message['id']}") + # print(f" Critical: {message['critical']}") + # print(f" Sender: {message['sender']}") + # print(f" Receiver: {message['receiver']}") + # print(" Signals:") + # for signal in message['signals']: + # print(f" - Name: {signal['name']}, Start Bit: {signal['start_bit']}, Length: {signal['length']}") + + return {"Boards": boards, "Messages": messages, "Messages_dict": messages_dict} def main(): diff --git a/libraries/codegen/templates/_tx_all.c.jinja b/libraries/codegen/templates/_tx_all.c.jinja index de78aaff1..553485367 100644 --- a/libraries/codegen/templates/_tx_all.c.jinja +++ b/libraries/codegen/templates/_tx_all.c.jinja @@ -26,5 +26,4 @@ void can_tx_all() { (uint64_t) g_tx_struct.{{message.name}}_{{signal.name}} << {{signal.start_bit}}{{ " |" if not loop.last }} {%- endfor -%} ); -{%- endfor %} -} +{% } From 53b819a25eb8640d18ed902237e305fbb3cbda86 Mon Sep 17 00:00:00 2001 From: Steven Chow Date: Mon, 4 Nov 2024 02:58:43 +0000 Subject: [PATCH 2/3] created decode_packet function --- libraries/codegen/generator.py | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/libraries/codegen/generator.py b/libraries/codegen/generator.py index c7f89528a..3f5efd257 100644 --- a/libraries/codegen/generator.py +++ b/libraries/codegen/generator.py @@ -121,6 +121,50 @@ def get_data(): return {"Boards": boards, "Messages": messages, "Messages_dict": messages_dict} +def decode_packet(messages_dict, bitstream): + clean_bitstream = bitstream.replace(" ", "") + + # Extract the source_id + source_id_binary = clean_bitstream[0:8] # start: start + length + source_id = int(source_id_binary, 2) + print(source_id) + + # Extract the msg_id (next 24 bits) + msg_id_binary = clean_bitstream[8:32] + msg_id = int(msg_id_binary, 2) + print(msg_id) + + if msg_id in messages_dict: + message = messages_dict[msg_id] + else: + print(f"Source ID {msg_id} not found in messages_dict.") + return + + parsed_signals = [] + data_start_bit = 56 + + # Iterate through each signal in the message dictionary + for signal in message['signals']: + name = signal['name'] + start_bit = signal['start_bit'] + data_start_bit + length = signal['length'] + + # # Extract the relevant bits for the signal + signal_bits = clean_bitstream[start_bit:start_bit + length] + + # # Convert the bits to a decimal value + signal_value = int(signal_bits, 2) + + # # Store the parsed signal value + parsed_signals.append({ + "name": name, + "value": signal_value + }) + + return {"message ID": msg_id, + "message name": messages_dict[msg_id]["name"], + "signals": parsed_signals} + def main(): parser = argparse.ArgumentParser() parser.add_argument("-t", "--template", nargs='+', default=[], dest="templates", @@ -131,6 +175,18 @@ def main(): args = parser.parse_args() data = get_data() + + # # Define message values + # source_id = 1 # source_id (3 + 4 bits) + # type_field = 0 # type (1 bit) + # msg_id = 3 # msg_id (24 bits) + # dlc = 5 Bytes # (40 bits) + # throttle_output_value = 30 # throttle_value (32 bits) + # brake_output_value = 31 # brake_value (8 bits) + + print(decode_packet(data["Messages_dict"], "0000 0001 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0001 1110 0001 1111")) + + data.update({"Board": args.board}) template_loader = jinja2.FileSystemLoader( From 86791005a4672f74bb466bb77d85a4553c36c31a Mon Sep 17 00:00:00 2001 From: vagrant Date: Tue, 5 Nov 2024 01:40:34 +0000 Subject: [PATCH 3/3] Created python_autogen_py.jinja --- libraries/codegen/generator.py | 87 ++++--------------- .../codegen/templates/python_autogen.py.jinja | 50 +++++++++++ 2 files changed, 65 insertions(+), 72 deletions(-) create mode 100644 libraries/codegen/templates/python_autogen.py.jinja diff --git a/libraries/codegen/generator.py b/libraries/codegen/generator.py index 3f5efd257..d93d2f3cc 100644 --- a/libraries/codegen/generator.py +++ b/libraries/codegen/generator.py @@ -103,68 +103,23 @@ def get_data(): "receiver": message["target"], } - # print("Boards:") - # for board in boards: - # print(f" - {board}") - - # print("\nMessages:") - # for message in messages: - # print(f"Message Name: {message['name']}") - # print(f" ID: {message['id']}") - # print(f" Critical: {message['critical']}") - # print(f" Sender: {message['sender']}") - # print(f" Receiver: {message['receiver']}") - # print(" Signals:") - # for signal in message['signals']: - # print(f" - Name: {signal['name']}, Start Bit: {signal['start_bit']}, Length: {signal['length']}") + print("Boards:") + for board in boards: + print(f" - {board}") + + print("\nMessages:") + for message in messages: + print(f"Message Name: {message['name']}") + print(f" ID: {message['id']}") + print(f" Critical: {message['critical']}") + print(f" Sender: {message['sender']}") + print(f" Receiver: {message['receiver']}") + print(" Signals:") + for signal in message['signals']: + print(f" - Name: {signal['name']}, Start Bit: {signal['start_bit']}, Length: {signal['length']}") return {"Boards": boards, "Messages": messages, "Messages_dict": messages_dict} - -def decode_packet(messages_dict, bitstream): - clean_bitstream = bitstream.replace(" ", "") - - # Extract the source_id - source_id_binary = clean_bitstream[0:8] # start: start + length - source_id = int(source_id_binary, 2) - print(source_id) - - # Extract the msg_id (next 24 bits) - msg_id_binary = clean_bitstream[8:32] - msg_id = int(msg_id_binary, 2) - print(msg_id) - - if msg_id in messages_dict: - message = messages_dict[msg_id] - else: - print(f"Source ID {msg_id} not found in messages_dict.") - return - - parsed_signals = [] - data_start_bit = 56 - - # Iterate through each signal in the message dictionary - for signal in message['signals']: - name = signal['name'] - start_bit = signal['start_bit'] + data_start_bit - length = signal['length'] - - # # Extract the relevant bits for the signal - signal_bits = clean_bitstream[start_bit:start_bit + length] - - # # Convert the bits to a decimal value - signal_value = int(signal_bits, 2) - - # # Store the parsed signal value - parsed_signals.append({ - "name": name, - "value": signal_value - }) - - return {"message ID": msg_id, - "message name": messages_dict[msg_id]["name"], - "signals": parsed_signals} - def main(): parser = argparse.ArgumentParser() parser.add_argument("-t", "--template", nargs='+', default=[], dest="templates", @@ -175,18 +130,6 @@ def main(): args = parser.parse_args() data = get_data() - - # # Define message values - # source_id = 1 # source_id (3 + 4 bits) - # type_field = 0 # type (1 bit) - # msg_id = 3 # msg_id (24 bits) - # dlc = 5 Bytes # (40 bits) - # throttle_output_value = 30 # throttle_value (32 bits) - # brake_output_value = 31 # brake_value (8 bits) - - print(decode_packet(data["Messages_dict"], "0000 0001 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0001 1110 0001 1111")) - - data.update({"Board": args.board}) template_loader = jinja2.FileSystemLoader( @@ -199,6 +142,6 @@ def main(): output = env.get_template(template).render(data=data) Path(output_dir, get_file_name(template, args.board)).write_text(output) - + if __name__ == "__main__": main() diff --git a/libraries/codegen/templates/python_autogen.py.jinja b/libraries/codegen/templates/python_autogen.py.jinja new file mode 100644 index 000000000..8c430ac8a --- /dev/null +++ b/libraries/codegen/templates/python_autogen.py.jinja @@ -0,0 +1,50 @@ +{% set bitstream = data["bitstream"] -%} +{% set messages_dict = data["Messages_dict"] -%} + +def decode_packet(messages_dict, bitstream): + # Clean the bitstream by removing spaces + clean_bitstream = bitstream.replace(" ", "") + + # Extract the source_id (first 8 bits) + source_id_binary = clean_bitstream[0:8] + source_id = int(source_id_binary, 2) # Assuming it's a binary string + print(source_id) + + # Extract the msg_id (next 24 bits) + msg_id_binary = clean_bitstream[8:32] + msg_id = int(msg_id_binary, 2) # Assuming it's a binary string + print(msg_id) + + # Message definition + if 0 < msg_id <= 63: + message = messages_dict[msg_id] + else: + print(f"Message ID {msg_id} not found in messages dictionary.") + return + + parsed_signals = [] + data_start_bit = 56 + + # Iterate through each signal in the message dictionary + for signal in message['signals']: + name = signal['name'] + start_bit = signal['start_bit'] + data_start_bit + length = signal['length'] + + # Extract the relevant bits for the signal + signal_bits = clean_bitstream[start_bit:start_bit + length] + + # Convert the bits to a decimal value + signal_value = int(signal_bits, 2) # Assuming it's a binary string + + # Store the parsed signal value + parsed_signals.append({ + "name": name, + "value": signal_value + }) + + return { + "message ID": msg_id, + "message name": message["name"], + "signals": parsed_signals + } \ No newline at end of file