diff --git a/gen_c/gen_messages.py b/gen_c/gen_messages.py
index a44a829..54cddf8 100644
--- a/gen_c/gen_messages.py
+++ b/gen_c/gen_messages.py
@@ -62,11 +62,11 @@ typedef struct {msg_struct} {{
{struct_fields_str}
}} {msg_type};
-void {NS_PREFIX_LOWER}{m.name_lower}_msg_encode(uint8_t src_id, uint8_t dst_id, const {msg_type} *msg, {GENERIC_MSG_TYPE} *packet) {{
+static inline void {NS_PREFIX_LOWER}msg_{m.name_lower}_encode(uint8_t src_id, uint8_t dst_id, const {msg_type} *msg, {GENERIC_MSG_TYPE} *packet) {{
packet->id = {MSG_ID_PREFIX}{m.name};
packet->src_id = src_id;
packet->dst_id = dst_id;
- packet->length = {MSG_ID_PREFIX}{m.id}_LEN + HYDROLINK_NON_PAYLOAD_LEN;
+ packet->payload_length = {MSG_ID_PREFIX}{m.id}_LEN + HYDROLINK_NON_PAYLOAD_LEN;
{encode_payload_str}
}}
""")
@@ -77,6 +77,6 @@ static inline {field.type} {msg_name}_get_{field.name}(const {GENERIC_MSG_TYPE}
return HYDROLINK_RETURN_{field.type}(packet, {field.wire_offset});
}}""")
f.write(f"""
-static inline void {NS_PREFIX_LOWER}msg{m.name_lower}_decode(const {GENERIC_MSG_TYPE} *packet, {msg_type} *{m.name_lower}) {{
+static inline void {NS_PREFIX_LOWER}msg_{m.name_lower}_decode(const {GENERIC_MSG_TYPE} *packet, {msg_type} *{m.name_lower}) {{
{decode_payload_str(m)}
}}""")
diff --git a/gen_c/hydrolink_gen_c.py b/gen_c/hydrolink_gen_c.py
index 7682e22..65ea1fc 100644
--- a/gen_c/hydrolink_gen_c.py
+++ b/gen_c/hydrolink_gen_c.py
@@ -13,10 +13,11 @@ def generate_main_header(msgs, dir):
with open(os.path.join(dir, "hydrolink.h"), "w") as f:
f.write(f"""#pragma once
#include "protocol.h"
+#include "hydrolink_enums.h"
{"\n".join(f"#include \"{GENERIC_MSG_NAME}_{msg.name_lower}.h\"" for msg in msgs)}
""")
-def generate_protocol(xml, dir):
+def generate_protocol(xml, msgs, dir):
put_defines = []
for typename in TYPE_LENGTHS:
length = TYPE_LENGTHS[typename]
@@ -41,6 +42,44 @@ def generate_protocol(xml, dir):
#define HYDROLINK_MAX_PAYLOAD_LEN {xml.largest_payload}
#define HYDROLINK_MAX_MSG_LEN (HYDROLINK_MAX_PAYLOAD_LEN + HYDROLINK_NON_PAYLOAD_LEN)
+typedef struct {{
+ uint8_t msg_id;
+ uint8_t crc_extra;
+}} hydrolink_crc_extra_t;
+
+#define HYDROLINK_MSG_CRCS {{{", ".join(f"{{{msg.id}, {msg.crc_extra}}}" for msg in msgs)}}}
+
+/**
+* @brief Get the crc_extra byte corresponding to msg_id
+*
+* @param msg_id the message's id
+* @param crc[out] the crc_extra byte as output of this function
+* @return Return 1 if successfull, 0 otherwise.
+**/
+static inline uint8_t hydrolink_get_crc_extra(uint8_t msg_id, uint8_t *crc) {{
+ static const hydrolink_crc_extra_t crcs[] = HYDROLINK_MSG_CRCS;
+ uint8_t left = 0;
+ uint8_t right = sizeof(crcs) / sizeof(crcs[0]) - 1;
+ while (left < right) {{
+ uint8_t center = (left+right+1) / 2;
+ if (msg_id < crcs[center].msg_id) {{
+ right = center - 1;
+ continue;
+ }}
+ if (msg_id > crcs[center].msg_id) {{
+ left = center;
+ continue;
+ }}
+ left = center;
+ break;
+ }}
+ if (crcs[left].msg_id != msg_id) {{
+ return 0;
+ }}
+ *crc = crcs[left].crc_extra;
+ return 1;
+}}
+
struct {GENERIC_MSG_STRUCT};
typedef struct {GENERIC_MSG_STRUCT} {GENERIC_MSG_TYPE};
@@ -59,19 +98,19 @@ struct {GENERIC_MSG_STRUCT} {{
{put_defines_str}
-inline void byte_swap_2(char *dst, const char *src) {{
+static inline void byte_swap_2(char *dst, const char *src) {{
dst[0] = src[1];
dst[1] = src[0];
}}
-inline void byte_swap_4(char *dst, const char *src) {{
+static inline void byte_swap_4(char *dst, const char *src) {{
dst[0] = src[3];
dst[1] = src[2];
dst[2] = src[1];
dst[3] = src[0];
}}
-inline void byte_swap_8(char *dst, const char *src) {{
+static inline void byte_swap_8(char *dst, const char *src) {{
dst[0] = src[7];
dst[1] = src[6];
dst[2] = src[5];
@@ -100,9 +139,9 @@ static inline TYPE HYDROLINK_RETURN_## TYPE(const {GENERIC_MSG_TYPE} *msg, uint8
HYDROLINK_MSG_RETURN_TYPE({typename}, {length})
""")
f.write("""
-inline void crc_xmodem_init(uint16_t *crc) { *crc = 0; }
+static inline void crc_xmodem_init(uint16_t *crc) { *crc = 0; }
-inline void crc_xmodem_accumulate(uint8_t data, uint16_t *crc) {
+static inline void crc_xmodem_accumulate(uint8_t data, uint16_t *crc) {
*crc = *crc ^ ((uint16_t)data << 8);
for (uint8_t j = 0; j < 8; j++) {
if (*crc & 0x8000) {
@@ -113,7 +152,7 @@ inline void crc_xmodem_accumulate(uint8_t data, uint16_t *crc) {
}
}
-inline uint16_t crc_xmodem_calculate(const uint8_t *data, uint8_t length) {
+static inline uint16_t crc_xmodem_calculate(const uint8_t *data, uint8_t length) {
uint16_t crc;
crc_xmodem_init(&crc);
for (uint8_t i = 0; i < length; i++) {
@@ -121,15 +160,29 @@ inline uint16_t crc_xmodem_calculate(const uint8_t *data, uint8_t length) {
}
return crc;
}
-""")
- f.write(f"""
-void hydrolink_fill_header_and_crc({GENERIC_MSG_TYPE} *msg, uint8_t msg_id, uint8_t payload_length, uint8_t dst_id, uint8_t src_id, uint8_t crc_extra) {{
- msg->id = msg_id;
- msg->payload_length = payload_length;
- msg->dst_id = dst_id;
- msg->src_id = src_id;
+
+static inline uint16_t hydrolink_calculate_crc(const uint8_t *payload, uint8_t length, uint8_t crc_extra) {
uint16_t crc;
crc_xmodem_init(&crc);
+ for(int i = 0; i < length; ++i) {
+ crc_xmodem_accumulate(payload[i], &crc);
+ }
+ crc_xmodem_accumulate(crc_extra, &crc);
+ return crc;
+}
+""")
+ f.write(f"""
+static inline void hydrolink_fill_header_and_crc({GENERIC_MSG_TYPE} *msg, uint8_t msg_id, uint8_t payload_length, uint8_t dst_id, uint8_t src_id, uint8_t crc_extra) {{
+ uint16_t crc;
+ crc_xmodem_init(&crc);
+ msg->id = msg_id;
+ crc_xmodem_accumulate(msg->id, &crc);
+ msg->payload_length = payload_length;
+ crc_xmodem_accumulate(msg->payload_length, &crc);
+ msg->dst_id = dst_id;
+ crc_xmodem_accumulate(msg->dst_id, &crc);
+ msg->src_id = src_id;
+ crc_xmodem_accumulate(msg->src_id, &crc);
for(int i = 0; i < msg->payload_length; ++i) {{
crc_xmodem_accumulate(msg->payload[i], &crc);
}}
@@ -137,7 +190,7 @@ void hydrolink_fill_header_and_crc({GENERIC_MSG_TYPE} *msg, uint8_t msg_id, uint
msg->crc = crc;
}}
-uint8_t hydrolink_serialize_message({GENERIC_MSG_TYPE} *msg, uint8_t *buffer) {{
+static inline uint8_t hydrolink_serialize_message({GENERIC_MSG_TYPE} *msg, uint8_t *buffer) {{
buffer[0] = msg->id;
buffer[1] = msg->payload_length;
buffer[2] = msg->dst_id;
@@ -151,7 +204,7 @@ uint8_t hydrolink_serialize_message({GENERIC_MSG_TYPE} *msg, uint8_t *buffer) {{
return HYDROLINK_NON_PAYLOAD_LEN + msg->payload_length;
}}
-uint8_t hydrolink_deserialize_header({GENERIC_MSG_TYPE} *msg, uint8_t *buffer, uint8_t buffer_length) {{
+static inline uint8_t hydrolink_deserialize_header({GENERIC_MSG_TYPE} *msg, uint8_t *buffer, uint8_t buffer_length) {{
if (buffer_length < HYDROLINK_NON_PAYLOAD_LEN) {{
return 0;
}}
@@ -176,8 +229,9 @@ def generate(xmls, out_dir):
msgs = []
for x in xmls:
msgs.extend(x.messages)
+ sorted(msgs, key=lambda msg: msg.id)
for msg in msgs:
generate_message_h(os.path.join(out_dir), msg)
generate_main_header(msgs, out_dir)
- generate_protocol(xmls[0], out_dir)
+ generate_protocol(xmls[0], msgs, out_dir)
generate_enums_h(out_dir, xmls[0].enums)
diff --git a/gen_python/hydrolink_gen_python.py b/gen_python/hydrolink_gen_python.py
index 4816f6a..7b2c33b 100644
--- a/gen_python/hydrolink_gen_python.py
+++ b/gen_python/hydrolink_gen_python.py
@@ -45,7 +45,41 @@ def generate_hydrolink(out_dir, msgs):
from .hydrolink_msg import HydrolinkHeader, HydrolinkMessage, CrcXmodem
from .hydrolink_msg_ids import {", ".join(f"HYDROLINK_MSG_ID_{msg.name}" for msg in msgs)}
{"\n".join(f"from .hydrolink_{msg.name_lower}_message import Hydrolink{to_camel_case(msg.name)}Message" for msg in msgs)}
-import hydrolink_enums as ENUMS
+from . import hydrolink_enums as ENUMS
+
+
+def cobs_decode(data):
+ output = []
+ index = 1
+ offset = data[0] - 1
+ while index < len(data):
+ if offset == 0:
+ output.append(0)
+ offset = data[index]
+ else:
+ output.append(data[index])
+ index = index + 1
+ offset = offset - 1
+ return bytearray(output)
+
+
+def cobs_encode(data):
+ output = [0 for i in range(len(data) + 2)]
+ dst_index = 1
+ zero_offset = 1
+ for src_byte in data:
+ if src_byte == 0:
+ output[dst_index - zero_offset] = zero_offset
+ zero_offset = 1
+ else:
+ output[dst_index] = src_byte
+ zero_offset += 1
+ dst_index += 1
+
+ output[dst_index - zero_offset] = zero_offset
+ output[dst_index] = 0
+
+ return output
MSG_ID_TO_CLASS_MAP = {{
diff --git a/gen_python/hydrolink_msg.py b/gen_python/hydrolink_msg.py
index bf1c779..37c8d14 100644
--- a/gen_python/hydrolink_msg.py
+++ b/gen_python/hydrolink_msg.py
@@ -161,11 +161,9 @@ class HydrolinkMessage:
self._header.payload_length = len(self._payload)
self._msg_buffer = self._header.pack() + self._payload
crc = CrcXmodem()
- print(f"Computing crc over {[int(x) for x in self._msg_buffer]}")
crc.accumulate(self._msg_buffer)
crc.accumulate(struct.pack("B", crc_extra))
self._crc = crc.crc
- print(f"Computed crc: {self._crc}")
self._msg_buffer += struct.pack("!H", self._crc)
return self._msg_buffer
diff --git a/hydrolink_def.xml b/hydrolink_def.xml
index 085025b..688bb6e 100644
--- a/hydrolink_def.xml
+++ b/hydrolink_def.xml
@@ -4,7 +4,7 @@
Command for getting/setting the state of a switch
-
+
Command for getting/setting the value of a PWM channel
@@ -37,7 +37,7 @@
-
+