diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterCommands.c b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterCommands.c
new file mode 100644
index 0000000000..c88f82e26c
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterCommands.c
@@ -0,0 +1,248 @@
+// TransmuterCommands.c was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#include "TransmuterCommands.h"
+#include "fielddecode.h"
+#include "fieldencode.h"
+#include "scaleddecode.h"
+#include "scaledencode.h"
+
+/*!
+ * \brief Lookup label for 'TransmuterSystemCommands' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string label of the given entry
+ */
+const char* TransmuterSystemCommands_EnumLabel(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case CMD_TRANSMUTER_SET_CURRENT_TARGET_AUTO:
+ return "CMD_TRANSMUTER_SET_CURRENT_TARGET_AUTO";
+ case CMD_TRANSMUTER_SET_CURRENT_TARGET_MANUAL:
+ return "CMD_TRANSMUTER_SET_CURRENT_TARGET_MANUAL";
+ case CMD_TRANSMUTER_SET_RPM_TARGET_AUTO:
+ return "CMD_TRANSMUTER_SET_RPM_TARGET_AUTO";
+ case CMD_TRANSMUTER_SET_RPM_TARGET_MANUAL:
+ return "CMD_TRANSMUTER_SET_RPM_TARGET_MANUAL";
+ case CMD_TRANSMUTER_REQUEST_HF_DATA:
+ return "CMD_TRANSMUTER_REQUEST_HF_DATA";
+ }
+}
+
+/*!
+ * \brief Create the Transmuter_SetCurrentTargetAuto packet
+ *
+ * Set current target to auto mode
+ * \param _pg_pkt points to the packet which will be created by this function
+ */
+void encodeTransmuter_SetCurrentTargetAutoPacket(void* _pg_pkt)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ uint8ToBytes((uint8_t)(CMD_TRANSMUTER_SET_CURRENT_TARGET_AUTO), _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_SetCurrentTargetAutoPacketID());
+
+}// encodeTransmuter_SetCurrentTargetAutoPacket
+
+/*!
+ * \brief Decode the Transmuter_SetCurrentTargetAuto packet
+ *
+ * Set current target to auto mode
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_SetCurrentTargetAutoPacket(const void* _pg_pkt)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_SetCurrentTargetAutoPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_SetCurrentTargetAutoMinDataLength())
+ return 0;
+
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) CMD_TRANSMUTER_SET_CURRENT_TARGET_AUTO)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_SetCurrentTargetAutoPacket
+
+/*!
+ * \brief Create the Transmuter_SetCurrentTargetManual packet
+ *
+ * Set current target to auto mode
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param current is
+ */
+void encodeTransmuter_SetCurrentTargetManualPacket(void* _pg_pkt, float current)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ uint8ToBytes((uint8_t)(CMD_TRANSMUTER_SET_CURRENT_TARGET_MANUAL), _pg_data, &_pg_byteindex);
+
+ // Range of current is -255.0f to 255.0f.
+ float32ScaledTo2SignedBeBytes(current, _pg_data, &_pg_byteindex, 128.498039f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_SetCurrentTargetManualPacketID());
+
+}// encodeTransmuter_SetCurrentTargetManualPacket
+
+/*!
+ * \brief Decode the Transmuter_SetCurrentTargetManual packet
+ *
+ * Set current target to auto mode
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param current receives
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_SetCurrentTargetManualPacket(const void* _pg_pkt, float* current)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_SetCurrentTargetManualPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_SetCurrentTargetManualMinDataLength())
+ return 0;
+
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) CMD_TRANSMUTER_SET_CURRENT_TARGET_MANUAL)
+ return 0;
+
+ // Range of current is -255.0f to 255.0f.
+ (*current) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/128.498039f);
+
+ return 1;
+
+}// decodeTransmuter_SetCurrentTargetManualPacket
+
+/*!
+ * \brief Create the Transmuter_SetRpmTargetAuto packet
+ *
+ * Set RPM target to auto mode
+ * \param _pg_pkt points to the packet which will be created by this function
+ */
+void encodeTransmuter_SetRpmTargetAutoPacket(void* _pg_pkt)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ uint8ToBytes((uint8_t)(CMD_TRANSMUTER_SET_RPM_TARGET_AUTO), _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_SetRpmTargetAutoPacketID());
+
+}// encodeTransmuter_SetRpmTargetAutoPacket
+
+/*!
+ * \brief Decode the Transmuter_SetRpmTargetAuto packet
+ *
+ * Set RPM target to auto mode
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_SetRpmTargetAutoPacket(const void* _pg_pkt)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_SetRpmTargetAutoPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_SetRpmTargetAutoMinDataLength())
+ return 0;
+
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) CMD_TRANSMUTER_SET_RPM_TARGET_AUTO)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_SetRpmTargetAutoPacket
+
+/*!
+ * \brief Create the Transmuter_SetRpmTargetManual packet
+ *
+ * Set RPM target to auto mode
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param rpm is Manual RPM command
+ */
+void encodeTransmuter_SetRpmTargetManualPacket(void* _pg_pkt, uint16_t rpm)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ uint8ToBytes((uint8_t)(CMD_TRANSMUTER_SET_RPM_TARGET_MANUAL), _pg_data, &_pg_byteindex);
+
+ // Manual RPM command
+ // Range of rpm is 0 to 65535.
+ uint16ToBeBytes(rpm, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_SetRpmTargetManualPacketID());
+
+}// encodeTransmuter_SetRpmTargetManualPacket
+
+/*!
+ * \brief Decode the Transmuter_SetRpmTargetManual packet
+ *
+ * Set RPM target to auto mode
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param rpm receives Manual RPM command
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_SetRpmTargetManualPacket(const void* _pg_pkt, uint16_t* rpm)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_SetRpmTargetManualPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_SetRpmTargetManualMinDataLength())
+ return 0;
+
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) CMD_TRANSMUTER_SET_RPM_TARGET_MANUAL)
+ return 0;
+
+ // Manual RPM command
+ // Range of rpm is 0 to 65535.
+ (*rpm) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_SetRpmTargetManualPacket
+// end of TransmuterCommands.c
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterCommands.h b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterCommands.h
new file mode 100644
index 0000000000..c35572094f
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterCommands.h
@@ -0,0 +1,130 @@
+// TransmuterCommands.h was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#ifndef _TRANSMUTERCOMMANDS_H
+#define _TRANSMUTERCOMMANDS_H
+
+// Language target is C, C++ compilers: don't mangle us
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ */
+
+#include
+#include
+#include "TransmuterProtocol.h"
+
+/*!
+ * Enumeration of available system commands
+ */
+typedef enum
+{
+ CMD_TRANSMUTER_SET_CURRENT_TARGET_AUTO = 0xC0, //!< Set the current target to auto
+ CMD_TRANSMUTER_SET_CURRENT_TARGET_MANUAL, //!< Set the current target manual value
+ CMD_TRANSMUTER_SET_RPM_TARGET_AUTO = 0xD0, //!< Set the RPM target to auto
+ CMD_TRANSMUTER_SET_RPM_TARGET_MANUAL, //!< Set the RPM target to a manual value
+ CMD_TRANSMUTER_REQUEST_HF_DATA = 0xE0 //!< Request high-frequency transmuter specific telemetry data
+} TransmuterSystemCommands;
+
+//! \return the label of a 'TransmuterSystemCommands' enum entry, based on its value
+const char* TransmuterSystemCommands_EnumLabel(int value);
+
+//! Create the Transmuter_SetCurrentTargetAuto packet from parameters
+void encodeTransmuter_SetCurrentTargetAutoPacket(void* pkt);
+
+//! Decode the Transmuter_SetCurrentTargetAuto packet to parameters
+int decodeTransmuter_SetCurrentTargetAutoPacket(const void* pkt);
+
+//! return the packet ID for the Transmuter_SetCurrentTargetAuto packet
+#define getTransmuter_SetCurrentTargetAutoPacketID() (PKT_TRANSMUTER_SYSTEM_CMD)
+
+//! return the minimum encoded length for the Transmuter_SetCurrentTargetAuto packet
+#define getTransmuter_SetCurrentTargetAutoMinDataLength() (1)
+
+//! return the maximum encoded length for the Transmuter_SetCurrentTargetAuto packet
+#define getTransmuter_SetCurrentTargetAutoMaxDataLength() (1)
+
+/*!
+ * Set current target to auto mode
+ */
+typedef struct
+{
+ float current;
+}Transmuter_SetCurrentTargetManual_t;
+
+//! Create the Transmuter_SetCurrentTargetManual packet from parameters
+void encodeTransmuter_SetCurrentTargetManualPacket(void* pkt, float current);
+
+//! Decode the Transmuter_SetCurrentTargetManual packet to parameters
+int decodeTransmuter_SetCurrentTargetManualPacket(const void* pkt, float* current);
+
+//! return the packet ID for the Transmuter_SetCurrentTargetManual packet
+#define getTransmuter_SetCurrentTargetManualPacketID() (PKT_TRANSMUTER_SYSTEM_CMD)
+
+//! return the minimum encoded length for the Transmuter_SetCurrentTargetManual packet
+#define getTransmuter_SetCurrentTargetManualMinDataLength() (3)
+
+//! return the maximum encoded length for the Transmuter_SetCurrentTargetManual packet
+#define getTransmuter_SetCurrentTargetManualMaxDataLength() (3)
+
+//! Create the Transmuter_SetRpmTargetAuto packet from parameters
+void encodeTransmuter_SetRpmTargetAutoPacket(void* pkt);
+
+//! Decode the Transmuter_SetRpmTargetAuto packet to parameters
+int decodeTransmuter_SetRpmTargetAutoPacket(const void* pkt);
+
+//! return the packet ID for the Transmuter_SetRpmTargetAuto packet
+#define getTransmuter_SetRpmTargetAutoPacketID() (PKT_TRANSMUTER_SYSTEM_CMD)
+
+//! return the minimum encoded length for the Transmuter_SetRpmTargetAuto packet
+#define getTransmuter_SetRpmTargetAutoMinDataLength() (1)
+
+//! return the maximum encoded length for the Transmuter_SetRpmTargetAuto packet
+#define getTransmuter_SetRpmTargetAutoMaxDataLength() (1)
+
+/*!
+ * Set RPM target to auto mode
+ */
+typedef struct
+{
+ uint16_t rpm; //!< Manual RPM command
+}Transmuter_SetRpmTargetManual_t;
+
+//! Create the Transmuter_SetRpmTargetManual packet from parameters
+void encodeTransmuter_SetRpmTargetManualPacket(void* pkt, uint16_t rpm);
+
+//! Decode the Transmuter_SetRpmTargetManual packet to parameters
+int decodeTransmuter_SetRpmTargetManualPacket(const void* pkt, uint16_t* rpm);
+
+//! return the packet ID for the Transmuter_SetRpmTargetManual packet
+#define getTransmuter_SetRpmTargetManualPacketID() (PKT_TRANSMUTER_SYSTEM_CMD)
+
+//! return the minimum encoded length for the Transmuter_SetRpmTargetManual packet
+#define getTransmuter_SetRpmTargetManualMinDataLength() (3)
+
+//! return the maximum encoded length for the Transmuter_SetRpmTargetManual packet
+#define getTransmuter_SetRpmTargetManualMaxDataLength() (3)
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _TRANSMUTERCOMMANDS_H
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterDefines.c b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterDefines.c
new file mode 100644
index 0000000000..d64991ebaa
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterDefines.c
@@ -0,0 +1,465 @@
+// TransmuterDefines.c was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#include "TransmuterDefines.h"
+#include "fielddecode.h"
+#include "fieldencode.h"
+#include "scaleddecode.h"
+#include "scaledencode.h"
+
+/*!
+ * \brief Encode a Transmuter_StatusBits_t into a byte array
+ *
+ * Transmuter operational status information
+ * \param _pg_data points to the byte array to add encoded data to
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of encoded bytes.
+ * \param _pg_user is the data to encode in the byte array
+ */
+void encodeTransmuter_StatusBits_t(uint8_t* _pg_data, int* _pg_bytecount, const Transmuter_StatusBits_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // Transmuter operational mode
+ // Range of mode is 0 to 15.
+ _pg_data[_pg_byteindex] = (uint8_t)limitMax(_pg_user->mode, 15) << 4;
+
+ // Hardware enable is active
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->hwEnable == true) ? 1 : 0) << 3;
+
+ // Software enable is active
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->swEnable == true) ? 1 : 0) << 2;
+
+ // Critical error flag set (refer to error status packet)
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->anyErrors == true) ? 1 : 0) << 1;
+
+ // Warning flag set (refer to error status packet)
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->anyWarnings == true) ? 1 : 0);
+
+ // 0 = Auto current, 1 = Manual current
+ _pg_data[_pg_byteindex + 1] = (uint8_t)((_pg_user->manualCurrent == true) ? 1 : 0) << 7;
+
+ // 0 = Auto RPM, 1 = Manual RPM
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->manualSpeed == true) ? 1 : 0) << 6;
+
+ // Reserved for future use
+
+ // EFI system enabled status
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->efiEnabled == true) ? 1 : 0) << 1;
+
+ // Transmuter is ready to run
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->readyToRun == true) ? 1 : 0);
+ _pg_byteindex += 2; // close bit field
+
+ *_pg_bytecount = _pg_byteindex;
+
+}// encodeTransmuter_StatusBits_t
+
+/*!
+ * \brief Decode a Transmuter_StatusBits_t from a byte array
+ *
+ * Transmuter operational status information
+ * \param _pg_data points to the byte array to decoded data from
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of bytes decoded
+ * \param _pg_user is the data to decode from the byte array
+ * \return 1 if the data are decoded, else 0.
+ */
+int decodeTransmuter_StatusBits_t(const uint8_t* _pg_data, int* _pg_bytecount, Transmuter_StatusBits_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // Transmuter operational mode
+ // Range of mode is 0 to 15.
+ _pg_user->mode = (_pg_data[_pg_byteindex] >> 4);
+
+ // Hardware enable is active
+ _pg_user->hwEnable = (((_pg_data[_pg_byteindex] >> 3) & 0x1)) ? true : false;
+
+ // Software enable is active
+ _pg_user->swEnable = (((_pg_data[_pg_byteindex] >> 2) & 0x1)) ? true : false;
+
+ // Critical error flag set (refer to error status packet)
+ _pg_user->anyErrors = (((_pg_data[_pg_byteindex] >> 1) & 0x1)) ? true : false;
+
+ // Warning flag set (refer to error status packet)
+ _pg_user->anyWarnings = (((_pg_data[_pg_byteindex]) & 0x1)) ? true : false;
+
+ // 0 = Auto current, 1 = Manual current
+ _pg_user->manualCurrent = ((_pg_data[_pg_byteindex + 1] >> 7)) ? true : false;
+
+ // 0 = Auto RPM, 1 = Manual RPM
+ _pg_user->manualSpeed = (((_pg_data[_pg_byteindex + 1] >> 6) & 0x1)) ? true : false;
+
+ // Reserved for future use
+
+ // EFI system enabled status
+ _pg_user->efiEnabled = (((_pg_data[_pg_byteindex + 1] >> 1) & 0x1)) ? true : false;
+
+ // Transmuter is ready to run
+ _pg_user->readyToRun = (((_pg_data[_pg_byteindex + 1]) & 0x1)) ? true : false;
+ _pg_byteindex += 2; // close bit field
+
+ *_pg_bytecount = _pg_byteindex;
+
+ return 1;
+
+}// decodeTransmuter_StatusBits_t
+
+/*!
+ * \brief Encode a Transmuter_WarningBits_t into a byte array
+ *
+ * Transmuter operational status warning bits
+ * \param _pg_data points to the byte array to add encoded data to
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of encoded bytes.
+ * \param _pg_user is the data to encode in the byte array
+ */
+void encodeTransmuter_WarningBits_t(uint8_t* _pg_data, int* _pg_bytecount, const Transmuter_WarningBits_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // General motor control warning (refer to the motor warnings packet)
+ _pg_data[_pg_byteindex] = (uint8_t)((_pg_user->motor == true) ? 1 : 0) << 7;
+
+ // Battery voltage is outside configured range
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->batVoltage == true) ? 1 : 0) << 6;
+
+ // Battery current is outside configured range
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->batCurrent == true) ? 1 : 0) << 5;
+
+ // Generator current is outside configured range
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->genCurrent == true) ? 1 : 0) << 4;
+
+ // Generator motor temperature exceeds warning limit
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->genTemp == true) ? 1 : 0) << 3;
+
+ // ESC MOSFET temperature exceeds warning limit
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->escTemp == true) ? 1 : 0) << 2;
+
+ // Reserved for future use
+
+ // General ECU warning
+ _pg_data[_pg_byteindex + 1] = (uint8_t)((_pg_user->ecu == true) ? 1 : 0) << 7;
+
+ // General fuel pump warning
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->pump == true) ? 1 : 0) << 6;
+
+ // Mismatch between engine and generator RPM
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->rpmMismatch == true) ? 1 : 0) << 5;
+
+ // Engine is not generating expected power
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->powerLoss == true) ? 1 : 0) << 4;
+
+ // Engine is performing at maximum power limit
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->engineLimit == true) ? 1 : 0) << 3;
+
+ // Fuel pressure warning
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->fuelPressure == true) ? 1 : 0) << 2;
+
+ // Engine temperature exceeds warning threshold
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->chtTemp == true) ? 1 : 0) << 1;
+
+ // Reserved for future use
+ _pg_byteindex += 2; // close bit field
+
+ // Reserved for future use
+ uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
+
+ *_pg_bytecount = _pg_byteindex;
+
+}// encodeTransmuter_WarningBits_t
+
+/*!
+ * \brief Decode a Transmuter_WarningBits_t from a byte array
+ *
+ * Transmuter operational status warning bits
+ * \param _pg_data points to the byte array to decoded data from
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of bytes decoded
+ * \param _pg_user is the data to decode from the byte array
+ * \return 1 if the data are decoded, else 0.
+ */
+int decodeTransmuter_WarningBits_t(const uint8_t* _pg_data, int* _pg_bytecount, Transmuter_WarningBits_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // General motor control warning (refer to the motor warnings packet)
+ _pg_user->motor = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
+
+ // Battery voltage is outside configured range
+ _pg_user->batVoltage = (((_pg_data[_pg_byteindex] >> 6) & 0x1)) ? true : false;
+
+ // Battery current is outside configured range
+ _pg_user->batCurrent = (((_pg_data[_pg_byteindex] >> 5) & 0x1)) ? true : false;
+
+ // Generator current is outside configured range
+ _pg_user->genCurrent = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
+
+ // Generator motor temperature exceeds warning limit
+ _pg_user->genTemp = (((_pg_data[_pg_byteindex] >> 3) & 0x1)) ? true : false;
+
+ // ESC MOSFET temperature exceeds warning limit
+ _pg_user->escTemp = (((_pg_data[_pg_byteindex] >> 2) & 0x1)) ? true : false;
+
+ // Reserved for future use
+
+ // General ECU warning
+ _pg_user->ecu = ((_pg_data[_pg_byteindex + 1] >> 7)) ? true : false;
+
+ // General fuel pump warning
+ _pg_user->pump = (((_pg_data[_pg_byteindex + 1] >> 6) & 0x1)) ? true : false;
+
+ // Mismatch between engine and generator RPM
+ _pg_user->rpmMismatch = (((_pg_data[_pg_byteindex + 1] >> 5) & 0x1)) ? true : false;
+
+ // Engine is not generating expected power
+ _pg_user->powerLoss = (((_pg_data[_pg_byteindex + 1] >> 4) & 0x1)) ? true : false;
+
+ // Engine is performing at maximum power limit
+ _pg_user->engineLimit = (((_pg_data[_pg_byteindex + 1] >> 3) & 0x1)) ? true : false;
+
+ // Fuel pressure warning
+ _pg_user->fuelPressure = (((_pg_data[_pg_byteindex + 1] >> 2) & 0x1)) ? true : false;
+
+ // Engine temperature exceeds warning threshold
+ _pg_user->chtTemp = (((_pg_data[_pg_byteindex + 1] >> 1) & 0x1)) ? true : false;
+
+ // Reserved for future use
+ _pg_byteindex += 2; // close bit field
+
+ // Reserved for future use
+ _pg_byteindex += 1;
+
+ *_pg_bytecount = _pg_byteindex;
+
+ return 1;
+
+}// decodeTransmuter_WarningBits_t
+
+/*!
+ * \brief Encode a Transmuter_ErrorBits_t into a byte array
+ *
+ * Transmuter operational status error bits
+ * \param _pg_data points to the byte array to add encoded data to
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of encoded bytes.
+ * \param _pg_user is the data to encode in the byte array
+ */
+void encodeTransmuter_ErrorBits_t(uint8_t* _pg_data, int* _pg_bytecount, const Transmuter_ErrorBits_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // General motor control error (refer to the motor errors packet)
+ _pg_data[_pg_byteindex] = (uint8_t)((_pg_user->motor == true) ? 1 : 0) << 7;
+
+ // Reserved for future use
+
+ // System power map is improperly configured
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->powerMap == true) ? 1 : 0) << 5;
+
+ // Error during starting routine
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->starting == true) ? 1 : 0) << 4;
+
+ // Reserved for future use
+
+ // ECU connection lost
+ _pg_data[_pg_byteindex + 1] = (uint8_t)((_pg_user->ecuConnection == true) ? 1 : 0) << 7;
+
+ // Fuel pump connection lost
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->pumpConnection == true) ? 1 : 0) << 6;
+
+ // Engine stopped due to between engine and generator RPM
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->rpmMismatch == true) ? 1 : 0) << 5;
+
+ // Engine stopped due to not generating power
+ _pg_data[_pg_byteindex + 1] |= (uint8_t)((_pg_user->powerLoss == true) ? 1 : 0) << 4;
+
+ // Reserved for future use
+ _pg_byteindex += 2; // close bit field
+
+ // Reserved for future use
+ uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
+
+ *_pg_bytecount = _pg_byteindex;
+
+}// encodeTransmuter_ErrorBits_t
+
+/*!
+ * \brief Decode a Transmuter_ErrorBits_t from a byte array
+ *
+ * Transmuter operational status error bits
+ * \param _pg_data points to the byte array to decoded data from
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of bytes decoded
+ * \param _pg_user is the data to decode from the byte array
+ * \return 1 if the data are decoded, else 0.
+ */
+int decodeTransmuter_ErrorBits_t(const uint8_t* _pg_data, int* _pg_bytecount, Transmuter_ErrorBits_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // General motor control error (refer to the motor errors packet)
+ _pg_user->motor = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
+
+ // Reserved for future use
+
+ // System power map is improperly configured
+ _pg_user->powerMap = (((_pg_data[_pg_byteindex] >> 5) & 0x1)) ? true : false;
+
+ // Error during starting routine
+ _pg_user->starting = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
+
+ // Reserved for future use
+
+ // ECU connection lost
+ _pg_user->ecuConnection = ((_pg_data[_pg_byteindex + 1] >> 7)) ? true : false;
+
+ // Fuel pump connection lost
+ _pg_user->pumpConnection = (((_pg_data[_pg_byteindex + 1] >> 6) & 0x1)) ? true : false;
+
+ // Engine stopped due to between engine and generator RPM
+ _pg_user->rpmMismatch = (((_pg_data[_pg_byteindex + 1] >> 5) & 0x1)) ? true : false;
+
+ // Engine stopped due to not generating power
+ _pg_user->powerLoss = (((_pg_data[_pg_byteindex + 1] >> 4) & 0x1)) ? true : false;
+
+ // Reserved for future use
+ _pg_byteindex += 2; // close bit field
+
+ // Reserved for future use
+ _pg_byteindex += 1;
+
+ *_pg_bytecount = _pg_byteindex;
+
+ return 1;
+
+}// decodeTransmuter_ErrorBits_t
+
+/*!
+ * \brief Set a Transmuter_TelemetryPackets_t to initial values.
+ *
+ * Set a Transmuter_TelemetryPackets_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_TelemetryPackets_t(Transmuter_TelemetryPackets_t* _pg_user)
+{
+
+ // Enable TelemetryStatus packet
+ _pg_user->status = 1;
+
+ // Enable TelemetryPower packet
+ _pg_user->power = 1;
+
+ // Enable TelemetrySetpoint packet
+ _pg_user->setpoint = 1;
+
+ // Enable TelemetryGenerator packet
+ _pg_user->generator = 1;
+
+ // Enable TelemetryCapacity packet
+ _pg_user->capacity = 1;
+
+ // Enable ControlLoop packet
+ _pg_user->ctrlLoop = 0;
+
+ // Enable TelemetryAPB packet
+ _pg_user->apb = 0;
+
+}// initTransmuter_TelemetryPackets_t
+
+/*!
+ * \brief Encode a Transmuter_TelemetryPackets_t into a byte array
+ *
+
+ * \param _pg_data points to the byte array to add encoded data to
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of encoded bytes.
+ * \param _pg_user is the data to encode in the byte array
+ */
+void encodeTransmuter_TelemetryPackets_t(uint8_t* _pg_data, int* _pg_bytecount, const Transmuter_TelemetryPackets_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // Enable TelemetryStatus packet
+ _pg_data[_pg_byteindex] = (uint8_t)((_pg_user->status == true) ? 1 : 0) << 7;
+
+ // Enable TelemetryPower packet
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->power == true) ? 1 : 0) << 6;
+
+ // Enable TelemetrySetpoint packet
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->setpoint == true) ? 1 : 0) << 5;
+
+ // Enable TelemetryGenerator packet
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->generator == true) ? 1 : 0) << 4;
+
+ // Enable TelemetryCapacity packet
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->capacity == true) ? 1 : 0) << 3;
+
+ // Enable ControlLoop packet
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->ctrlLoop == true) ? 1 : 0) << 2;
+
+ // Enable TelemetryAPB packet
+ _pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->apb == true) ? 1 : 0) << 1;
+
+ // Reserved for future use
+ _pg_byteindex += 1; // close bit field
+
+ *_pg_bytecount = _pg_byteindex;
+
+}// encodeTransmuter_TelemetryPackets_t
+
+/*!
+ * \brief Decode a Transmuter_TelemetryPackets_t from a byte array
+ *
+
+ * \param _pg_data points to the byte array to decoded data from
+ * \param _pg_bytecount points to the starting location in the byte array, and will be incremented by the number of bytes decoded
+ * \param _pg_user is the data to decode from the byte array
+ * \return 1 if the data are decoded, else 0.
+ */
+int decodeTransmuter_TelemetryPackets_t(const uint8_t* _pg_data, int* _pg_bytecount, Transmuter_TelemetryPackets_t* _pg_user)
+{
+ int _pg_byteindex = *_pg_bytecount;
+
+ // Enable TelemetryStatus packet
+ _pg_user->status = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
+
+ // Enable TelemetryPower packet
+ _pg_user->power = (((_pg_data[_pg_byteindex] >> 6) & 0x1)) ? true : false;
+
+ // Enable TelemetrySetpoint packet
+ _pg_user->setpoint = (((_pg_data[_pg_byteindex] >> 5) & 0x1)) ? true : false;
+
+ // Enable TelemetryGenerator packet
+ _pg_user->generator = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
+
+ // Enable TelemetryCapacity packet
+ _pg_user->capacity = (((_pg_data[_pg_byteindex] >> 3) & 0x1)) ? true : false;
+
+ // Enable ControlLoop packet
+ _pg_user->ctrlLoop = (((_pg_data[_pg_byteindex] >> 2) & 0x1)) ? true : false;
+
+ // Enable TelemetryAPB packet
+ _pg_user->apb = (((_pg_data[_pg_byteindex] >> 1) & 0x1)) ? true : false;
+
+ // Reserved for future use
+ _pg_byteindex += 1; // close bit field
+
+ *_pg_bytecount = _pg_byteindex;
+
+ return 1;
+
+}// decodeTransmuter_TelemetryPackets_t
+
+// end of TransmuterDefines.c
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterDefines.h b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterDefines.h
new file mode 100644
index 0000000000..f1b96a55ab
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterDefines.h
@@ -0,0 +1,160 @@
+// TransmuterDefines.h was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#ifndef _TRANSMUTERDEFINES_H
+#define _TRANSMUTERDEFINES_H
+
+// Language target is C, C++ compilers: don't mangle us
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ */
+
+#include
+#include
+#include "TransmuterProtocol.h"
+
+/*!
+ * Transmuter operational status information
+ */
+typedef struct
+{
+ uint8_t mode; //!< Transmuter operational mode
+ bool hwEnable; //!< Hardware enable is active
+ bool swEnable; //!< Software enable is active
+ bool anyErrors; //!< Critical error flag set (refer to error status packet)
+ bool anyWarnings; //!< Warning flag set (refer to error status packet)
+ bool manualCurrent; //!< 0 = Auto current, 1 = Manual current
+ bool manualSpeed; //!< 0 = Auto RPM, 1 = Manual RPM
+ bool efiEnabled; //!< EFI system enabled status
+ bool readyToRun; //!< Transmuter is ready to run
+}Transmuter_StatusBits_t;
+
+//! return the minimum encoded length for the Transmuter_StatusBits_t structure
+#define getMinLengthOfTransmuter_StatusBits_t() (2)
+
+//! return the maximum encoded length for the Transmuter_StatusBits_t structure
+#define getMaxLengthOfTransmuter_StatusBits_t() (2)
+
+//! Encode a Transmuter_StatusBits_t into a byte array
+void encodeTransmuter_StatusBits_t(uint8_t* data, int* bytecount, const Transmuter_StatusBits_t* user);
+
+//! Decode a Transmuter_StatusBits_t from a byte array
+int decodeTransmuter_StatusBits_t(const uint8_t* data, int* bytecount, Transmuter_StatusBits_t* user);
+
+/*!
+ * Transmuter operational status warning bits
+ */
+typedef struct
+{
+ bool motor; //!< General motor control warning (refer to the motor warnings packet)
+ bool batVoltage; //!< Battery voltage is outside configured range
+ bool batCurrent; //!< Battery current is outside configured range
+ bool genCurrent; //!< Generator current is outside configured range
+ bool genTemp; //!< Generator motor temperature exceeds warning limit
+ bool escTemp; //!< ESC MOSFET temperature exceeds warning limit
+ bool ecu; //!< General ECU warning
+ bool pump; //!< General fuel pump warning
+ bool rpmMismatch; //!< Mismatch between engine and generator RPM
+ bool powerLoss; //!< Engine is not generating expected power
+ bool engineLimit; //!< Engine is performing at maximum power limit
+ bool fuelPressure; //!< Fuel pressure warning
+ bool chtTemp; //!< Engine temperature exceeds warning threshold
+}Transmuter_WarningBits_t;
+
+//! return the minimum encoded length for the Transmuter_WarningBits_t structure
+#define getMinLengthOfTransmuter_WarningBits_t() (3)
+
+//! return the maximum encoded length for the Transmuter_WarningBits_t structure
+#define getMaxLengthOfTransmuter_WarningBits_t() (3)
+
+//! Encode a Transmuter_WarningBits_t into a byte array
+void encodeTransmuter_WarningBits_t(uint8_t* data, int* bytecount, const Transmuter_WarningBits_t* user);
+
+//! Decode a Transmuter_WarningBits_t from a byte array
+int decodeTransmuter_WarningBits_t(const uint8_t* data, int* bytecount, Transmuter_WarningBits_t* user);
+
+/*!
+ * Transmuter operational status error bits
+ */
+typedef struct
+{
+ bool motor; //!< General motor control error (refer to the motor errors packet)
+ bool powerMap; //!< System power map is improperly configured
+ bool starting; //!< Error during starting routine
+ bool ecuConnection; //!< ECU connection lost
+ bool pumpConnection; //!< Fuel pump connection lost
+ bool rpmMismatch; //!< Engine stopped due to between engine and generator RPM
+ bool powerLoss; //!< Engine stopped due to not generating power
+}Transmuter_ErrorBits_t;
+
+//! return the minimum encoded length for the Transmuter_ErrorBits_t structure
+#define getMinLengthOfTransmuter_ErrorBits_t() (3)
+
+//! return the maximum encoded length for the Transmuter_ErrorBits_t structure
+#define getMaxLengthOfTransmuter_ErrorBits_t() (3)
+
+//! Encode a Transmuter_ErrorBits_t into a byte array
+void encodeTransmuter_ErrorBits_t(uint8_t* data, int* bytecount, const Transmuter_ErrorBits_t* user);
+
+//! Decode a Transmuter_ErrorBits_t from a byte array
+int decodeTransmuter_ErrorBits_t(const uint8_t* data, int* bytecount, Transmuter_ErrorBits_t* user);
+
+// Initial and verify values for TelemetryPackets
+#define Transmuter_TelemetryPackets_status_InitValue 1
+#define Transmuter_TelemetryPackets_power_InitValue 1
+#define Transmuter_TelemetryPackets_setpoint_InitValue 1
+#define Transmuter_TelemetryPackets_generator_InitValue 1
+#define Transmuter_TelemetryPackets_capacity_InitValue 1
+#define Transmuter_TelemetryPackets_ctrlLoop_InitValue 0
+#define Transmuter_TelemetryPackets_apb_InitValue 0
+
+typedef struct
+{
+ bool status; //!< Enable TelemetryStatus packet
+ bool power; //!< Enable TelemetryPower packet
+ bool setpoint; //!< Enable TelemetrySetpoint packet
+ bool generator; //!< Enable TelemetryGenerator packet
+ bool capacity; //!< Enable TelemetryCapacity packet
+ bool ctrlLoop; //!< Enable ControlLoop packet
+ bool apb; //!< Enable TelemetryAPB packet
+}Transmuter_TelemetryPackets_t;
+
+//! return the minimum encoded length for the Transmuter_TelemetryPackets_t structure
+#define getMinLengthOfTransmuter_TelemetryPackets_t() (1)
+
+//! return the maximum encoded length for the Transmuter_TelemetryPackets_t structure
+#define getMaxLengthOfTransmuter_TelemetryPackets_t() (1)
+
+//! Set a Transmuter_TelemetryPackets_t to initial values
+void initTransmuter_TelemetryPackets_t(Transmuter_TelemetryPackets_t* user);
+
+//! Encode a Transmuter_TelemetryPackets_t into a byte array
+void encodeTransmuter_TelemetryPackets_t(uint8_t* data, int* bytecount, const Transmuter_TelemetryPackets_t* user);
+
+//! Decode a Transmuter_TelemetryPackets_t from a byte array
+int decodeTransmuter_TelemetryPackets_t(const uint8_t* data, int* bytecount, Transmuter_TelemetryPackets_t* user);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _TRANSMUTERDEFINES_H
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterPackets.c b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterPackets.c
new file mode 100644
index 0000000000..a9f9994d47
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterPackets.c
@@ -0,0 +1,2988 @@
+// TransmuterPackets.c was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#include "TransmuterPackets.h"
+#include "fielddecode.h"
+#include "fieldencode.h"
+#include "scaleddecode.h"
+#include "scaledencode.h"
+#include "TransmuterDefines.h"
+
+/*!
+ * \brief Create the Transmuter_EnterStandby packet
+ *
+ * Put the Transmuter in *STANDBY* mode. If the Transmuter is running it will
+ * be disabled.
+ * \param _pg_pkt points to the packet which will be created by this function
+ */
+void encodeTransmuter_EnterStandbyPacket(void* _pg_pkt)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Constant value required for standby sequence
+ uint8ToBytes((uint8_t)(0xA0), _pg_data, &_pg_byteindex);
+
+ // Constant value required for standby sequence
+ uint8ToBytes((uint8_t)(0xB0), _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_EnterStandbyPacketID());
+
+}// encodeTransmuter_EnterStandbyPacket
+
+/*!
+ * \brief Decode the Transmuter_EnterStandby packet
+ *
+ * Put the Transmuter in *STANDBY* mode. If the Transmuter is running it will
+ * be disabled.
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_EnterStandbyPacket(const void* _pg_pkt)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_EnterStandbyPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_EnterStandbyMinDataLength())
+ return 0;
+
+ // Constant value required for standby sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0xA0)
+ return 0;
+
+ // Constant value required for standby sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0xB0)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_EnterStandbyPacket
+
+/*!
+ * \brief Create the Transmuter_EnterPreflight packet
+ *
+ * Put the Transmuter in *PREFLIGHT* mode
+ * \param _pg_pkt points to the packet which will be created by this function
+ */
+void encodeTransmuter_EnterPreflightPacket(void* _pg_pkt)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Constant value required for standby sequence
+ uint8ToBytes((uint8_t)(0xC0), _pg_data, &_pg_byteindex);
+
+ // Constant value required for standby sequence
+ uint8ToBytes((uint8_t)(0xD0), _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_EnterPreflightPacketID());
+
+}// encodeTransmuter_EnterPreflightPacket
+
+/*!
+ * \brief Decode the Transmuter_EnterPreflight packet
+ *
+ * Put the Transmuter in *PREFLIGHT* mode
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_EnterPreflightPacket(const void* _pg_pkt)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_EnterPreflightPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_EnterPreflightMinDataLength())
+ return 0;
+
+ // Constant value required for standby sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0xC0)
+ return 0;
+
+ // Constant value required for standby sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0xD0)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_EnterPreflightPacket
+
+/*!
+ * \brief Create the Transmuter_EnterWarmup packet
+ *
+ * Put the Transmuter in *WARMUP* mode. If the engine is not spinning, the
+ * Transmuter will enter the engine starting routine.
+ * \param _pg_pkt points to the packet which will be created by this function
+ */
+void encodeTransmuter_EnterWarmupPacket(void* _pg_pkt)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Constant value required for warmup sequence
+ uint8ToBytes((uint8_t)(0xC5), _pg_data, &_pg_byteindex);
+
+ // Constant value required for warmup sequence
+ uint8ToBytes((uint8_t)(0x5C), _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_EnterWarmupPacketID());
+
+}// encodeTransmuter_EnterWarmupPacket
+
+/*!
+ * \brief Decode the Transmuter_EnterWarmup packet
+ *
+ * Put the Transmuter in *WARMUP* mode. If the engine is not spinning, the
+ * Transmuter will enter the engine starting routine.
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_EnterWarmupPacket(const void* _pg_pkt)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_EnterWarmupPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_EnterWarmupMinDataLength())
+ return 0;
+
+ // Constant value required for warmup sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0xC5)
+ return 0;
+
+ // Constant value required for warmup sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0x5C)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_EnterWarmupPacket
+
+/*!
+ * \brief Create the Transmuter_EnterRunMode packet
+ *
+ * Put the Transmuter in *RUN* mode. If the engine is not spinning, the
+ * Transmuter will enter the engine starting routine.
+ * \param _pg_pkt points to the packet which will be created by this function
+ */
+void encodeTransmuter_EnterRunModePacket(void* _pg_pkt)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Constant value requried for run sequence
+ uint8ToBytes((uint8_t)(0x5A), _pg_data, &_pg_byteindex);
+
+ // Constant value requried for run sequence
+ uint8ToBytes((uint8_t)(0xA5), _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_EnterRunModePacketID());
+
+}// encodeTransmuter_EnterRunModePacket
+
+/*!
+ * \brief Decode the Transmuter_EnterRunMode packet
+ *
+ * Put the Transmuter in *RUN* mode. If the engine is not spinning, the
+ * Transmuter will enter the engine starting routine.
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_EnterRunModePacket(const void* _pg_pkt)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_EnterRunModePacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_EnterRunModeMinDataLength())
+ return 0;
+
+ // Constant value requried for run sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0x5A)
+ return 0;
+
+ // Constant value requried for run sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0xA5)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_EnterRunModePacket
+
+/*!
+ * \brief Create the Transmuter_EnterPWMMode packet
+ *
+ * Put the Transmtuer in *PWM* mode. The Transmuter will act as a regular ESC
+ * and perform ESC PWM commands
+ * \param _pg_pkt points to the packet which will be created by this function
+ */
+void encodeTransmuter_EnterPWMModePacket(void* _pg_pkt)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Constant value requried for run sequence
+ uint8ToBytes((uint8_t)(0x6B), _pg_data, &_pg_byteindex);
+
+ // Constant value requried for run sequence
+ uint8ToBytes((uint8_t)(0xB6), _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_EnterPWMModePacketID());
+
+}// encodeTransmuter_EnterPWMModePacket
+
+/*!
+ * \brief Decode the Transmuter_EnterPWMMode packet
+ *
+ * Put the Transmtuer in *PWM* mode. The Transmuter will act as a regular ESC
+ * and perform ESC PWM commands
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_EnterPWMModePacket(const void* _pg_pkt)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_EnterPWMModePacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_EnterPWMModeMinDataLength())
+ return 0;
+
+ // Constant value requried for run sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0x6B)
+ return 0;
+
+ // Constant value requried for run sequence
+ if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) 0xB6)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_EnterPWMModePacket
+
+/*!
+ * \brief Create the Transmuter_TelemetryStatus packet
+ *
+ * The TelemetryStatus packet contains critical operational status information
+ * pertaining to the current state of the Transmuter
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetryStatusPacketStructure(void* _pg_pkt, const Transmuter_TelemetryStatus_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ encodeTransmuter_StatusBits_t(_pg_data, &_pg_byteindex, &_pg_user->status);
+
+ encodeTransmuter_WarningBits_t(_pg_data, &_pg_byteindex, &_pg_user->warning);
+
+ encodeTransmuter_ErrorBits_t(_pg_data, &_pg_byteindex, &_pg_user->errors);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryStatusPacketID());
+
+}// encodeTransmuter_TelemetryStatusPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetryStatus packet
+ *
+ * The TelemetryStatus packet contains critical operational status information
+ * pertaining to the current state of the Transmuter
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryStatusPacketStructure(const void* _pg_pkt, Transmuter_TelemetryStatus_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryStatusPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetryStatusMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ if(decodeTransmuter_StatusBits_t(_pg_data, &_pg_byteindex, &_pg_user->status) == 0)
+ return 0;
+
+ if(decodeTransmuter_WarningBits_t(_pg_data, &_pg_byteindex, &_pg_user->warning) == 0)
+ return 0;
+
+ if(decodeTransmuter_ErrorBits_t(_pg_data, &_pg_byteindex, &_pg_user->errors) == 0)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_TelemetryStatusPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetryStatus packet
+ *
+ * The TelemetryStatus packet contains critical operational status information
+ * pertaining to the current state of the Transmuter
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param status is
+ * \param warning is
+ * \param errors is
+ */
+void encodeTransmuter_TelemetryStatusPacket(void* _pg_pkt, const Transmuter_StatusBits_t* status, const Transmuter_WarningBits_t* warning, const Transmuter_ErrorBits_t* errors)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ encodeTransmuter_StatusBits_t(_pg_data, &_pg_byteindex, status);
+
+ encodeTransmuter_WarningBits_t(_pg_data, &_pg_byteindex, warning);
+
+ encodeTransmuter_ErrorBits_t(_pg_data, &_pg_byteindex, errors);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryStatusPacketID());
+
+}// encodeTransmuter_TelemetryStatusPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetryStatus packet
+ *
+ * The TelemetryStatus packet contains critical operational status information
+ * pertaining to the current state of the Transmuter
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param status receives
+ * \param warning receives
+ * \param errors receives
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryStatusPacket(const void* _pg_pkt, Transmuter_StatusBits_t* status, Transmuter_WarningBits_t* warning, Transmuter_ErrorBits_t* errors)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryStatusPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetryStatusMinDataLength())
+ return 0;
+
+ if(decodeTransmuter_StatusBits_t(_pg_data, &_pg_byteindex, status) == 0)
+ return 0;
+
+ if(decodeTransmuter_WarningBits_t(_pg_data, &_pg_byteindex, warning) == 0)
+ return 0;
+
+ if(decodeTransmuter_ErrorBits_t(_pg_data, &_pg_byteindex, errors) == 0)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_TelemetryStatusPacket
+
+/*!
+ * \brief Create the Transmuter_TelemetryPower packet
+ *
+ * The TelemetryPower packet contains information on the current operation
+ * point of the engine and generator
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetryPowerPacketStructure(void* _pg_pkt, const Transmuter_TelemetryPower_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // System voltage
+ // Range of voltage is 0.0f to 128.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->voltage, _pg_data, &_pg_byteindex, 0.0f, 511.992188f);
+
+ // Generator current
+ // Range of genCurrent is -500.0f to 500.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->genCurrent, _pg_data, &_pg_byteindex, 65.534f);
+
+ // Battery current
+ // Range of batCurrent is -500.0f to 500.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->batCurrent, _pg_data, &_pg_byteindex, 65.534f);
+
+ // Mechanical rotational speed
+ // Range of rpm is -32768 to 32767.
+ int16ToBeBytes(_pg_user->rpm, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryPowerPacketID());
+
+}// encodeTransmuter_TelemetryPowerPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetryPower packet
+ *
+ * The TelemetryPower packet contains information on the current operation
+ * point of the engine and generator
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryPowerPacketStructure(const void* _pg_pkt, Transmuter_TelemetryPower_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryPowerPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetryPowerMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // System voltage
+ // Range of voltage is 0.0f to 128.0f.
+ _pg_user->voltage = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/511.992188f);
+
+ // Generator current
+ // Range of genCurrent is -500.0f to 500.0f.
+ _pg_user->genCurrent = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
+
+ // Battery current
+ // Range of batCurrent is -500.0f to 500.0f.
+ _pg_user->batCurrent = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
+
+ // Mechanical rotational speed
+ // Range of rpm is -32768 to 32767.
+ _pg_user->rpm = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryPowerPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetryPower packet
+ *
+ * The TelemetryPower packet contains information on the current operation
+ * point of the engine and generator
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param voltage is System voltage
+ * \param genCurrent is Generator current
+ * \param batCurrent is Battery current
+ * \param rpm is Mechanical rotational speed
+ */
+void encodeTransmuter_TelemetryPowerPacket(void* _pg_pkt, float voltage, float genCurrent, float batCurrent, int16_t rpm)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // System voltage
+ // Range of voltage is 0.0f to 128.0f.
+ float32ScaledTo2UnsignedBeBytes(voltage, _pg_data, &_pg_byteindex, 0.0f, 511.992188f);
+
+ // Generator current
+ // Range of genCurrent is -500.0f to 500.0f.
+ float32ScaledTo2SignedBeBytes(genCurrent, _pg_data, &_pg_byteindex, 65.534f);
+
+ // Battery current
+ // Range of batCurrent is -500.0f to 500.0f.
+ float32ScaledTo2SignedBeBytes(batCurrent, _pg_data, &_pg_byteindex, 65.534f);
+
+ // Mechanical rotational speed
+ // Range of rpm is -32768 to 32767.
+ int16ToBeBytes(rpm, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryPowerPacketID());
+
+}// encodeTransmuter_TelemetryPowerPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetryPower packet
+ *
+ * The TelemetryPower packet contains information on the current operation
+ * point of the engine and generator
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param voltage receives System voltage
+ * \param genCurrent receives Generator current
+ * \param batCurrent receives Battery current
+ * \param rpm receives Mechanical rotational speed
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryPowerPacket(const void* _pg_pkt, float* voltage, float* genCurrent, float* batCurrent, int16_t* rpm)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryPowerPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetryPowerMinDataLength())
+ return 0;
+
+ // System voltage
+ // Range of voltage is 0.0f to 128.0f.
+ (*voltage) = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/511.992188f);
+
+ // Generator current
+ // Range of genCurrent is -500.0f to 500.0f.
+ (*genCurrent) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
+
+ // Battery current
+ // Range of batCurrent is -500.0f to 500.0f.
+ (*batCurrent) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
+
+ // Mechanical rotational speed
+ // Range of rpm is -32768 to 32767.
+ (*rpm) = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryPowerPacket
+
+/*!
+ * \brief Create the Transmuter_TelemetrySetpoint packet
+ *
+ * The TelemetrySetpoint packet contains system setpoint/target information
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetrySetpointPacketStructure(void* _pg_pkt, const Transmuter_TelemetrySetpoint_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Battery current setpoint value
+ // Range of currentSetpoint is -255.0f to 255.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->currentSetpoint, _pg_data, &_pg_byteindex, 128.498039f);
+
+ // System RPM target
+ // Range of rpmTarget is -32768 to 32767.
+ int16ToBeBytes(_pg_user->rpmTarget, _pg_data, &_pg_byteindex);
+
+ // ECU throttle target
+ // Range of throttleTarget is 0 to 255.
+ uint8ToBytes(_pg_user->throttleTarget, _pg_data, &_pg_byteindex);
+
+ // Generator power target
+ // Range of powerTarget is -32768 to 32767.
+ int16ToBeBytes(_pg_user->powerTarget, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetrySetpointPacketID());
+
+}// encodeTransmuter_TelemetrySetpointPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetrySetpoint packet
+ *
+ * The TelemetrySetpoint packet contains system setpoint/target information
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetrySetpointPacketStructure(const void* _pg_pkt, Transmuter_TelemetrySetpoint_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetrySetpointPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetrySetpointMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Battery current setpoint value
+ // Range of currentSetpoint is -255.0f to 255.0f.
+ _pg_user->currentSetpoint = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/128.498039f);
+
+ // System RPM target
+ // Range of rpmTarget is -32768 to 32767.
+ _pg_user->rpmTarget = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // ECU throttle target
+ // Range of throttleTarget is 0 to 255.
+ _pg_user->throttleTarget = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Generator power target
+ // Range of powerTarget is -32768 to 32767.
+ _pg_user->powerTarget = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_TelemetrySetpointPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetrySetpoint packet
+ *
+ * The TelemetrySetpoint packet contains system setpoint/target information
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param currentSetpoint is Battery current setpoint value
+ * \param rpmTarget is System RPM target
+ * \param throttleTarget is ECU throttle target
+ * \param powerTarget is Generator power target
+ */
+void encodeTransmuter_TelemetrySetpointPacket(void* _pg_pkt, float currentSetpoint, int16_t rpmTarget, uint8_t throttleTarget, int16_t powerTarget)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Battery current setpoint value
+ // Range of currentSetpoint is -255.0f to 255.0f.
+ float32ScaledTo2SignedBeBytes(currentSetpoint, _pg_data, &_pg_byteindex, 128.498039f);
+
+ // System RPM target
+ // Range of rpmTarget is -32768 to 32767.
+ int16ToBeBytes(rpmTarget, _pg_data, &_pg_byteindex);
+
+ // ECU throttle target
+ // Range of throttleTarget is 0 to 255.
+ uint8ToBytes(throttleTarget, _pg_data, &_pg_byteindex);
+
+ // Generator power target
+ // Range of powerTarget is -32768 to 32767.
+ int16ToBeBytes(powerTarget, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetrySetpointPacketID());
+
+}// encodeTransmuter_TelemetrySetpointPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetrySetpoint packet
+ *
+ * The TelemetrySetpoint packet contains system setpoint/target information
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param currentSetpoint receives Battery current setpoint value
+ * \param rpmTarget receives System RPM target
+ * \param throttleTarget receives ECU throttle target
+ * \param powerTarget receives Generator power target
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetrySetpointPacket(const void* _pg_pkt, float* currentSetpoint, int16_t* rpmTarget, uint8_t* throttleTarget, int16_t* powerTarget)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetrySetpointPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetrySetpointMinDataLength())
+ return 0;
+
+ // Battery current setpoint value
+ // Range of currentSetpoint is -255.0f to 255.0f.
+ (*currentSetpoint) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/128.498039f);
+
+ // System RPM target
+ // Range of rpmTarget is -32768 to 32767.
+ (*rpmTarget) = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // ECU throttle target
+ // Range of throttleTarget is 0 to 255.
+ (*throttleTarget) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Generator power target
+ // Range of powerTarget is -32768 to 32767.
+ (*powerTarget) = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_TelemetrySetpointPacket
+
+/*!
+ * \brief Create the Transmuter_TelemetryGenerator packet
+ *
+ * The TelemetryGenerator packet provides information about the current
+ * operational status of the generator and EFI system.
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetryGeneratorPacketStructure(void* _pg_pkt, const Transmuter_TelemetryGenerator_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Power electronics module temperature
+ // Range of fetTemperature is 0 to 255.
+ uint8ToBytes(_pg_user->fetTemperature, _pg_data, &_pg_byteindex);
+
+ // Generator motor temperature
+ // Range of motTemperature is 0 to 255.
+ uint8ToBytes(_pg_user->motTemperature, _pg_data, &_pg_byteindex);
+
+ // Engine cylinder head temperature
+ // Range of chtTemperature is 0 to 255.
+ uint8ToBytes(_pg_user->chtTemperature, _pg_data, &_pg_byteindex);
+
+ // Fuel pressure
+ // Range of fuelPressure is 0.0f to 655.35f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->fuelPressure, _pg_data, &_pg_byteindex, 0.0f, 100.0f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryGeneratorPacketID());
+
+}// encodeTransmuter_TelemetryGeneratorPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetryGenerator packet
+ *
+ * The TelemetryGenerator packet provides information about the current
+ * operational status of the generator and EFI system.
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryGeneratorPacketStructure(const void* _pg_pkt, Transmuter_TelemetryGenerator_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryGeneratorPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetryGeneratorMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Power electronics module temperature
+ // Range of fetTemperature is 0 to 255.
+ _pg_user->fetTemperature = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Generator motor temperature
+ // Range of motTemperature is 0 to 255.
+ _pg_user->motTemperature = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Engine cylinder head temperature
+ // Range of chtTemperature is 0 to 255.
+ _pg_user->chtTemperature = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Fuel pressure
+ // Range of fuelPressure is 0.0f to 655.35f.
+ _pg_user->fuelPressure = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/100.0f);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryGeneratorPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetryGenerator packet
+ *
+ * The TelemetryGenerator packet provides information about the current
+ * operational status of the generator and EFI system.
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param fetTemperature is Power electronics module temperature
+ * \param motTemperature is Generator motor temperature
+ * \param chtTemperature is Engine cylinder head temperature
+ * \param fuelPressure is Fuel pressure
+ */
+void encodeTransmuter_TelemetryGeneratorPacket(void* _pg_pkt, uint8_t fetTemperature, uint8_t motTemperature, uint8_t chtTemperature, float fuelPressure)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Power electronics module temperature
+ // Range of fetTemperature is 0 to 255.
+ uint8ToBytes(fetTemperature, _pg_data, &_pg_byteindex);
+
+ // Generator motor temperature
+ // Range of motTemperature is 0 to 255.
+ uint8ToBytes(motTemperature, _pg_data, &_pg_byteindex);
+
+ // Engine cylinder head temperature
+ // Range of chtTemperature is 0 to 255.
+ uint8ToBytes(chtTemperature, _pg_data, &_pg_byteindex);
+
+ // Fuel pressure
+ // Range of fuelPressure is 0.0f to 655.35f.
+ float32ScaledTo2UnsignedBeBytes(fuelPressure, _pg_data, &_pg_byteindex, 0.0f, 100.0f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryGeneratorPacketID());
+
+}// encodeTransmuter_TelemetryGeneratorPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetryGenerator packet
+ *
+ * The TelemetryGenerator packet provides information about the current
+ * operational status of the generator and EFI system.
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param fetTemperature receives Power electronics module temperature
+ * \param motTemperature receives Generator motor temperature
+ * \param chtTemperature receives Engine cylinder head temperature
+ * \param fuelPressure receives Fuel pressure
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryGeneratorPacket(const void* _pg_pkt, uint8_t* fetTemperature, uint8_t* motTemperature, uint8_t* chtTemperature, float* fuelPressure)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryGeneratorPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetryGeneratorMinDataLength())
+ return 0;
+
+ // Power electronics module temperature
+ // Range of fetTemperature is 0 to 255.
+ (*fetTemperature) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Generator motor temperature
+ // Range of motTemperature is 0 to 255.
+ (*motTemperature) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Engine cylinder head temperature
+ // Range of chtTemperature is 0 to 255.
+ (*chtTemperature) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Fuel pressure
+ // Range of fuelPressure is 0.0f to 655.35f.
+ (*fuelPressure) = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/100.0f);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryGeneratorPacket
+
+/*!
+ * \brief Create the Transmuter_TelemetryCapacity packet
+ *
+ * The TelemetryCapacity packet provides information on the battery and fuel
+ * capacity
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetryCapacityPacketStructure(void* _pg_pkt, const Transmuter_TelemetryCapacity_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Fuel used estimate
+ // Range of fuelUsed is 0 to 4294967295.
+ uint32ToBeBytes(_pg_user->fuelUsed, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryCapacityPacketID());
+
+}// encodeTransmuter_TelemetryCapacityPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetryCapacity packet
+ *
+ * The TelemetryCapacity packet provides information on the battery and fuel
+ * capacity
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryCapacityPacketStructure(const void* _pg_pkt, Transmuter_TelemetryCapacity_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryCapacityPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetryCapacityMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Fuel used estimate
+ // Range of fuelUsed is 0 to 4294967295.
+ _pg_user->fuelUsed = uint32FromBeBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryCapacityPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetryCapacity packet
+ *
+ * The TelemetryCapacity packet provides information on the battery and fuel
+ * capacity
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param fuelUsed is Fuel used estimate
+ */
+void encodeTransmuter_TelemetryCapacityPacket(void* _pg_pkt, uint32_t fuelUsed)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Fuel used estimate
+ // Range of fuelUsed is 0 to 4294967295.
+ uint32ToBeBytes(fuelUsed, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryCapacityPacketID());
+
+}// encodeTransmuter_TelemetryCapacityPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetryCapacity packet
+ *
+ * The TelemetryCapacity packet provides information on the battery and fuel
+ * capacity
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param fuelUsed receives Fuel used estimate
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryCapacityPacket(const void* _pg_pkt, uint32_t* fuelUsed)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryCapacityPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetryCapacityMinDataLength())
+ return 0;
+
+ // Fuel used estimate
+ // Range of fuelUsed is 0 to 4294967295.
+ (*fuelUsed) = uint32FromBeBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryCapacityPacket
+
+/*!
+ * \brief Create the Transmuter_TelemetryControlLoop packet
+ *
+ * Current state of the transmuter current control loop
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetryControlLoopPacketStructure(void* _pg_pkt, const Transmuter_TelemetryControlLoop_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Range of pTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->pTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Range of iTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->iTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Range of dTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->dTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Range of fTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->fTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryControlLoopPacketID());
+
+}// encodeTransmuter_TelemetryControlLoopPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetryControlLoop packet
+ *
+ * Current state of the transmuter current control loop
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryControlLoopPacketStructure(const void* _pg_pkt, Transmuter_TelemetryControlLoop_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryControlLoopPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetryControlLoopMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Range of pTerm is -100.0f to 100.0f.
+ _pg_user->pTerm = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ // Range of iTerm is -100.0f to 100.0f.
+ _pg_user->iTerm = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ // Range of dTerm is -100.0f to 100.0f.
+ _pg_user->dTerm = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ // Range of fTerm is -100.0f to 100.0f.
+ _pg_user->fTerm = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryControlLoopPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetryControlLoop packet
+ *
+ * Current state of the transmuter current control loop
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param pTerm is
+ * \param iTerm is
+ * \param dTerm is
+ * \param fTerm is
+ */
+void encodeTransmuter_TelemetryControlLoopPacket(void* _pg_pkt, float pTerm, float iTerm, float dTerm, float fTerm)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Range of pTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(pTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Range of iTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(iTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Range of dTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(dTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Range of fTerm is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(fTerm, _pg_data, &_pg_byteindex, 327.67f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryControlLoopPacketID());
+
+}// encodeTransmuter_TelemetryControlLoopPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetryControlLoop packet
+ *
+ * Current state of the transmuter current control loop
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param pTerm receives
+ * \param iTerm receives
+ * \param dTerm receives
+ * \param fTerm receives
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryControlLoopPacket(const void* _pg_pkt, float* pTerm, float* iTerm, float* dTerm, float* fTerm)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryControlLoopPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetryControlLoopMinDataLength())
+ return 0;
+
+ // Range of pTerm is -100.0f to 100.0f.
+ (*pTerm) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ // Range of iTerm is -100.0f to 100.0f.
+ (*iTerm) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ // Range of dTerm is -100.0f to 100.0f.
+ (*dTerm) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ // Range of fTerm is -100.0f to 100.0f.
+ (*fTerm) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryControlLoopPacket
+
+/*!
+ * \brief Create the Transmuter_TelemetryAPBPower packet
+ *
+ * Power information for the Auxilary Power Board
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetryAPBPowerPacketStructure(void* _pg_pkt, const Transmuter_TelemetryAPBPower_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // APB output voltage (V)
+ // Range of apbVoltage is 0.0f to 25.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->apbVoltage, _pg_data, &_pg_byteindex, 0.0f, 2621.4f);
+
+ // APB output current (A)
+ // Range of apbCurrent is 0.0f to 8.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->apbCurrent, _pg_data, &_pg_byteindex, 0.0f, 8191.875f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryAPBPowerPacketID());
+
+}// encodeTransmuter_TelemetryAPBPowerPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetryAPBPower packet
+ *
+ * Power information for the Auxilary Power Board
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryAPBPowerPacketStructure(const void* _pg_pkt, Transmuter_TelemetryAPBPower_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryAPBPowerPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetryAPBPowerMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // APB output voltage (V)
+ // Range of apbVoltage is 0.0f to 25.0f.
+ _pg_user->apbVoltage = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/2621.4f);
+
+ // APB output current (A)
+ // Range of apbCurrent is 0.0f to 8.0f.
+ _pg_user->apbCurrent = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/8191.875f);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryAPBPowerPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetryAPBPower packet
+ *
+ * Power information for the Auxilary Power Board
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param apbVoltage is APB output voltage (V)
+ * \param apbCurrent is APB output current (A)
+ */
+void encodeTransmuter_TelemetryAPBPowerPacket(void* _pg_pkt, float apbVoltage, float apbCurrent)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // APB output voltage (V)
+ // Range of apbVoltage is 0.0f to 25.0f.
+ float32ScaledTo2UnsignedBeBytes(apbVoltage, _pg_data, &_pg_byteindex, 0.0f, 2621.4f);
+
+ // APB output current (A)
+ // Range of apbCurrent is 0.0f to 8.0f.
+ float32ScaledTo2UnsignedBeBytes(apbCurrent, _pg_data, &_pg_byteindex, 0.0f, 8191.875f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetryAPBPowerPacketID());
+
+}// encodeTransmuter_TelemetryAPBPowerPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetryAPBPower packet
+ *
+ * Power information for the Auxilary Power Board
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param apbVoltage receives APB output voltage (V)
+ * \param apbCurrent receives APB output current (A)
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetryAPBPowerPacket(const void* _pg_pkt, float* apbVoltage, float* apbCurrent)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetryAPBPowerPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetryAPBPowerMinDataLength())
+ return 0;
+
+ // APB output voltage (V)
+ // Range of apbVoltage is 0.0f to 25.0f.
+ (*apbVoltage) = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/2621.4f);
+
+ // APB output current (A)
+ // Range of apbCurrent is 0.0f to 8.0f.
+ (*apbCurrent) = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/8191.875f);
+
+ return 1;
+
+}// decodeTransmuter_TelemetryAPBPowerPacket
+
+/*!
+ * \brief Set a Transmuter_WarningLevels_t to initial values.
+ *
+ * Set a Transmuter_WarningLevels_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_WarningLevels_t(Transmuter_WarningLevels_t* _pg_user)
+{
+
+ // Engine (CHT) temperature warning level
+ _pg_user->engineTemp = 140;
+
+}// initTransmuter_WarningLevels_t
+
+/*!
+ * \brief Create the Transmuter_WarningLevels packet
+ *
+ * Warning level configuration values
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_WarningLevelsPacketStructure(void* _pg_pkt, const Transmuter_WarningLevels_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Engine (CHT) temperature warning level
+ // Range of engineTemp is 0 to 255.
+ uint8ToBytes(_pg_user->engineTemp, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_WarningLevelsPacketID());
+
+}// encodeTransmuter_WarningLevelsPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_WarningLevels packet
+ *
+ * Warning level configuration values
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_WarningLevelsPacketStructure(const void* _pg_pkt, Transmuter_WarningLevels_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_WarningLevelsPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_WarningLevelsMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Engine (CHT) temperature warning level
+ // Range of engineTemp is 0 to 255.
+ _pg_user->engineTemp = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_WarningLevelsPacketStructure
+
+/*!
+ * \brief Create the Transmuter_WarningLevels packet
+ *
+ * Warning level configuration values
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param engineTemp is Engine (CHT) temperature warning level
+ */
+void encodeTransmuter_WarningLevelsPacket(void* _pg_pkt, uint8_t engineTemp)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Engine (CHT) temperature warning level
+ // Range of engineTemp is 0 to 255.
+ uint8ToBytes(engineTemp, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_WarningLevelsPacketID());
+
+}// encodeTransmuter_WarningLevelsPacket
+
+/*!
+ * \brief Decode the Transmuter_WarningLevels packet
+ *
+ * Warning level configuration values
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param engineTemp receives Engine (CHT) temperature warning level
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_WarningLevelsPacket(const void* _pg_pkt, uint8_t* engineTemp)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_WarningLevelsPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_WarningLevelsMinDataLength())
+ return 0;
+
+ // Engine (CHT) temperature warning level
+ // Range of engineTemp is 0 to 255.
+ (*engineTemp) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_WarningLevelsPacket
+
+/*!
+ * \brief Verify a Transmuter_WarningLevels_t has acceptable values.
+ *
+ * Verify a Transmuter_WarningLevels_t has acceptable values. Not all fields are
+ * verified, only those which the protocol specifies. Fields which are outside
+ * the allowable range are changed to the maximum or minimum allowable value.
+ * \param _pg_user is the structure whose data are verified
+ * \return 1 if all verifiable data where valid, else 0 if data had to be corrected
+ */
+int verifyTransmuter_WarningLevels_t(Transmuter_WarningLevels_t* _pg_user)
+{
+ int _pg_good = 1;
+
+ // Engine (CHT) temperature warning level
+ if(_pg_user->engineTemp < 50)
+ {
+ _pg_user->engineTemp = 50;
+ _pg_good = 0;
+ }
+
+ return _pg_good;
+
+}// verifyTransmuter_WarningLevels_t
+
+/*!
+ * \brief Set a Transmuter_EFISettings_t to initial values.
+ *
+ * Set a Transmuter_EFISettings_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_EFISettings_t(Transmuter_EFISettings_t* _pg_user)
+{
+
+ // CAN Node ID for the ECU
+ _pg_user->ecuAddress = 200;
+
+ // CAN Node ID for the triplex pump
+ _pg_user->triplexAddress = 201;
+
+ // Minimum required fuel pressure
+ _pg_user->fuelPressureMin = 5.0f;
+
+}// initTransmuter_EFISettings_t
+
+/*!
+ * \brief Create the Transmuter_EFISettings packet
+ *
+ * ECU connection configuration packet
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_EFISettingsPacketStructure(void* _pg_pkt, const Transmuter_EFISettings_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // CAN Node ID for the ECU
+ // Range of ecuAddress is 0 to 255.
+ uint8ToBytes(_pg_user->ecuAddress, _pg_data, &_pg_byteindex);
+
+ // ECU firmware checksum
+ // Range of ecuFirmwareChecksum is 0 to 65535.
+ uint16ToBeBytes(_pg_user->ecuFirmwareChecksum, _pg_data, &_pg_byteindex);
+
+ // ECU settings checksum
+ // Range of ecuSettingsChecksum is 0 to 65535.
+ uint16ToBeBytes(_pg_user->ecuSettingsChecksum, _pg_data, &_pg_byteindex);
+
+ // CAN Node ID for the triplex pump
+ // Range of triplexAddress is 0 to 255.
+ uint8ToBytes(_pg_user->triplexAddress, _pg_data, &_pg_byteindex);
+
+ // Triplex pump firmware checksum
+ // Range of triplexFirmwareChecksum is 0 to 65535.
+ uint16ToBeBytes(_pg_user->triplexFirmwareChecksum, _pg_data, &_pg_byteindex);
+
+ // Minimum required fuel pressure
+ // Range of fuelPressureMin is -327.67f to 327.67f.
+ float32ScaledTo2SignedBeBytes(_pg_user->fuelPressureMin, _pg_data, &_pg_byteindex, 100.0f);
+
+ // Fuel pressure control method
+ // Range of pumpController is 0 to 255.
+ uint8ToBytes(_pg_user->pumpController, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_EFISettingsPacketID());
+
+}// encodeTransmuter_EFISettingsPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_EFISettings packet
+ *
+ * ECU connection configuration packet
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_EFISettingsPacketStructure(const void* _pg_pkt, Transmuter_EFISettings_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_EFISettingsPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_EFISettingsMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // this packet has default fields, make sure they are set
+ _pg_user->pumpController = TRANSMUTER_PUMP_TRIPLEX;
+
+ // CAN Node ID for the ECU
+ // Range of ecuAddress is 0 to 255.
+ _pg_user->ecuAddress = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // ECU firmware checksum
+ // Range of ecuFirmwareChecksum is 0 to 65535.
+ _pg_user->ecuFirmwareChecksum = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // ECU settings checksum
+ // Range of ecuSettingsChecksum is 0 to 65535.
+ _pg_user->ecuSettingsChecksum = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // CAN Node ID for the triplex pump
+ // Range of triplexAddress is 0 to 255.
+ _pg_user->triplexAddress = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Triplex pump firmware checksum
+ // Range of triplexFirmwareChecksum is 0 to 65535.
+ _pg_user->triplexFirmwareChecksum = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Minimum required fuel pressure
+ // Range of fuelPressureMin is -327.67f to 327.67f.
+ _pg_user->fuelPressureMin = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/100.0f);
+
+ if(_pg_byteindex + 1 > _pg_numbytes)
+ return 1;
+
+ // Fuel pressure control method
+ // Range of pumpController is 0 to 255.
+ _pg_user->pumpController = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_EFISettingsPacketStructure
+
+/*!
+ * \brief Create the Transmuter_EFISettings packet
+ *
+ * ECU connection configuration packet
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param ecuAddress is CAN Node ID for the ECU
+ * \param ecuFirmwareChecksum is ECU firmware checksum
+ * \param ecuSettingsChecksum is ECU settings checksum
+ * \param triplexAddress is CAN Node ID for the triplex pump
+ * \param triplexFirmwareChecksum is Triplex pump firmware checksum
+ * \param fuelPressureMin is Minimum required fuel pressure
+ * \param pumpController is Fuel pressure control method
+ */
+void encodeTransmuter_EFISettingsPacket(void* _pg_pkt, uint8_t ecuAddress, uint16_t ecuFirmwareChecksum, uint16_t ecuSettingsChecksum, uint8_t triplexAddress, uint16_t triplexFirmwareChecksum, float fuelPressureMin, uint8_t pumpController)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // CAN Node ID for the ECU
+ // Range of ecuAddress is 0 to 255.
+ uint8ToBytes(ecuAddress, _pg_data, &_pg_byteindex);
+
+ // ECU firmware checksum
+ // Range of ecuFirmwareChecksum is 0 to 65535.
+ uint16ToBeBytes(ecuFirmwareChecksum, _pg_data, &_pg_byteindex);
+
+ // ECU settings checksum
+ // Range of ecuSettingsChecksum is 0 to 65535.
+ uint16ToBeBytes(ecuSettingsChecksum, _pg_data, &_pg_byteindex);
+
+ // CAN Node ID for the triplex pump
+ // Range of triplexAddress is 0 to 255.
+ uint8ToBytes(triplexAddress, _pg_data, &_pg_byteindex);
+
+ // Triplex pump firmware checksum
+ // Range of triplexFirmwareChecksum is 0 to 65535.
+ uint16ToBeBytes(triplexFirmwareChecksum, _pg_data, &_pg_byteindex);
+
+ // Minimum required fuel pressure
+ // Range of fuelPressureMin is -327.67f to 327.67f.
+ float32ScaledTo2SignedBeBytes(fuelPressureMin, _pg_data, &_pg_byteindex, 100.0f);
+
+ // Fuel pressure control method
+ // Range of pumpController is 0 to 255.
+ uint8ToBytes(pumpController, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_EFISettingsPacketID());
+
+}// encodeTransmuter_EFISettingsPacket
+
+/*!
+ * \brief Decode the Transmuter_EFISettings packet
+ *
+ * ECU connection configuration packet
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param ecuAddress receives CAN Node ID for the ECU
+ * \param ecuFirmwareChecksum receives ECU firmware checksum
+ * \param ecuSettingsChecksum receives ECU settings checksum
+ * \param triplexAddress receives CAN Node ID for the triplex pump
+ * \param triplexFirmwareChecksum receives Triplex pump firmware checksum
+ * \param fuelPressureMin receives Minimum required fuel pressure
+ * \param pumpController receives Fuel pressure control method
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_EFISettingsPacket(const void* _pg_pkt, uint8_t* ecuAddress, uint16_t* ecuFirmwareChecksum, uint16_t* ecuSettingsChecksum, uint8_t* triplexAddress, uint16_t* triplexFirmwareChecksum, float* fuelPressureMin, uint8_t* pumpController)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_EFISettingsPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_EFISettingsMinDataLength())
+ return 0;
+
+ // this packet has default fields, make sure they are set
+ (*pumpController) = TRANSMUTER_PUMP_TRIPLEX;
+
+ // CAN Node ID for the ECU
+ // Range of ecuAddress is 0 to 255.
+ (*ecuAddress) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // ECU firmware checksum
+ // Range of ecuFirmwareChecksum is 0 to 65535.
+ (*ecuFirmwareChecksum) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // ECU settings checksum
+ // Range of ecuSettingsChecksum is 0 to 65535.
+ (*ecuSettingsChecksum) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // CAN Node ID for the triplex pump
+ // Range of triplexAddress is 0 to 255.
+ (*triplexAddress) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Triplex pump firmware checksum
+ // Range of triplexFirmwareChecksum is 0 to 65535.
+ (*triplexFirmwareChecksum) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Minimum required fuel pressure
+ // Range of fuelPressureMin is -327.67f to 327.67f.
+ (*fuelPressureMin) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/100.0f);
+
+ if(_pg_byteindex + 1 > _pg_numbytes)
+ return 1;
+
+ // Fuel pressure control method
+ // Range of pumpController is 0 to 255.
+ (*pumpController) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_EFISettingsPacket
+
+/*!
+ * \brief Verify a Transmuter_EFISettings_t has acceptable values.
+ *
+ * Verify a Transmuter_EFISettings_t has acceptable values. Not all fields are
+ * verified, only those which the protocol specifies. Fields which are outside
+ * the allowable range are changed to the maximum or minimum allowable value.
+ * \param _pg_user is the structure whose data are verified
+ * \return 1 if all verifiable data where valid, else 0 if data had to be corrected
+ */
+int verifyTransmuter_EFISettings_t(Transmuter_EFISettings_t* _pg_user)
+{
+ int _pg_good = 1;
+
+ // CAN Node ID for the ECU
+ if(_pg_user->ecuAddress > 254)
+ {
+ _pg_user->ecuAddress = 254;
+ _pg_good = 0;
+ }
+
+ // CAN Node ID for the triplex pump
+ if(_pg_user->triplexAddress > 254)
+ {
+ _pg_user->triplexAddress = 254;
+ _pg_good = 0;
+ }
+
+ // Minimum required fuel pressure
+ if(_pg_user->fuelPressureMin < 1.0f)
+ {
+ _pg_user->fuelPressureMin = 1.0f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->fuelPressureMin > 25.0f)
+ {
+ _pg_user->fuelPressureMin = 25.0f;
+ _pg_good = 0;
+ }
+
+ return _pg_good;
+
+}// verifyTransmuter_EFISettings_t
+
+/*!
+ * \brief Set a Transmuter_GeneratorSettings_t to initial values.
+ *
+ * Set a Transmuter_GeneratorSettings_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_GeneratorSettings_t(Transmuter_GeneratorSettings_t* _pg_user)
+{
+
+ // Belt ratio between engine and generator motor
+ _pg_user->beltRatio = 1.0f;
+
+ // Allowable RPM measurement difference between generator and engine
+ _pg_user->rpmThreshold = 350;
+
+ // Timeout before system disables due to engine power loss. Set to zero to disable timeout
+ _pg_user->powerLossTimeout = 25;
+
+}// initTransmuter_GeneratorSettings_t
+
+/*!
+ * \brief Create the Transmuter_GeneratorSettings packet
+ *
+ * Generator motor parameters
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_GeneratorSettingsPacketStructure(void* _pg_pkt, const Transmuter_GeneratorSettings_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Belt ratio between engine and generator motor
+ // Range of beltRatio is 0.0f to 65.535f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->beltRatio, _pg_data, &_pg_byteindex, 0.0f, 1000.0f);
+
+ // Allowable RPM measurement difference between generator and engine
+ // Range of rpmThreshold is 0 to 65535.
+ uint16ToBeBytes(_pg_user->rpmThreshold, _pg_data, &_pg_byteindex);
+
+ // Timeout before system disables due to engine power loss. Set to zero to disable timeout
+ // Range of powerLossTimeout is 0 to 255.
+ uint8ToBytes(_pg_user->powerLossTimeout, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_GeneratorSettingsPacketID());
+
+}// encodeTransmuter_GeneratorSettingsPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_GeneratorSettings packet
+ *
+ * Generator motor parameters
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_GeneratorSettingsPacketStructure(const void* _pg_pkt, Transmuter_GeneratorSettings_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_GeneratorSettingsPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_GeneratorSettingsMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Belt ratio between engine and generator motor
+ // Range of beltRatio is 0.0f to 65.535f.
+ _pg_user->beltRatio = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1000.0f);
+
+ // Allowable RPM measurement difference between generator and engine
+ // Range of rpmThreshold is 0 to 65535.
+ _pg_user->rpmThreshold = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Timeout before system disables due to engine power loss. Set to zero to disable timeout
+ // Range of powerLossTimeout is 0 to 255.
+ _pg_user->powerLossTimeout = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_GeneratorSettingsPacketStructure
+
+/*!
+ * \brief Create the Transmuter_GeneratorSettings packet
+ *
+ * Generator motor parameters
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param beltRatio is Belt ratio between engine and generator motor
+ * \param rpmThreshold is Allowable RPM measurement difference between generator and engine
+ * \param powerLossTimeout is Timeout before system disables due to engine power loss. Set to zero to disable timeout
+ */
+void encodeTransmuter_GeneratorSettingsPacket(void* _pg_pkt, float beltRatio, uint16_t rpmThreshold, uint8_t powerLossTimeout)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Belt ratio between engine and generator motor
+ // Range of beltRatio is 0.0f to 65.535f.
+ float32ScaledTo2UnsignedBeBytes(beltRatio, _pg_data, &_pg_byteindex, 0.0f, 1000.0f);
+
+ // Allowable RPM measurement difference between generator and engine
+ // Range of rpmThreshold is 0 to 65535.
+ uint16ToBeBytes(rpmThreshold, _pg_data, &_pg_byteindex);
+
+ // Timeout before system disables due to engine power loss. Set to zero to disable timeout
+ // Range of powerLossTimeout is 0 to 255.
+ uint8ToBytes(powerLossTimeout, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_GeneratorSettingsPacketID());
+
+}// encodeTransmuter_GeneratorSettingsPacket
+
+/*!
+ * \brief Decode the Transmuter_GeneratorSettings packet
+ *
+ * Generator motor parameters
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param beltRatio receives Belt ratio between engine and generator motor
+ * \param rpmThreshold receives Allowable RPM measurement difference between generator and engine
+ * \param powerLossTimeout receives Timeout before system disables due to engine power loss. Set to zero to disable timeout
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_GeneratorSettingsPacket(const void* _pg_pkt, float* beltRatio, uint16_t* rpmThreshold, uint8_t* powerLossTimeout)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_GeneratorSettingsPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_GeneratorSettingsMinDataLength())
+ return 0;
+
+ // Belt ratio between engine and generator motor
+ // Range of beltRatio is 0.0f to 65.535f.
+ (*beltRatio) = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1000.0f);
+
+ // Allowable RPM measurement difference between generator and engine
+ // Range of rpmThreshold is 0 to 65535.
+ (*rpmThreshold) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Timeout before system disables due to engine power loss. Set to zero to disable timeout
+ // Range of powerLossTimeout is 0 to 255.
+ (*powerLossTimeout) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_GeneratorSettingsPacket
+
+/*!
+ * \brief Verify a Transmuter_GeneratorSettings_t has acceptable values.
+ *
+ * Verify a Transmuter_GeneratorSettings_t has acceptable values. Not all fields are
+ * verified, only those which the protocol specifies. Fields which are outside
+ * the allowable range are changed to the maximum or minimum allowable value.
+ * \param _pg_user is the structure whose data are verified
+ * \return 1 if all verifiable data where valid, else 0 if data had to be corrected
+ */
+int verifyTransmuter_GeneratorSettings_t(Transmuter_GeneratorSettings_t* _pg_user)
+{
+ int _pg_good = 1;
+
+ // Belt ratio between engine and generator motor
+ if(_pg_user->beltRatio < 0.1f)
+ {
+ _pg_user->beltRatio = 0.1f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->beltRatio > 10.0f)
+ {
+ _pg_user->beltRatio = 10.0f;
+ _pg_good = 0;
+ }
+
+ // Allowable RPM measurement difference between generator and engine
+ if(_pg_user->rpmThreshold > 5000)
+ {
+ _pg_user->rpmThreshold = 5000;
+ _pg_good = 0;
+ }
+
+ return _pg_good;
+
+}// verifyTransmuter_GeneratorSettings_t
+
+/*!
+ * \brief Set a Transmuter_StartingSettings_t to initial values.
+ *
+ * Set a Transmuter_StartingSettings_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_StartingSettings_t(Transmuter_StartingSettings_t* _pg_user)
+{
+
+ // Number of auto-retries allowed for engine starting routine
+ _pg_user->retries = 3;
+
+ // Timeout for engine starting routine
+ _pg_user->timeout = 50;
+
+ // Starting RPM value
+ _pg_user->rpm = 3000;
+
+ // Starting throttle position
+ _pg_user->throttle = 25;
+
+ // Settling time after reaching starting RPM
+ _pg_user->settlingPeriod = 25;
+
+}// initTransmuter_StartingSettings_t
+
+/*!
+ * \brief Create the Transmuter_StartingSettings packet
+ *
+ * Engine starting settings
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_StartingSettingsPacketStructure(void* _pg_pkt, const Transmuter_StartingSettings_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Number of auto-retries allowed for engine starting routine
+ // Range of retries is 0 to 255.
+ uint8ToBytes(_pg_user->retries, _pg_data, &_pg_byteindex);
+
+ // Timeout for engine starting routine
+ // Range of timeout is 0 to 255.
+ uint8ToBytes(_pg_user->timeout, _pg_data, &_pg_byteindex);
+
+ // Starting RPM value
+ // Range of rpm is 0 to 65535.
+ uint16ToBeBytes(_pg_user->rpm, _pg_data, &_pg_byteindex);
+
+ // Starting throttle position
+ // Range of throttle is 0 to 255.
+ uint8ToBytes(_pg_user->throttle, _pg_data, &_pg_byteindex);
+
+ // Settling time after reaching starting RPM
+ // Range of settlingPeriod is 0 to 255.
+ uint8ToBytes(_pg_user->settlingPeriod, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_StartingSettingsPacketID());
+
+}// encodeTransmuter_StartingSettingsPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_StartingSettings packet
+ *
+ * Engine starting settings
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_StartingSettingsPacketStructure(const void* _pg_pkt, Transmuter_StartingSettings_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_StartingSettingsPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_StartingSettingsMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Number of auto-retries allowed for engine starting routine
+ // Range of retries is 0 to 255.
+ _pg_user->retries = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Timeout for engine starting routine
+ // Range of timeout is 0 to 255.
+ _pg_user->timeout = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Starting RPM value
+ // Range of rpm is 0 to 65535.
+ _pg_user->rpm = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Starting throttle position
+ // Range of throttle is 0 to 255.
+ _pg_user->throttle = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Settling time after reaching starting RPM
+ // Range of settlingPeriod is 0 to 255.
+ _pg_user->settlingPeriod = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_StartingSettingsPacketStructure
+
+/*!
+ * \brief Create the Transmuter_StartingSettings packet
+ *
+ * Engine starting settings
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param retries is Number of auto-retries allowed for engine starting routine
+ * \param timeout is Timeout for engine starting routine
+ * \param rpm is Starting RPM value
+ * \param throttle is Starting throttle position
+ * \param settlingPeriod is Settling time after reaching starting RPM
+ */
+void encodeTransmuter_StartingSettingsPacket(void* _pg_pkt, uint8_t retries, uint8_t timeout, uint16_t rpm, uint8_t throttle, uint8_t settlingPeriod)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Number of auto-retries allowed for engine starting routine
+ // Range of retries is 0 to 255.
+ uint8ToBytes(retries, _pg_data, &_pg_byteindex);
+
+ // Timeout for engine starting routine
+ // Range of timeout is 0 to 255.
+ uint8ToBytes(timeout, _pg_data, &_pg_byteindex);
+
+ // Starting RPM value
+ // Range of rpm is 0 to 65535.
+ uint16ToBeBytes(rpm, _pg_data, &_pg_byteindex);
+
+ // Starting throttle position
+ // Range of throttle is 0 to 255.
+ uint8ToBytes(throttle, _pg_data, &_pg_byteindex);
+
+ // Settling time after reaching starting RPM
+ // Range of settlingPeriod is 0 to 255.
+ uint8ToBytes(settlingPeriod, _pg_data, &_pg_byteindex);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_StartingSettingsPacketID());
+
+}// encodeTransmuter_StartingSettingsPacket
+
+/*!
+ * \brief Decode the Transmuter_StartingSettings packet
+ *
+ * Engine starting settings
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param retries receives Number of auto-retries allowed for engine starting routine
+ * \param timeout receives Timeout for engine starting routine
+ * \param rpm receives Starting RPM value
+ * \param throttle receives Starting throttle position
+ * \param settlingPeriod receives Settling time after reaching starting RPM
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_StartingSettingsPacket(const void* _pg_pkt, uint8_t* retries, uint8_t* timeout, uint16_t* rpm, uint8_t* throttle, uint8_t* settlingPeriod)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_StartingSettingsPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_StartingSettingsMinDataLength())
+ return 0;
+
+ // Number of auto-retries allowed for engine starting routine
+ // Range of retries is 0 to 255.
+ (*retries) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Timeout for engine starting routine
+ // Range of timeout is 0 to 255.
+ (*timeout) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Starting RPM value
+ // Range of rpm is 0 to 65535.
+ (*rpm) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Starting throttle position
+ // Range of throttle is 0 to 255.
+ (*throttle) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Settling time after reaching starting RPM
+ // Range of settlingPeriod is 0 to 255.
+ (*settlingPeriod) = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ return 1;
+
+}// decodeTransmuter_StartingSettingsPacket
+
+/*!
+ * \brief Verify a Transmuter_StartingSettings_t has acceptable values.
+ *
+ * Verify a Transmuter_StartingSettings_t has acceptable values. Not all fields are
+ * verified, only those which the protocol specifies. Fields which are outside
+ * the allowable range are changed to the maximum or minimum allowable value.
+ * \param _pg_user is the structure whose data are verified
+ * \return 1 if all verifiable data where valid, else 0 if data had to be corrected
+ */
+int verifyTransmuter_StartingSettings_t(Transmuter_StartingSettings_t* _pg_user)
+{
+ int _pg_good = 1;
+
+ // Number of auto-retries allowed for engine starting routine
+ if(_pg_user->retries > 50)
+ {
+ _pg_user->retries = 50;
+ _pg_good = 0;
+ }
+
+ // Timeout for engine starting routine
+ if(_pg_user->timeout < 1)
+ {
+ _pg_user->timeout = 1;
+ _pg_good = 0;
+ }
+
+ // Starting RPM value
+ if(_pg_user->rpm < 500)
+ {
+ _pg_user->rpm = 500;
+ _pg_good = 0;
+ }
+ else if(_pg_user->rpm > 25000)
+ {
+ _pg_user->rpm = 25000;
+ _pg_good = 0;
+ }
+
+ // Starting throttle position
+ if(_pg_user->throttle > 100)
+ {
+ _pg_user->throttle = 100;
+ _pg_good = 0;
+ }
+
+ // Settling time after reaching starting RPM
+ if(_pg_user->settlingPeriod < 10)
+ {
+ _pg_user->settlingPeriod = 10;
+ _pg_good = 0;
+ }
+ else if(_pg_user->settlingPeriod > 250)
+ {
+ _pg_user->settlingPeriod = 250;
+ _pg_good = 0;
+ }
+
+ return _pg_good;
+
+}// verifyTransmuter_StartingSettings_t
+
+/*!
+ * \brief Set a Transmuter_PowerMap_t to initial values.
+ *
+ * Set a Transmuter_PowerMap_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_PowerMap_t(Transmuter_PowerMap_t* _pg_user)
+{
+
+ // Power demand low pass filter corner frequency
+ _pg_user->powerFilterHz = 1.0f;
+
+}// initTransmuter_PowerMap_t
+
+/*!
+ * \brief Create the Transmuter_PowerMap packet
+ *
+ * Configuration of transmuter power map lookup table
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_PowerMapPacketStructure(void* _pg_pkt, const Transmuter_PowerMap_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+ unsigned _pg_i = 0;
+
+ // Range of size is 0 to 255.
+ uint8ToBytes(_pg_user->size, _pg_data, &_pg_byteindex);
+
+ // Power Input (W)
+ // Range of power is -32768 to 32767.
+ for(_pg_i = 0; _pg_i < (unsigned)_pg_user->size && _pg_i < 15; _pg_i++)
+ int16ToBeBytes(_pg_user->power[_pg_i], _pg_data, &_pg_byteindex);
+
+ // Speed Output (RPM)
+ // Range of rpm is -32768 to 32767.
+ for(_pg_i = 0; _pg_i < (unsigned)_pg_user->size && _pg_i < 15; _pg_i++)
+ int16ToBeBytes(_pg_user->rpm[_pg_i], _pg_data, &_pg_byteindex);
+
+ // Power demand low pass filter corner frequency
+ // Range of powerFilterHz is 0.0f to 65.535f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->powerFilterHz, _pg_data, &_pg_byteindex, 0.0f, 1000.0f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_PowerMapPacketID());
+
+}// encodeTransmuter_PowerMapPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_PowerMap packet
+ *
+ * Configuration of transmuter power map lookup table
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_PowerMapPacketStructure(const void* _pg_pkt, Transmuter_PowerMap_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+ unsigned _pg_i = 0;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_PowerMapPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_PowerMapMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // this packet has default fields, make sure they are set
+ _pg_user->powerFilterHz = 1.0f;
+
+ // Range of size is 0 to 255.
+ _pg_user->size = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Power Input (W)
+ // Range of power is -32768 to 32767.
+ for(_pg_i = 0; _pg_i < (unsigned)_pg_user->size && _pg_i < 15; _pg_i++)
+ _pg_user->power[_pg_i] = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Speed Output (RPM)
+ // Range of rpm is -32768 to 32767.
+ for(_pg_i = 0; _pg_i < (unsigned)_pg_user->size && _pg_i < 15; _pg_i++)
+ _pg_user->rpm[_pg_i] = int16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Used variable length arrays or dependent fields, check actual length
+ if(_pg_numbytes < _pg_byteindex)
+ return 0;
+
+ if(_pg_byteindex + 2 > _pg_numbytes)
+ return 1;
+
+ // Power demand low pass filter corner frequency
+ // Range of powerFilterHz is 0.0f to 65.535f.
+ _pg_user->powerFilterHz = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1000.0f);
+
+ return 1;
+
+}// decodeTransmuter_PowerMapPacketStructure
+
+/*!
+ * \brief Verify a Transmuter_PowerMap_t has acceptable values.
+ *
+ * Verify a Transmuter_PowerMap_t has acceptable values. Not all fields are
+ * verified, only those which the protocol specifies. Fields which are outside
+ * the allowable range are changed to the maximum or minimum allowable value.
+ * \param _pg_user is the structure whose data are verified
+ * \return 1 if all verifiable data where valid, else 0 if data had to be corrected
+ */
+int verifyTransmuter_PowerMap_t(Transmuter_PowerMap_t* _pg_user)
+{
+ int _pg_good = 1;
+ unsigned _pg_i = 0;
+
+ if(_pg_user->size < 2)
+ {
+ _pg_user->size = 2;
+ _pg_good = 0;
+ }
+ else if(_pg_user->size > 15)
+ {
+ _pg_user->size = 15;
+ _pg_good = 0;
+ }
+
+ // Power Input (W)
+ for(_pg_i = 0; _pg_i < (unsigned)_pg_user->size && _pg_i < 15; _pg_i++)
+ if(_pg_user->power[_pg_i] < 0)
+ {
+ _pg_user->power[_pg_i] = 0;
+ _pg_good = 0;
+ }
+ else if(_pg_user->power[_pg_i] > 25000)
+ {
+ _pg_user->power[_pg_i] = 25000;
+ _pg_good = 0;
+ }
+
+ // Speed Output (RPM)
+ for(_pg_i = 0; _pg_i < (unsigned)_pg_user->size && _pg_i < 15; _pg_i++)
+ if(_pg_user->rpm[_pg_i] < 0)
+ {
+ _pg_user->rpm[_pg_i] = 0;
+ _pg_good = 0;
+ }
+ else if(_pg_user->rpm[_pg_i] > 25000)
+ {
+ _pg_user->rpm[_pg_i] = 25000;
+ _pg_good = 0;
+ }
+
+ // Power demand low pass filter corner frequency
+ if(_pg_user->powerFilterHz < 0.01f)
+ {
+ _pg_user->powerFilterHz = 0.01f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->powerFilterHz > 50.0f)
+ {
+ _pg_user->powerFilterHz = 50.0f;
+ _pg_good = 0;
+ }
+
+ return _pg_good;
+
+}// verifyTransmuter_PowerMap_t
+
+/*!
+ * \brief Set a Transmuter_BatterySettings_t to initial values.
+ *
+ * Set a Transmuter_BatterySettings_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_BatterySettings_t(Transmuter_BatterySettings_t* _pg_user)
+{
+
+ _pg_user->nominalVoltage = 48;
+
+ _pg_user->chargingCurrent = 5;
+
+ // Battery capacity
+ _pg_user->capacity = 5000;
+
+ // Battery current measurement scaler value
+ _pg_user->currentScaler = 1.0f;
+
+ // Battery current measurement offset value
+ _pg_user->currentOffset = 0.0f;
+
+}// initTransmuter_BatterySettings_t
+
+/*!
+ * \brief Create the Transmuter_BatterySettings packet
+ *
+ * Configuration of battery charging parameters
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_BatterySettingsPacketStructure(void* _pg_pkt, const Transmuter_BatterySettings_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Range of nominalVoltage is 0.0f to 100.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->nominalVoltage, _pg_data, &_pg_byteindex, 0.0f, 655.35f);
+
+ // Range of chargingCurrent is 0.0f to 100.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->chargingCurrent, _pg_data, &_pg_byteindex, 0.0f, 655.35f);
+
+ // Battery capacity
+ // Range of capacity is 0 to 65535.
+ uint16ToBeBytes(_pg_user->capacity, _pg_data, &_pg_byteindex);
+
+ // Reserved for future use
+ uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
+
+ // Battery current measurement scaler value
+ // Range of currentScaler is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->currentScaler, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Battery current measurement offset value
+ // Range of currentOffset is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(_pg_user->currentOffset, _pg_data, &_pg_byteindex, 327.67f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_BatterySettingsPacketID());
+
+}// encodeTransmuter_BatterySettingsPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_BatterySettings packet
+ *
+ * Configuration of battery charging parameters
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_BatterySettingsPacketStructure(const void* _pg_pkt, Transmuter_BatterySettings_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_BatterySettingsPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_BatterySettingsMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // this packet has default fields, make sure they are set
+ _pg_user->currentScaler = 1.0f;
+ _pg_user->currentOffset = 0.0f;
+
+ // Range of nominalVoltage is 0.0f to 100.0f.
+ _pg_user->nominalVoltage = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/655.35f);
+
+ // Range of chargingCurrent is 0.0f to 100.0f.
+ _pg_user->chargingCurrent = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/655.35f);
+
+ // Battery capacity
+ // Range of capacity is 0 to 65535.
+ _pg_user->capacity = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Reserved for future use
+ _pg_byteindex += 1;
+
+ if(_pg_byteindex + 2 > _pg_numbytes)
+ return 1;
+
+ // Battery current measurement scaler value
+ // Range of currentScaler is -100.0f to 100.0f.
+ _pg_user->currentScaler = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ if(_pg_byteindex + 2 > _pg_numbytes)
+ return 1;
+
+ // Battery current measurement offset value
+ // Range of currentOffset is -100.0f to 100.0f.
+ _pg_user->currentOffset = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ return 1;
+
+}// decodeTransmuter_BatterySettingsPacketStructure
+
+/*!
+ * \brief Create the Transmuter_BatterySettings packet
+ *
+ * Configuration of battery charging parameters
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param nominalVoltage is
+ * \param chargingCurrent is
+ * \param capacity is Battery capacity
+ * \param currentScaler is Battery current measurement scaler value
+ * \param currentOffset is Battery current measurement offset value
+ */
+void encodeTransmuter_BatterySettingsPacket(void* _pg_pkt, float nominalVoltage, float chargingCurrent, uint16_t capacity, float currentScaler, float currentOffset)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Range of nominalVoltage is 0.0f to 100.0f.
+ float32ScaledTo2UnsignedBeBytes(nominalVoltage, _pg_data, &_pg_byteindex, 0.0f, 655.35f);
+
+ // Range of chargingCurrent is 0.0f to 100.0f.
+ float32ScaledTo2UnsignedBeBytes(chargingCurrent, _pg_data, &_pg_byteindex, 0.0f, 655.35f);
+
+ // Battery capacity
+ // Range of capacity is 0 to 65535.
+ uint16ToBeBytes(capacity, _pg_data, &_pg_byteindex);
+
+ // Reserved for future use
+ uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
+
+ // Battery current measurement scaler value
+ // Range of currentScaler is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(currentScaler, _pg_data, &_pg_byteindex, 327.67f);
+
+ // Battery current measurement offset value
+ // Range of currentOffset is -100.0f to 100.0f.
+ float32ScaledTo2SignedBeBytes(currentOffset, _pg_data, &_pg_byteindex, 327.67f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_BatterySettingsPacketID());
+
+}// encodeTransmuter_BatterySettingsPacket
+
+/*!
+ * \brief Decode the Transmuter_BatterySettings packet
+ *
+ * Configuration of battery charging parameters
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param nominalVoltage receives
+ * \param chargingCurrent receives
+ * \param capacity receives Battery capacity
+ * \param currentScaler receives Battery current measurement scaler value
+ * \param currentOffset receives Battery current measurement offset value
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_BatterySettingsPacket(const void* _pg_pkt, float* nominalVoltage, float* chargingCurrent, uint16_t* capacity, float* currentScaler, float* currentOffset)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_BatterySettingsPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_BatterySettingsMinDataLength())
+ return 0;
+
+ // this packet has default fields, make sure they are set
+ (*currentScaler) = 1.0f;
+ (*currentOffset) = 0.0f;
+
+ // Range of nominalVoltage is 0.0f to 100.0f.
+ (*nominalVoltage) = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/655.35f);
+
+ // Range of chargingCurrent is 0.0f to 100.0f.
+ (*chargingCurrent) = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/655.35f);
+
+ // Battery capacity
+ // Range of capacity is 0 to 65535.
+ (*capacity) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ // Reserved for future use
+ _pg_byteindex += 1;
+
+ if(_pg_byteindex + 2 > _pg_numbytes)
+ return 1;
+
+ // Battery current measurement scaler value
+ // Range of currentScaler is -100.0f to 100.0f.
+ (*currentScaler) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ if(_pg_byteindex + 2 > _pg_numbytes)
+ return 1;
+
+ // Battery current measurement offset value
+ // Range of currentOffset is -100.0f to 100.0f.
+ (*currentOffset) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/327.67f);
+
+ return 1;
+
+}// decodeTransmuter_BatterySettingsPacket
+
+/*!
+ * \brief Verify a Transmuter_BatterySettings_t has acceptable values.
+ *
+ * Verify a Transmuter_BatterySettings_t has acceptable values. Not all fields are
+ * verified, only those which the protocol specifies. Fields which are outside
+ * the allowable range are changed to the maximum or minimum allowable value.
+ * \param _pg_user is the structure whose data are verified
+ * \return 1 if all verifiable data where valid, else 0 if data had to be corrected
+ */
+int verifyTransmuter_BatterySettings_t(Transmuter_BatterySettings_t* _pg_user)
+{
+ int _pg_good = 1;
+
+ if(_pg_user->nominalVoltage < 20.0f)
+ {
+ _pg_user->nominalVoltage = 20.0f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->nominalVoltage > 100.0f)
+ {
+ _pg_user->nominalVoltage = 100.0f;
+ _pg_good = 0;
+ }
+
+ // Battery current measurement scaler value
+ if(_pg_user->currentScaler < 0.75f)
+ {
+ _pg_user->currentScaler = 0.75f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->currentScaler > 1.25f)
+ {
+ _pg_user->currentScaler = 1.25f;
+ _pg_good = 0;
+ }
+
+ return _pg_good;
+
+}// verifyTransmuter_BatterySettings_t
+
+/*!
+ * \brief Set a Transmuter_TelemetrySettings_t to initial values.
+ *
+ * Set a Transmuter_TelemetrySettings_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_TelemetrySettings_t(Transmuter_TelemetrySettings_t* _pg_user)
+{
+
+ // Telemetry packet selection
+ initTransmuter_TelemetryPackets_t(&_pg_user->packets);
+
+}// initTransmuter_TelemetrySettings_t
+
+/*!
+ * \brief Create the Transmuter_TelemetrySettings packet
+ *
+ * Transmuter packet selection. Enable or disable various telemetry packets
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_TelemetrySettingsPacketStructure(void* _pg_pkt, const Transmuter_TelemetrySettings_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Telemetry packet selection
+ encodeTransmuter_TelemetryPackets_t(_pg_data, &_pg_byteindex, &_pg_user->packets);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetrySettingsPacketID());
+
+}// encodeTransmuter_TelemetrySettingsPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_TelemetrySettings packet
+ *
+ * Transmuter packet selection. Enable or disable various telemetry packets
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetrySettingsPacketStructure(const void* _pg_pkt, Transmuter_TelemetrySettings_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetrySettingsPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_TelemetrySettingsMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // Telemetry packet selection
+ if(decodeTransmuter_TelemetryPackets_t(_pg_data, &_pg_byteindex, &_pg_user->packets) == 0)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_TelemetrySettingsPacketStructure
+
+/*!
+ * \brief Create the Transmuter_TelemetrySettings packet
+ *
+ * Transmuter packet selection. Enable or disable various telemetry packets
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param packets is Telemetry packet selection
+ */
+void encodeTransmuter_TelemetrySettingsPacket(void* _pg_pkt, const Transmuter_TelemetryPackets_t* packets)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Telemetry packet selection
+ encodeTransmuter_TelemetryPackets_t(_pg_data, &_pg_byteindex, packets);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_TelemetrySettingsPacketID());
+
+}// encodeTransmuter_TelemetrySettingsPacket
+
+/*!
+ * \brief Decode the Transmuter_TelemetrySettings packet
+ *
+ * Transmuter packet selection. Enable or disable various telemetry packets
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param packets receives Telemetry packet selection
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_TelemetrySettingsPacket(const void* _pg_pkt, Transmuter_TelemetryPackets_t* packets)
+{
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+ int _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_TelemetrySettingsPacketID())
+ return 0;
+
+ if(_pg_numbytes < getTransmuter_TelemetrySettingsMinDataLength())
+ return 0;
+
+ // Telemetry packet selection
+ if(decodeTransmuter_TelemetryPackets_t(_pg_data, &_pg_byteindex, packets) == 0)
+ return 0;
+
+ return 1;
+
+}// decodeTransmuter_TelemetrySettingsPacket
+
+/*!
+ * \brief Set a Transmuter_ThrottleControlLoopSettings_t to initial values.
+ *
+ * Set a Transmuter_ThrottleControlLoopSettings_t to initial values. Not all fields are set,
+ * only those which the protocol specifies.
+ * \param _pg_user is the structure whose data are set to initial values
+ */
+void initTransmuter_ThrottleControlLoopSettings_t(Transmuter_ThrottleControlLoopSettings_t* _pg_user)
+{
+
+ _pg_user->Kp = 25;
+
+ _pg_user->Ki = (float)2.5;
+
+ _pg_user->Kd = 0;
+
+ _pg_user->Kf = 0;
+
+ // Minimum engine throttle position
+ _pg_user->throttleMin = 10;
+
+ // Maximum engine throttle position
+ _pg_user->throttleMax = 100;
+
+ // Maximum throttle slew rate
+ _pg_user->slewLimit = 100;
+
+ // Throttle command low pass filter corner frequency
+ _pg_user->throttleFilterHz = 1.0f;
+
+}// initTransmuter_ThrottleControlLoopSettings_t
+
+/*!
+ * \brief Create the Transmuter_ThrottleControlLoopSettings packet
+ *
+ * Engine throttle control loop settings
+ * \param _pg_pkt points to the packet which will be created by this function
+ * \param _pg_user points to the user data that will be encoded in _pg_pkt
+ */
+void encodeTransmuter_ThrottleControlLoopSettingsPacketStructure(void* _pg_pkt, const Transmuter_ThrottleControlLoopSettings_t* _pg_user)
+{
+ uint8_t* _pg_data = getTransmuterPacketData(_pg_pkt);
+ int _pg_byteindex = 0;
+
+ // Range of Kp is 0.0f to 50.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->Kp, _pg_data, &_pg_byteindex, 0.0f, 1310.7f);
+
+ // Range of Ki is 0.0f to 50.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->Ki, _pg_data, &_pg_byteindex, 0.0f, 1310.7f);
+
+ // Range of Kd is 0.0f to 50.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->Kd, _pg_data, &_pg_byteindex, 0.0f, 1310.7f);
+
+ // Range of Kf is 0.0f to 50.0f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->Kf, _pg_data, &_pg_byteindex, 0.0f, 1310.7f);
+
+ // Minimum engine throttle position
+ // Range of throttleMin is 0 to 255.
+ uint8ToBytes(_pg_user->throttleMin, _pg_data, &_pg_byteindex);
+
+ // Maximum engine throttle position
+ // Range of throttleMax is 0 to 255.
+ uint8ToBytes(_pg_user->throttleMax, _pg_data, &_pg_byteindex);
+
+ // Maximum throttle slew rate
+ // Range of slewLimit is 0 to 65535.
+ uint16ToBeBytes(_pg_user->slewLimit, _pg_data, &_pg_byteindex);
+
+ // Throttle command low pass filter corner frequency
+ // Range of throttleFilterHz is 0.0f to 65.535f.
+ float32ScaledTo2UnsignedBeBytes(_pg_user->throttleFilterHz, _pg_data, &_pg_byteindex, 0.0f, 1000.0f);
+
+ // complete the process of creating the packet
+ finishTransmuterPacket(_pg_pkt, _pg_byteindex, getTransmuter_ThrottleControlLoopSettingsPacketID());
+
+}// encodeTransmuter_ThrottleControlLoopSettingsPacketStructure
+
+/*!
+ * \brief Decode the Transmuter_ThrottleControlLoopSettings packet
+ *
+ * Engine throttle control loop settings
+ * \param _pg_pkt points to the packet being decoded by this function
+ * \param _pg_user receives the data decoded from the packet
+ * \return 0 is returned if the packet ID or size is wrong, else 1
+ */
+int decodeTransmuter_ThrottleControlLoopSettingsPacketStructure(const void* _pg_pkt, Transmuter_ThrottleControlLoopSettings_t* _pg_user)
+{
+ int _pg_numbytes;
+ int _pg_byteindex = 0;
+ const uint8_t* _pg_data;
+
+ // Verify the packet identifier
+ if(getTransmuterPacketID(_pg_pkt) != getTransmuter_ThrottleControlLoopSettingsPacketID())
+ return 0;
+
+ // Verify the packet size
+ _pg_numbytes = getTransmuterPacketSize(_pg_pkt);
+ if(_pg_numbytes < getTransmuter_ThrottleControlLoopSettingsMinDataLength())
+ return 0;
+
+ // The raw data from the packet
+ _pg_data = getTransmuterPacketDataConst(_pg_pkt);
+
+ // this packet has default fields, make sure they are set
+ _pg_user->throttleFilterHz = 1.0f;
+
+ // Range of Kp is 0.0f to 50.0f.
+ _pg_user->Kp = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1310.7f);
+
+ // Range of Ki is 0.0f to 50.0f.
+ _pg_user->Ki = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1310.7f);
+
+ // Range of Kd is 0.0f to 50.0f.
+ _pg_user->Kd = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1310.7f);
+
+ // Range of Kf is 0.0f to 50.0f.
+ _pg_user->Kf = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1310.7f);
+
+ // Minimum engine throttle position
+ // Range of throttleMin is 0 to 255.
+ _pg_user->throttleMin = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Maximum engine throttle position
+ // Range of throttleMax is 0 to 255.
+ _pg_user->throttleMax = uint8FromBytes(_pg_data, &_pg_byteindex);
+
+ // Maximum throttle slew rate
+ // Range of slewLimit is 0 to 65535.
+ _pg_user->slewLimit = uint16FromBeBytes(_pg_data, &_pg_byteindex);
+
+ if(_pg_byteindex + 2 > _pg_numbytes)
+ return 1;
+
+ // Throttle command low pass filter corner frequency
+ // Range of throttleFilterHz is 0.0f to 65.535f.
+ _pg_user->throttleFilterHz = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/1000.0f);
+
+ return 1;
+
+}// decodeTransmuter_ThrottleControlLoopSettingsPacketStructure
+
+/*!
+ * \brief Verify a Transmuter_ThrottleControlLoopSettings_t has acceptable values.
+ *
+ * Verify a Transmuter_ThrottleControlLoopSettings_t has acceptable values. Not all fields are
+ * verified, only those which the protocol specifies. Fields which are outside
+ * the allowable range are changed to the maximum or minimum allowable value.
+ * \param _pg_user is the structure whose data are verified
+ * \return 1 if all verifiable data where valid, else 0 if data had to be corrected
+ */
+int verifyTransmuter_ThrottleControlLoopSettings_t(Transmuter_ThrottleControlLoopSettings_t* _pg_user)
+{
+ int _pg_good = 1;
+
+ if(_pg_user->Kp < 0.0f)
+ {
+ _pg_user->Kp = 0.0f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->Kp > 50.0f)
+ {
+ _pg_user->Kp = 50.0f;
+ _pg_good = 0;
+ }
+
+ if(_pg_user->Ki < 0.0f)
+ {
+ _pg_user->Ki = 0.0f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->Ki > 50.0f)
+ {
+ _pg_user->Ki = 50.0f;
+ _pg_good = 0;
+ }
+
+ if(_pg_user->Kd < 0.0f)
+ {
+ _pg_user->Kd = 0.0f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->Kd > 50.0f)
+ {
+ _pg_user->Kd = 50.0f;
+ _pg_good = 0;
+ }
+
+ if(_pg_user->Kf < 0.0f)
+ {
+ _pg_user->Kf = 0.0f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->Kf > 50.0f)
+ {
+ _pg_user->Kf = 50.0f;
+ _pg_good = 0;
+ }
+
+ // Minimum engine throttle position
+ if(_pg_user->throttleMin > 100)
+ {
+ _pg_user->throttleMin = 100;
+ _pg_good = 0;
+ }
+
+ // Maximum engine throttle position
+ if(_pg_user->throttleMax > 100)
+ {
+ _pg_user->throttleMax = 100;
+ _pg_good = 0;
+ }
+
+ // Maximum throttle slew rate
+ if(_pg_user->slewLimit < 10)
+ {
+ _pg_user->slewLimit = 10;
+ _pg_good = 0;
+ }
+ else if(_pg_user->slewLimit > 1000)
+ {
+ _pg_user->slewLimit = 1000;
+ _pg_good = 0;
+ }
+
+ // Throttle command low pass filter corner frequency
+ if(_pg_user->throttleFilterHz < 0.01f)
+ {
+ _pg_user->throttleFilterHz = 0.01f;
+ _pg_good = 0;
+ }
+ else if(_pg_user->throttleFilterHz > 50.0f)
+ {
+ _pg_user->throttleFilterHz = 50.0f;
+ _pg_good = 0;
+ }
+
+ return _pg_good;
+
+}// verifyTransmuter_ThrottleControlLoopSettings_t
+
+// end of TransmuterPackets.c
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterPackets.h b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterPackets.h
new file mode 100644
index 0000000000..9199fb3f66
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterPackets.h
@@ -0,0 +1,709 @@
+// TransmuterPackets.h was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#ifndef _TRANSMUTERPACKETS_H
+#define _TRANSMUTERPACKETS_H
+
+// Language target is C, C++ compilers: don't mangle us
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ */
+
+#include
+#include
+#include "TransmuterProtocol.h"
+#include "TransmuterDefines.h"
+
+//! Create the Transmuter_EnterStandby packet from parameters
+void encodeTransmuter_EnterStandbyPacket(void* pkt);
+
+//! Decode the Transmuter_EnterStandby packet to parameters
+int decodeTransmuter_EnterStandbyPacket(const void* pkt);
+
+//! return the packet ID for the Transmuter_EnterStandby packet
+#define getTransmuter_EnterStandbyPacketID() (PKT_TRANSMUTER_STANDBY)
+
+//! return the minimum encoded length for the Transmuter_EnterStandby packet
+#define getTransmuter_EnterStandbyMinDataLength() (2)
+
+//! return the maximum encoded length for the Transmuter_EnterStandby packet
+#define getTransmuter_EnterStandbyMaxDataLength() (2)
+
+//! Create the Transmuter_EnterPreflight packet from parameters
+void encodeTransmuter_EnterPreflightPacket(void* pkt);
+
+//! Decode the Transmuter_EnterPreflight packet to parameters
+int decodeTransmuter_EnterPreflightPacket(const void* pkt);
+
+//! return the packet ID for the Transmuter_EnterPreflight packet
+#define getTransmuter_EnterPreflightPacketID() (PKT_TRANSMUTER_PREFLIGHT)
+
+//! return the minimum encoded length for the Transmuter_EnterPreflight packet
+#define getTransmuter_EnterPreflightMinDataLength() (2)
+
+//! return the maximum encoded length for the Transmuter_EnterPreflight packet
+#define getTransmuter_EnterPreflightMaxDataLength() (2)
+
+//! Create the Transmuter_EnterWarmup packet from parameters
+void encodeTransmuter_EnterWarmupPacket(void* pkt);
+
+//! Decode the Transmuter_EnterWarmup packet to parameters
+int decodeTransmuter_EnterWarmupPacket(const void* pkt);
+
+//! return the packet ID for the Transmuter_EnterWarmup packet
+#define getTransmuter_EnterWarmupPacketID() (PKT_TRANSMUTER_WARMUP)
+
+//! return the minimum encoded length for the Transmuter_EnterWarmup packet
+#define getTransmuter_EnterWarmupMinDataLength() (2)
+
+//! return the maximum encoded length for the Transmuter_EnterWarmup packet
+#define getTransmuter_EnterWarmupMaxDataLength() (2)
+
+//! Create the Transmuter_EnterRunMode packet from parameters
+void encodeTransmuter_EnterRunModePacket(void* pkt);
+
+//! Decode the Transmuter_EnterRunMode packet to parameters
+int decodeTransmuter_EnterRunModePacket(const void* pkt);
+
+//! return the packet ID for the Transmuter_EnterRunMode packet
+#define getTransmuter_EnterRunModePacketID() (PKT_TRANSMUTER_RUN)
+
+//! return the minimum encoded length for the Transmuter_EnterRunMode packet
+#define getTransmuter_EnterRunModeMinDataLength() (2)
+
+//! return the maximum encoded length for the Transmuter_EnterRunMode packet
+#define getTransmuter_EnterRunModeMaxDataLength() (2)
+
+//! Create the Transmuter_EnterPWMMode packet from parameters
+void encodeTransmuter_EnterPWMModePacket(void* pkt);
+
+//! Decode the Transmuter_EnterPWMMode packet to parameters
+int decodeTransmuter_EnterPWMModePacket(const void* pkt);
+
+//! return the packet ID for the Transmuter_EnterPWMMode packet
+#define getTransmuter_EnterPWMModePacketID() (PKT_TRANSMUTER_PWM)
+
+//! return the minimum encoded length for the Transmuter_EnterPWMMode packet
+#define getTransmuter_EnterPWMModeMinDataLength() (2)
+
+//! return the maximum encoded length for the Transmuter_EnterPWMMode packet
+#define getTransmuter_EnterPWMModeMaxDataLength() (2)
+
+/*!
+ * The TelemetryStatus packet contains critical operational status information
+ * pertaining to the current state of the Transmuter
+ */
+typedef struct
+{
+ Transmuter_StatusBits_t status;
+ Transmuter_WarningBits_t warning;
+ Transmuter_ErrorBits_t errors;
+}Transmuter_TelemetryStatus_t;
+
+//! Create the Transmuter_TelemetryStatus packet
+void encodeTransmuter_TelemetryStatusPacketStructure(void* pkt, const Transmuter_TelemetryStatus_t* user);
+
+//! Decode the Transmuter_TelemetryStatus packet
+int decodeTransmuter_TelemetryStatusPacketStructure(const void* pkt, Transmuter_TelemetryStatus_t* user);
+
+//! Create the Transmuter_TelemetryStatus packet from parameters
+void encodeTransmuter_TelemetryStatusPacket(void* pkt, const Transmuter_StatusBits_t* status, const Transmuter_WarningBits_t* warning, const Transmuter_ErrorBits_t* errors);
+
+//! Decode the Transmuter_TelemetryStatus packet to parameters
+int decodeTransmuter_TelemetryStatusPacket(const void* pkt, Transmuter_StatusBits_t* status, Transmuter_WarningBits_t* warning, Transmuter_ErrorBits_t* errors);
+
+//! return the packet ID for the Transmuter_TelemetryStatus packet
+#define getTransmuter_TelemetryStatusPacketID() (PKT_TRANSMUTER_TELEMETRY_STATUS)
+
+//! return the minimum encoded length for the Transmuter_TelemetryStatus packet
+#define getTransmuter_TelemetryStatusMinDataLength() (8)
+
+//! return the maximum encoded length for the Transmuter_TelemetryStatus packet
+#define getTransmuter_TelemetryStatusMaxDataLength() (8)
+
+/*!
+ * The TelemetryPower packet contains information on the current operation
+ * point of the engine and generator
+ */
+typedef struct
+{
+ float voltage; //!< System voltage
+ float genCurrent; //!< Generator current
+ float batCurrent; //!< Battery current
+ int16_t rpm; //!< Mechanical rotational speed
+}Transmuter_TelemetryPower_t;
+
+//! Create the Transmuter_TelemetryPower packet
+void encodeTransmuter_TelemetryPowerPacketStructure(void* pkt, const Transmuter_TelemetryPower_t* user);
+
+//! Decode the Transmuter_TelemetryPower packet
+int decodeTransmuter_TelemetryPowerPacketStructure(const void* pkt, Transmuter_TelemetryPower_t* user);
+
+//! Create the Transmuter_TelemetryPower packet from parameters
+void encodeTransmuter_TelemetryPowerPacket(void* pkt, float voltage, float genCurrent, float batCurrent, int16_t rpm);
+
+//! Decode the Transmuter_TelemetryPower packet to parameters
+int decodeTransmuter_TelemetryPowerPacket(const void* pkt, float* voltage, float* genCurrent, float* batCurrent, int16_t* rpm);
+
+//! return the packet ID for the Transmuter_TelemetryPower packet
+#define getTransmuter_TelemetryPowerPacketID() (PKT_TRANSMUTER_TELEMETRY_POWER)
+
+//! return the minimum encoded length for the Transmuter_TelemetryPower packet
+#define getTransmuter_TelemetryPowerMinDataLength() (8)
+
+//! return the maximum encoded length for the Transmuter_TelemetryPower packet
+#define getTransmuter_TelemetryPowerMaxDataLength() (8)
+
+/*!
+ * The TelemetrySetpoint packet contains system setpoint/target information
+ */
+typedef struct
+{
+ float currentSetpoint; //!< Battery current setpoint value
+ int16_t rpmTarget; //!< System RPM target
+ uint8_t throttleTarget; //!< ECU throttle target
+ int16_t powerTarget; //!< Generator power target
+}Transmuter_TelemetrySetpoint_t;
+
+//! Create the Transmuter_TelemetrySetpoint packet
+void encodeTransmuter_TelemetrySetpointPacketStructure(void* pkt, const Transmuter_TelemetrySetpoint_t* user);
+
+//! Decode the Transmuter_TelemetrySetpoint packet
+int decodeTransmuter_TelemetrySetpointPacketStructure(const void* pkt, Transmuter_TelemetrySetpoint_t* user);
+
+//! Create the Transmuter_TelemetrySetpoint packet from parameters
+void encodeTransmuter_TelemetrySetpointPacket(void* pkt, float currentSetpoint, int16_t rpmTarget, uint8_t throttleTarget, int16_t powerTarget);
+
+//! Decode the Transmuter_TelemetrySetpoint packet to parameters
+int decodeTransmuter_TelemetrySetpointPacket(const void* pkt, float* currentSetpoint, int16_t* rpmTarget, uint8_t* throttleTarget, int16_t* powerTarget);
+
+//! return the packet ID for the Transmuter_TelemetrySetpoint packet
+#define getTransmuter_TelemetrySetpointPacketID() (PKT_TRANSMUTER_TELEMETRY_SETPOINT)
+
+//! return the minimum encoded length for the Transmuter_TelemetrySetpoint packet
+#define getTransmuter_TelemetrySetpointMinDataLength() (7)
+
+//! return the maximum encoded length for the Transmuter_TelemetrySetpoint packet
+#define getTransmuter_TelemetrySetpointMaxDataLength() (7)
+
+/*!
+ * The TelemetryGenerator packet provides information about the current
+ * operational status of the generator and EFI system.
+ */
+typedef struct
+{
+ uint8_t fetTemperature; //!< Power electronics module temperature
+ uint8_t motTemperature; //!< Generator motor temperature
+ uint8_t chtTemperature; //!< Engine cylinder head temperature
+ float fuelPressure; //!< Fuel pressure
+}Transmuter_TelemetryGenerator_t;
+
+//! Create the Transmuter_TelemetryGenerator packet
+void encodeTransmuter_TelemetryGeneratorPacketStructure(void* pkt, const Transmuter_TelemetryGenerator_t* user);
+
+//! Decode the Transmuter_TelemetryGenerator packet
+int decodeTransmuter_TelemetryGeneratorPacketStructure(const void* pkt, Transmuter_TelemetryGenerator_t* user);
+
+//! Create the Transmuter_TelemetryGenerator packet from parameters
+void encodeTransmuter_TelemetryGeneratorPacket(void* pkt, uint8_t fetTemperature, uint8_t motTemperature, uint8_t chtTemperature, float fuelPressure);
+
+//! Decode the Transmuter_TelemetryGenerator packet to parameters
+int decodeTransmuter_TelemetryGeneratorPacket(const void* pkt, uint8_t* fetTemperature, uint8_t* motTemperature, uint8_t* chtTemperature, float* fuelPressure);
+
+//! return the packet ID for the Transmuter_TelemetryGenerator packet
+#define getTransmuter_TelemetryGeneratorPacketID() (PKT_TRANSMUTER_TELEMETRY_GEN)
+
+//! return the minimum encoded length for the Transmuter_TelemetryGenerator packet
+#define getTransmuter_TelemetryGeneratorMinDataLength() (5)
+
+//! return the maximum encoded length for the Transmuter_TelemetryGenerator packet
+#define getTransmuter_TelemetryGeneratorMaxDataLength() (5)
+
+/*!
+ * The TelemetryCapacity packet provides information on the battery and fuel
+ * capacity
+ */
+typedef struct
+{
+ uint32_t fuelUsed; //!< Fuel used estimate
+}Transmuter_TelemetryCapacity_t;
+
+//! Create the Transmuter_TelemetryCapacity packet
+void encodeTransmuter_TelemetryCapacityPacketStructure(void* pkt, const Transmuter_TelemetryCapacity_t* user);
+
+//! Decode the Transmuter_TelemetryCapacity packet
+int decodeTransmuter_TelemetryCapacityPacketStructure(const void* pkt, Transmuter_TelemetryCapacity_t* user);
+
+//! Create the Transmuter_TelemetryCapacity packet from parameters
+void encodeTransmuter_TelemetryCapacityPacket(void* pkt, uint32_t fuelUsed);
+
+//! Decode the Transmuter_TelemetryCapacity packet to parameters
+int decodeTransmuter_TelemetryCapacityPacket(const void* pkt, uint32_t* fuelUsed);
+
+//! return the packet ID for the Transmuter_TelemetryCapacity packet
+#define getTransmuter_TelemetryCapacityPacketID() (PKT_TRANSMUTER_TELEMETRY_CAPACITY)
+
+//! return the minimum encoded length for the Transmuter_TelemetryCapacity packet
+#define getTransmuter_TelemetryCapacityMinDataLength() (4)
+
+//! return the maximum encoded length for the Transmuter_TelemetryCapacity packet
+#define getTransmuter_TelemetryCapacityMaxDataLength() (4)
+
+/*!
+ * Current state of the transmuter current control loop
+ */
+typedef struct
+{
+ float pTerm;
+ float iTerm;
+ float dTerm;
+ float fTerm;
+}Transmuter_TelemetryControlLoop_t;
+
+//! Create the Transmuter_TelemetryControlLoop packet
+void encodeTransmuter_TelemetryControlLoopPacketStructure(void* pkt, const Transmuter_TelemetryControlLoop_t* user);
+
+//! Decode the Transmuter_TelemetryControlLoop packet
+int decodeTransmuter_TelemetryControlLoopPacketStructure(const void* pkt, Transmuter_TelemetryControlLoop_t* user);
+
+//! Create the Transmuter_TelemetryControlLoop packet from parameters
+void encodeTransmuter_TelemetryControlLoopPacket(void* pkt, float pTerm, float iTerm, float dTerm, float fTerm);
+
+//! Decode the Transmuter_TelemetryControlLoop packet to parameters
+int decodeTransmuter_TelemetryControlLoopPacket(const void* pkt, float* pTerm, float* iTerm, float* dTerm, float* fTerm);
+
+//! return the packet ID for the Transmuter_TelemetryControlLoop packet
+#define getTransmuter_TelemetryControlLoopPacketID() (PKT_TRANSMUTER_TELEMETRY_CTRL_LOOP)
+
+//! return the minimum encoded length for the Transmuter_TelemetryControlLoop packet
+#define getTransmuter_TelemetryControlLoopMinDataLength() (8)
+
+//! return the maximum encoded length for the Transmuter_TelemetryControlLoop packet
+#define getTransmuter_TelemetryControlLoopMaxDataLength() (8)
+
+/*!
+ * Power information for the Auxilary Power Board
+ */
+typedef struct
+{
+ float apbVoltage; //!< APB output voltage (V)
+ float apbCurrent; //!< APB output current (A)
+}Transmuter_TelemetryAPBPower_t;
+
+//! Create the Transmuter_TelemetryAPBPower packet
+void encodeTransmuter_TelemetryAPBPowerPacketStructure(void* pkt, const Transmuter_TelemetryAPBPower_t* user);
+
+//! Decode the Transmuter_TelemetryAPBPower packet
+int decodeTransmuter_TelemetryAPBPowerPacketStructure(const void* pkt, Transmuter_TelemetryAPBPower_t* user);
+
+//! Create the Transmuter_TelemetryAPBPower packet from parameters
+void encodeTransmuter_TelemetryAPBPowerPacket(void* pkt, float apbVoltage, float apbCurrent);
+
+//! Decode the Transmuter_TelemetryAPBPower packet to parameters
+int decodeTransmuter_TelemetryAPBPowerPacket(const void* pkt, float* apbVoltage, float* apbCurrent);
+
+//! return the packet ID for the Transmuter_TelemetryAPBPower packet
+#define getTransmuter_TelemetryAPBPowerPacketID() (PKT_TRANSMUTER_TELEMETRY_APB)
+
+//! return the minimum encoded length for the Transmuter_TelemetryAPBPower packet
+#define getTransmuter_TelemetryAPBPowerMinDataLength() (4)
+
+//! return the maximum encoded length for the Transmuter_TelemetryAPBPower packet
+#define getTransmuter_TelemetryAPBPowerMaxDataLength() (4)
+
+// Initial and verify values for WarningLevels
+#define Transmuter_WarningLevels_engineTemp_InitValue 140
+#define Transmuter_WarningLevels_engineTemp_VerifyMin 50
+
+/*!
+ * Warning level configuration values
+ */
+typedef struct
+{
+ uint8_t engineTemp; //!< Engine (CHT) temperature warning level
+}Transmuter_WarningLevels_t;
+
+//! Set a Transmuter_WarningLevels_t to initial values
+void initTransmuter_WarningLevels_t(Transmuter_WarningLevels_t* user);
+
+//! Create the Transmuter_WarningLevels packet
+void encodeTransmuter_WarningLevelsPacketStructure(void* pkt, const Transmuter_WarningLevels_t* user);
+
+//! Decode the Transmuter_WarningLevels packet
+int decodeTransmuter_WarningLevelsPacketStructure(const void* pkt, Transmuter_WarningLevels_t* user);
+
+//! Create the Transmuter_WarningLevels packet from parameters
+void encodeTransmuter_WarningLevelsPacket(void* pkt, uint8_t engineTemp);
+
+//! Decode the Transmuter_WarningLevels packet to parameters
+int decodeTransmuter_WarningLevelsPacket(const void* pkt, uint8_t* engineTemp);
+
+//! Verify a Transmuter_WarningLevels_t has acceptable values
+int verifyTransmuter_WarningLevels_t(Transmuter_WarningLevels_t* user);
+
+//! return the packet ID for the Transmuter_WarningLevels packet
+#define getTransmuter_WarningLevelsPacketID() (PKT_TRANSMUTER_WARNING_LEVELS)
+
+//! return the minimum encoded length for the Transmuter_WarningLevels packet
+#define getTransmuter_WarningLevelsMinDataLength() (1)
+
+//! return the maximum encoded length for the Transmuter_WarningLevels packet
+#define getTransmuter_WarningLevelsMaxDataLength() (1)
+
+// Initial and verify values for EFISettings
+#define Transmuter_EFISettings_ecuAddress_InitValue 200
+#define Transmuter_EFISettings_ecuAddress_VerifyMax 254
+#define Transmuter_EFISettings_triplexAddress_InitValue 201
+#define Transmuter_EFISettings_triplexAddress_VerifyMax 254
+#define Transmuter_EFISettings_fuelPressureMin_InitValue 5.0f
+#define Transmuter_EFISettings_fuelPressureMin_VerifyMin 1.0f
+#define Transmuter_EFISettings_fuelPressureMin_VerifyMax 25.0f
+
+/*!
+ * ECU connection configuration packet
+ */
+typedef struct
+{
+ uint8_t ecuAddress; //!< CAN Node ID for the ECU
+ uint16_t ecuFirmwareChecksum; //!< ECU firmware checksum
+ uint16_t ecuSettingsChecksum; //!< ECU settings checksum
+ uint8_t triplexAddress; //!< CAN Node ID for the triplex pump
+ uint16_t triplexFirmwareChecksum; //!< Triplex pump firmware checksum
+ float fuelPressureMin; //!< Minimum required fuel pressure
+ uint8_t pumpController; //!< Fuel pressure control method
+}Transmuter_EFISettings_t;
+
+//! Set a Transmuter_EFISettings_t to initial values
+void initTransmuter_EFISettings_t(Transmuter_EFISettings_t* user);
+
+//! Create the Transmuter_EFISettings packet
+void encodeTransmuter_EFISettingsPacketStructure(void* pkt, const Transmuter_EFISettings_t* user);
+
+//! Decode the Transmuter_EFISettings packet
+int decodeTransmuter_EFISettingsPacketStructure(const void* pkt, Transmuter_EFISettings_t* user);
+
+//! Create the Transmuter_EFISettings packet from parameters
+void encodeTransmuter_EFISettingsPacket(void* pkt, uint8_t ecuAddress, uint16_t ecuFirmwareChecksum, uint16_t ecuSettingsChecksum, uint8_t triplexAddress, uint16_t triplexFirmwareChecksum, float fuelPressureMin, uint8_t pumpController);
+
+//! Decode the Transmuter_EFISettings packet to parameters
+int decodeTransmuter_EFISettingsPacket(const void* pkt, uint8_t* ecuAddress, uint16_t* ecuFirmwareChecksum, uint16_t* ecuSettingsChecksum, uint8_t* triplexAddress, uint16_t* triplexFirmwareChecksum, float* fuelPressureMin, uint8_t* pumpController);
+
+//! Verify a Transmuter_EFISettings_t has acceptable values
+int verifyTransmuter_EFISettings_t(Transmuter_EFISettings_t* user);
+
+//! return the packet ID for the Transmuter_EFISettings packet
+#define getTransmuter_EFISettingsPacketID() (PKT_TRANSMUTER_EFI_CONFIG)
+
+//! return the minimum encoded length for the Transmuter_EFISettings packet
+#define getTransmuter_EFISettingsMinDataLength() (10)
+
+//! return the maximum encoded length for the Transmuter_EFISettings packet
+#define getTransmuter_EFISettingsMaxDataLength() (11)
+
+// Initial and verify values for GeneratorSettings
+#define Transmuter_GeneratorSettings_beltRatio_InitValue 1.0f
+#define Transmuter_GeneratorSettings_beltRatio_VerifyMin 0.1f
+#define Transmuter_GeneratorSettings_beltRatio_VerifyMax 10.0f
+#define Transmuter_GeneratorSettings_rpmThreshold_InitValue 350
+#define Transmuter_GeneratorSettings_rpmThreshold_VerifyMax 5000
+#define Transmuter_GeneratorSettings_powerLossTimeout_InitValue 25
+
+/*!
+ * Generator motor parameters
+ */
+typedef struct
+{
+ float beltRatio; //!< Belt ratio between engine and generator motor
+ uint16_t rpmThreshold; //!< Allowable RPM measurement difference between generator and engine
+ uint8_t powerLossTimeout; //!< Timeout before system disables due to engine power loss. Set to zero to disable timeout
+}Transmuter_GeneratorSettings_t;
+
+//! Set a Transmuter_GeneratorSettings_t to initial values
+void initTransmuter_GeneratorSettings_t(Transmuter_GeneratorSettings_t* user);
+
+//! Create the Transmuter_GeneratorSettings packet
+void encodeTransmuter_GeneratorSettingsPacketStructure(void* pkt, const Transmuter_GeneratorSettings_t* user);
+
+//! Decode the Transmuter_GeneratorSettings packet
+int decodeTransmuter_GeneratorSettingsPacketStructure(const void* pkt, Transmuter_GeneratorSettings_t* user);
+
+//! Create the Transmuter_GeneratorSettings packet from parameters
+void encodeTransmuter_GeneratorSettingsPacket(void* pkt, float beltRatio, uint16_t rpmThreshold, uint8_t powerLossTimeout);
+
+//! Decode the Transmuter_GeneratorSettings packet to parameters
+int decodeTransmuter_GeneratorSettingsPacket(const void* pkt, float* beltRatio, uint16_t* rpmThreshold, uint8_t* powerLossTimeout);
+
+//! Verify a Transmuter_GeneratorSettings_t has acceptable values
+int verifyTransmuter_GeneratorSettings_t(Transmuter_GeneratorSettings_t* user);
+
+//! return the packet ID for the Transmuter_GeneratorSettings packet
+#define getTransmuter_GeneratorSettingsPacketID() (PKT_TRANSMUTER_GEN_CONFIG)
+
+//! return the minimum encoded length for the Transmuter_GeneratorSettings packet
+#define getTransmuter_GeneratorSettingsMinDataLength() (5)
+
+//! return the maximum encoded length for the Transmuter_GeneratorSettings packet
+#define getTransmuter_GeneratorSettingsMaxDataLength() (5)
+
+// Initial and verify values for StartingSettings
+#define Transmuter_StartingSettings_retries_InitValue 3
+#define Transmuter_StartingSettings_retries_VerifyMax 50
+#define Transmuter_StartingSettings_timeout_InitValue 50
+#define Transmuter_StartingSettings_timeout_VerifyMin 1
+#define Transmuter_StartingSettings_rpm_InitValue 3000
+#define Transmuter_StartingSettings_rpm_VerifyMin 500
+#define Transmuter_StartingSettings_rpm_VerifyMax 25000
+#define Transmuter_StartingSettings_throttle_InitValue 25
+#define Transmuter_StartingSettings_throttle_VerifyMax 100
+#define Transmuter_StartingSettings_settlingPeriod_InitValue 25
+#define Transmuter_StartingSettings_settlingPeriod_VerifyMin 10
+#define Transmuter_StartingSettings_settlingPeriod_VerifyMax 250
+
+/*!
+ * Engine starting settings
+ */
+typedef struct
+{
+ uint8_t retries; //!< Number of auto-retries allowed for engine starting routine
+ uint8_t timeout; //!< Timeout for engine starting routine
+ uint16_t rpm; //!< Starting RPM value
+ uint8_t throttle; //!< Starting throttle position
+ uint8_t settlingPeriod; //!< Settling time after reaching starting RPM
+}Transmuter_StartingSettings_t;
+
+//! Set a Transmuter_StartingSettings_t to initial values
+void initTransmuter_StartingSettings_t(Transmuter_StartingSettings_t* user);
+
+//! Create the Transmuter_StartingSettings packet
+void encodeTransmuter_StartingSettingsPacketStructure(void* pkt, const Transmuter_StartingSettings_t* user);
+
+//! Decode the Transmuter_StartingSettings packet
+int decodeTransmuter_StartingSettingsPacketStructure(const void* pkt, Transmuter_StartingSettings_t* user);
+
+//! Create the Transmuter_StartingSettings packet from parameters
+void encodeTransmuter_StartingSettingsPacket(void* pkt, uint8_t retries, uint8_t timeout, uint16_t rpm, uint8_t throttle, uint8_t settlingPeriod);
+
+//! Decode the Transmuter_StartingSettings packet to parameters
+int decodeTransmuter_StartingSettingsPacket(const void* pkt, uint8_t* retries, uint8_t* timeout, uint16_t* rpm, uint8_t* throttle, uint8_t* settlingPeriod);
+
+//! Verify a Transmuter_StartingSettings_t has acceptable values
+int verifyTransmuter_StartingSettings_t(Transmuter_StartingSettings_t* user);
+
+//! return the packet ID for the Transmuter_StartingSettings packet
+#define getTransmuter_StartingSettingsPacketID() (PKT_TRANSMUTER_STARTING_SETTINGS)
+
+//! return the minimum encoded length for the Transmuter_StartingSettings packet
+#define getTransmuter_StartingSettingsMinDataLength() (6)
+
+//! return the maximum encoded length for the Transmuter_StartingSettings packet
+#define getTransmuter_StartingSettingsMaxDataLength() (6)
+
+// Initial and verify values for PowerMap
+#define Transmuter_PowerMap_size_VerifyMin 2
+#define Transmuter_PowerMap_size_VerifyMax 15
+#define Transmuter_PowerMap_power_VerifyMin 0
+#define Transmuter_PowerMap_power_VerifyMax 25000
+#define Transmuter_PowerMap_rpm_VerifyMin 0
+#define Transmuter_PowerMap_rpm_VerifyMax 25000
+#define Transmuter_PowerMap_powerFilterHz_InitValue 1.0f
+#define Transmuter_PowerMap_powerFilterHz_VerifyMin 0.01f
+#define Transmuter_PowerMap_powerFilterHz_VerifyMax 50.0f
+
+/*!
+ * Configuration of transmuter power map lookup table
+ */
+typedef struct
+{
+ uint8_t size;
+ int16_t power[15]; //!< Power Input (W)
+ int16_t rpm[15]; //!< Speed Output (RPM)
+ float powerFilterHz; //!< Power demand low pass filter corner frequency
+}Transmuter_PowerMap_t;
+
+//! Set a Transmuter_PowerMap_t to initial values
+void initTransmuter_PowerMap_t(Transmuter_PowerMap_t* user);
+
+//! Create the Transmuter_PowerMap packet
+void encodeTransmuter_PowerMapPacketStructure(void* pkt, const Transmuter_PowerMap_t* user);
+
+//! Decode the Transmuter_PowerMap packet
+int decodeTransmuter_PowerMapPacketStructure(const void* pkt, Transmuter_PowerMap_t* user);
+
+//! Verify a Transmuter_PowerMap_t has acceptable values
+int verifyTransmuter_PowerMap_t(Transmuter_PowerMap_t* user);
+
+//! return the packet ID for the Transmuter_PowerMap packet
+#define getTransmuter_PowerMapPacketID() (PKT_TRANSMUTER_POWER_MAP)
+
+//! return the minimum encoded length for the Transmuter_PowerMap packet
+#define getTransmuter_PowerMapMinDataLength() (1)
+
+//! return the maximum encoded length for the Transmuter_PowerMap packet
+#define getTransmuter_PowerMapMaxDataLength() (63)
+
+// Initial and verify values for BatterySettings
+#define Transmuter_BatterySettings_nominalVoltage_InitValue 48
+#define Transmuter_BatterySettings_nominalVoltage_VerifyMin 20
+#define Transmuter_BatterySettings_nominalVoltage_VerifyMax 100
+#define Transmuter_BatterySettings_chargingCurrent_InitValue 5
+#define Transmuter_BatterySettings_capacity_InitValue 5000
+#define Transmuter_BatterySettings_currentScaler_InitValue 1.0f
+#define Transmuter_BatterySettings_currentScaler_VerifyMin 0.75f
+#define Transmuter_BatterySettings_currentScaler_VerifyMax 1.25f
+#define Transmuter_BatterySettings_currentOffset_InitValue 0.0f
+
+/*!
+ * Configuration of battery charging parameters
+ */
+typedef struct
+{
+ float nominalVoltage;
+ float chargingCurrent;
+ uint16_t capacity; //!< Battery capacity
+ float currentScaler; //!< Battery current measurement scaler value
+ float currentOffset; //!< Battery current measurement offset value
+}Transmuter_BatterySettings_t;
+
+//! Set a Transmuter_BatterySettings_t to initial values
+void initTransmuter_BatterySettings_t(Transmuter_BatterySettings_t* user);
+
+//! Create the Transmuter_BatterySettings packet
+void encodeTransmuter_BatterySettingsPacketStructure(void* pkt, const Transmuter_BatterySettings_t* user);
+
+//! Decode the Transmuter_BatterySettings packet
+int decodeTransmuter_BatterySettingsPacketStructure(const void* pkt, Transmuter_BatterySettings_t* user);
+
+//! Create the Transmuter_BatterySettings packet from parameters
+void encodeTransmuter_BatterySettingsPacket(void* pkt, float nominalVoltage, float chargingCurrent, uint16_t capacity, float currentScaler, float currentOffset);
+
+//! Decode the Transmuter_BatterySettings packet to parameters
+int decodeTransmuter_BatterySettingsPacket(const void* pkt, float* nominalVoltage, float* chargingCurrent, uint16_t* capacity, float* currentScaler, float* currentOffset);
+
+//! Verify a Transmuter_BatterySettings_t has acceptable values
+int verifyTransmuter_BatterySettings_t(Transmuter_BatterySettings_t* user);
+
+//! return the packet ID for the Transmuter_BatterySettings packet
+#define getTransmuter_BatterySettingsPacketID() (PKT_TRANSMUTER_BATTERY_SETTINGS)
+
+//! return the minimum encoded length for the Transmuter_BatterySettings packet
+#define getTransmuter_BatterySettingsMinDataLength() (7)
+
+//! return the maximum encoded length for the Transmuter_BatterySettings packet
+#define getTransmuter_BatterySettingsMaxDataLength() (11)
+
+/*!
+ * Transmuter packet selection. Enable or disable various telemetry packets
+ */
+typedef struct
+{
+ Transmuter_TelemetryPackets_t packets; //!< Telemetry packet selection
+}Transmuter_TelemetrySettings_t;
+
+//! Set a Transmuter_TelemetrySettings_t to initial values
+void initTransmuter_TelemetrySettings_t(Transmuter_TelemetrySettings_t* user);
+
+//! Create the Transmuter_TelemetrySettings packet
+void encodeTransmuter_TelemetrySettingsPacketStructure(void* pkt, const Transmuter_TelemetrySettings_t* user);
+
+//! Decode the Transmuter_TelemetrySettings packet
+int decodeTransmuter_TelemetrySettingsPacketStructure(const void* pkt, Transmuter_TelemetrySettings_t* user);
+
+//! Create the Transmuter_TelemetrySettings packet from parameters
+void encodeTransmuter_TelemetrySettingsPacket(void* pkt, const Transmuter_TelemetryPackets_t* packets);
+
+//! Decode the Transmuter_TelemetrySettings packet to parameters
+int decodeTransmuter_TelemetrySettingsPacket(const void* pkt, Transmuter_TelemetryPackets_t* packets);
+
+//! return the packet ID for the Transmuter_TelemetrySettings packet
+#define getTransmuter_TelemetrySettingsPacketID() (PKT_TRANSMUTER_TELEMETRY_CONFIG)
+
+//! return the minimum encoded length for the Transmuter_TelemetrySettings packet
+#define getTransmuter_TelemetrySettingsMinDataLength() (1)
+
+//! return the maximum encoded length for the Transmuter_TelemetrySettings packet
+#define getTransmuter_TelemetrySettingsMaxDataLength() (1)
+
+// Initial and verify values for ThrottleControlLoopSettings
+#define Transmuter_ThrottleControlLoopSettings_Kp_InitValue 25
+#define Transmuter_ThrottleControlLoopSettings_Kp_VerifyMin 0.0f
+#define Transmuter_ThrottleControlLoopSettings_Kp_VerifyMax 50.0f
+#define Transmuter_ThrottleControlLoopSettings_Ki_InitValue 2.5
+#define Transmuter_ThrottleControlLoopSettings_Ki_VerifyMin 0.0f
+#define Transmuter_ThrottleControlLoopSettings_Ki_VerifyMax 50.0f
+#define Transmuter_ThrottleControlLoopSettings_Kd_InitValue 0
+#define Transmuter_ThrottleControlLoopSettings_Kd_VerifyMin 0.0f
+#define Transmuter_ThrottleControlLoopSettings_Kd_VerifyMax 50.0f
+#define Transmuter_ThrottleControlLoopSettings_Kf_InitValue 0
+#define Transmuter_ThrottleControlLoopSettings_Kf_VerifyMin 0.0f
+#define Transmuter_ThrottleControlLoopSettings_Kf_VerifyMax 50.0f
+#define Transmuter_ThrottleControlLoopSettings_throttleMin_InitValue 10
+#define Transmuter_ThrottleControlLoopSettings_throttleMin_VerifyMax 100
+#define Transmuter_ThrottleControlLoopSettings_throttleMax_InitValue 100
+#define Transmuter_ThrottleControlLoopSettings_throttleMax_VerifyMax 100
+#define Transmuter_ThrottleControlLoopSettings_slewLimit_InitValue 100
+#define Transmuter_ThrottleControlLoopSettings_slewLimit_VerifyMin 10
+#define Transmuter_ThrottleControlLoopSettings_slewLimit_VerifyMax 1000
+#define Transmuter_ThrottleControlLoopSettings_throttleFilterHz_InitValue 1.0f
+#define Transmuter_ThrottleControlLoopSettings_throttleFilterHz_VerifyMin 0.01f
+#define Transmuter_ThrottleControlLoopSettings_throttleFilterHz_VerifyMax 50.0f
+
+/*!
+ * Engine throttle control loop settings
+ */
+typedef struct
+{
+ float Kp;
+ float Ki;
+ float Kd;
+ float Kf;
+ uint8_t throttleMin; //!< Minimum engine throttle position
+ uint8_t throttleMax; //!< Maximum engine throttle position
+ uint16_t slewLimit; //!< Maximum throttle slew rate
+ float throttleFilterHz; //!< Throttle command low pass filter corner frequency
+}Transmuter_ThrottleControlLoopSettings_t;
+
+//! Set a Transmuter_ThrottleControlLoopSettings_t to initial values
+void initTransmuter_ThrottleControlLoopSettings_t(Transmuter_ThrottleControlLoopSettings_t* user);
+
+//! Create the Transmuter_ThrottleControlLoopSettings packet
+void encodeTransmuter_ThrottleControlLoopSettingsPacketStructure(void* pkt, const Transmuter_ThrottleControlLoopSettings_t* user);
+
+//! Decode the Transmuter_ThrottleControlLoopSettings packet
+int decodeTransmuter_ThrottleControlLoopSettingsPacketStructure(const void* pkt, Transmuter_ThrottleControlLoopSettings_t* user);
+
+//! Verify a Transmuter_ThrottleControlLoopSettings_t has acceptable values
+int verifyTransmuter_ThrottleControlLoopSettings_t(Transmuter_ThrottleControlLoopSettings_t* user);
+
+//! return the packet ID for the Transmuter_ThrottleControlLoopSettings packet
+#define getTransmuter_ThrottleControlLoopSettingsPacketID() (PKT_TRANSMUTER_CTRL_LOOP_SETTINGS)
+
+//! return the minimum encoded length for the Transmuter_ThrottleControlLoopSettings packet
+#define getTransmuter_ThrottleControlLoopSettingsMinDataLength() (12)
+
+//! return the maximum encoded length for the Transmuter_ThrottleControlLoopSettings packet
+#define getTransmuter_ThrottleControlLoopSettingsMaxDataLength() (14)
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _TRANSMUTERPACKETS_H
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterProtocol.c b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterProtocol.c
new file mode 100644
index 0000000000..24ede728d3
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterProtocol.c
@@ -0,0 +1,253 @@
+// TransmuterProtocol.c was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#include "TransmuterProtocol.h"
+
+/*!
+ * \brief Lookup label for 'TransmuterModes' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string label of the given entry
+ */
+const char* TransmuterModes_EnumLabel(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case TRANSMUTER_MODE_STARTUP:
+ return "TRANSMUTER_MODE_STARTUP";
+ case TRANSMUTER_MODE_STANDBY:
+ return "TRANSMUTER_MODE_STANDBY";
+ case TRANSMUTER_MODE_PREFLIGHT:
+ return "TRANSMUTER_MODE_PREFLIGHT";
+ case TRANSMUTER_MODE_STARTING:
+ return "TRANSMUTER_MODE_STARTING";
+ case TRANSMUTER_MODE_WARMUP:
+ return "TRANSMUTER_MODE_WARMUP";
+ case TRANSMUTER_MODE_RPM:
+ return "TRANSMUTER_MODE_RPM";
+ case TRANSMUTER_MODE_CURRENT:
+ return "TRANSMUTER_MODE_CURRENT";
+ case TRANSMUTER_MODE_PWM:
+ return "TRANSMUTER_MODE_PWM";
+ case TRANSMUTER_MODE_NUM_MODES:
+ return "TRANSMUTER_MODE_NUM_MODES";
+ }
+}
+
+/*!
+ * \brief Lookup title for 'TransmuterModes' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string title of the given entry (comment if no title given)
+ */
+const char* TransmuterModes_EnumTitle(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case TRANSMUTER_MODE_STARTUP:
+ return "Initial powerup mode of the transmuter";
+ case TRANSMUTER_MODE_STANDBY:
+ return "Transmuter is in standby mode";
+ case TRANSMUTER_MODE_PREFLIGHT:
+ return "Transmuter is in preflight check mode";
+ case TRANSMUTER_MODE_STARTING:
+ return "Transmuter is attempting to start the engine";
+ case TRANSMUTER_MODE_WARMUP:
+ return "Transmuter is in warmup mode";
+ case TRANSMUTER_MODE_RPM:
+ return "Transmuter is running in RPM control mode";
+ case TRANSMUTER_MODE_CURRENT:
+ return "Transmuter is running in CURRENT control mode";
+ case TRANSMUTER_MODE_PWM:
+ return "Transmuter is running in PWM control mode";
+ case TRANSMUTER_MODE_NUM_MODES:
+ return "Number of transmuter operational modes";
+ }
+}
+
+
+/*!
+ * \brief Lookup label for 'TransmuterStartingStates' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string label of the given entry
+ */
+const char* TransmuterStartingStates_EnumLabel(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case TRANSMUTER_START_INIT:
+ return "TRANSMUTER_START_INIT";
+ case TRANSMUTER_START_PRIMING:
+ return "TRANSMUTER_START_PRIMING";
+ case TRANSMUTER_START_DISABLE_ECU:
+ return "TRANSMUTER_START_DISABLE_ECU";
+ case TRANSMUTER_START_CRANK_GEN:
+ return "TRANSMUTER_START_CRANK_GEN";
+ case TRANSMUTER_START_ENABLE_ECU:
+ return "TRANSMUTER_START_ENABLE_ECU";
+ case TRANSMUTER_START_FAILURE:
+ return "TRANSMUTER_START_FAILURE";
+ }
+}
+
+/*!
+ * \brief Lookup title for 'TransmuterStartingStates' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string title of the given entry (comment if no title given)
+ */
+const char* TransmuterStartingStates_EnumTitle(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case TRANSMUTER_START_INIT:
+ return "Initializing the starting routine";
+ case TRANSMUTER_START_PRIMING:
+ return "Priming engine / fuel pump / etc";
+ case TRANSMUTER_START_DISABLE_ECU:
+ return "Disabling ECU prior to engine cranking";
+ case TRANSMUTER_START_CRANK_GEN:
+ return "Spinning the generator";
+ case TRANSMUTER_START_ENABLE_ECU:
+ return "Enable ECU once the system is spinning";
+ case TRANSMUTER_START_FAILURE:
+ return "Starting failed";
+ }
+}
+
+
+/*!
+ * \brief Lookup label for 'TransmuterStandbyCause' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string label of the given entry
+ */
+const char* TransmuterStandbyCause_EnumLabel(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case TRANSMUTER_STANDBY_CAUSE_POWERUP:
+ return "TRANSMUTER_STANDBY_CAUSE_POWERUP";
+ case TRANSMUTER_STANDBY_CAUSE_HW_DISABLE:
+ return "TRANSMUTER_STANDBY_CAUSE_HW_DISABLE";
+ case TRANSMUTER_STANDBY_CAUSE_SW_DISABLE:
+ return "TRANSMUTER_STANDBY_CAUSE_SW_DISABLE";
+ case TRANSMUTER_STANDBY_CAUSE_STARTING_RETRIES:
+ return "TRANSMUTER_STANDBY_CAUSE_STARTING_RETRIES";
+ case TRANSMUTER_STANDBY_CAUSE_CMD:
+ return "TRANSMUTER_STANDBY_CAUSE_CMD";
+ case TRANSMUTER_STANDBY_CAUSE_CRITICAL_RUNNING_ERROR:
+ return "TRANSMUTER_STANDBY_CAUSE_CRITICAL_RUNNING_ERROR";
+ case TRANSMUTER_STANDBY_CAUSE_UNKNOWN_MODE:
+ return "TRANSMUTER_STANDBY_CAUSE_UNKNOWN_MODE";
+ }
+}
+
+
+/*!
+ * \brief Lookup label for 'TransmuterFuelPumpMode' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string label of the given entry
+ */
+const char* TransmuterFuelPumpMode_EnumLabel(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case TRANSMUTER_PUMP_TRIPLEX:
+ return "TRANSMUTER_PUMP_TRIPLEX";
+ case TRANSMUTER_PUMP_ECU:
+ return "TRANSMUTER_PUMP_ECU";
+ }
+}
+
+
+/*!
+ * \brief Lookup label for 'TransmuterPackets' enum entry
+ *
+ * \param value is the integer value of the enum entry
+ * \return string label of the given entry
+ */
+const char* TransmuterPackets_EnumLabel(int value)
+{
+ switch (value)
+ {
+ default:
+ return "";
+ case PKT_TRANSMUTER_STANDBY:
+ return "PKT_TRANSMUTER_STANDBY";
+ case PKT_TRANSMUTER_PREFLIGHT:
+ return "PKT_TRANSMUTER_PREFLIGHT";
+ case PKT_TRANSMUTER_WARMUP:
+ return "PKT_TRANSMUTER_WARMUP";
+ case PKT_TRANSMUTER_RUN:
+ return "PKT_TRANSMUTER_RUN";
+ case PKT_TRANSMUTER_PWM:
+ return "PKT_TRANSMUTER_PWM";
+ case PKT_TRANSMUTER_SYSTEM_CMD:
+ return "PKT_TRANSMUTER_SYSTEM_CMD";
+ case PKT_TRANSMUTER_TELEMETRY_STATUS:
+ return "PKT_TRANSMUTER_TELEMETRY_STATUS";
+ case PKT_TRANSMUTER_TELEMETRY_POWER:
+ return "PKT_TRANSMUTER_TELEMETRY_POWER";
+ case PKT_TRANSMUTER_TELEMETRY_SETPOINT:
+ return "PKT_TRANSMUTER_TELEMETRY_SETPOINT";
+ case PKT_TRANSMUTER_TELEMETRY_GEN:
+ return "PKT_TRANSMUTER_TELEMETRY_GEN";
+ case PKT_TRANSMUTER_TELEMETRY_CAPACITY:
+ return "PKT_TRANSMUTER_TELEMETRY_CAPACITY";
+ case PKT_TRANSMUTER_TELEMETRY_CTRL_LOOP:
+ return "PKT_TRANSMUTER_TELEMETRY_CTRL_LOOP";
+ case PKT_TRANSMUTER_TELEMETRY_APB:
+ return "PKT_TRANSMUTER_TELEMETRY_APB";
+ case PKT_TRANSMUTER_TELEMETRY_CONFIG:
+ return "PKT_TRANSMUTER_TELEMETRY_CONFIG";
+ case PKT_TRANSMUTER_WARNING_LEVELS:
+ return "PKT_TRANSMUTER_WARNING_LEVELS";
+ case PKT_TRANSMUTER_CTRL_LOOP_SETTINGS:
+ return "PKT_TRANSMUTER_CTRL_LOOP_SETTINGS";
+ case PKT_TRANSMUTER_BATTERY_SETTINGS:
+ return "PKT_TRANSMUTER_BATTERY_SETTINGS";
+ case PKT_TRANSMUTER_EFI_CONFIG:
+ return "PKT_TRANSMUTER_EFI_CONFIG";
+ case PKT_TRANSMUTER_GEN_CONFIG:
+ return "PKT_TRANSMUTER_GEN_CONFIG";
+ case PKT_TRANSMUTER_POWER_MAP:
+ return "PKT_TRANSMUTER_POWER_MAP";
+ case PKT_TRANSMUTER_STARTING_SETTINGS:
+ return "PKT_TRANSMUTER_STARTING_SETTINGS";
+ case PKT_TRANSMUTER_BULK_TRANSFER:
+ return "PKT_TRANSMUTER_BULK_TRANSFER";
+ }
+}
+
+// end of TransmuterProtocol.c
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterProtocol.h b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterProtocol.h
new file mode 100644
index 0000000000..3a49252e10
--- /dev/null
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/TransmuterProtocol.h
@@ -0,0 +1,177 @@
+// TransmuterProtocol.h was generated by ProtoGen version 3.5.c
+
+/*
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ *
+ * Author: Oliver Walters / Currawong Engineering Pty Ltd
+ */
+
+#ifndef _TRANSMUTERPROTOCOL_H
+#define _TRANSMUTERPROTOCOL_H
+
+// Language target is C, C++ compilers: don't mangle us
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \file
+ * \mainpage Transmuter protocol stack
+ *
+ * This is the ICD for the Currawong Engineering Hybrid Transmuter. This
+ * document details the Transmuter command and packet structure for
+ * communication with and configuration of the Transmuter.
+ *
+ * The protocol API enumeration is incremented anytime the protocol is changed
+ * in a way that affects compatibility with earlier versions of the protocol.
+ * The protocol enumeration for this version is: 15
+ *
+ * The protocol version is 0.11
+ */
+
+#include
+#include
+
+//! \return the protocol API enumeration
+#define getTransmuterApi() 15
+
+//! \return the protocol version string
+#define getTransmuterVersion() "0.11"
+
+/*!
+ * Defines the various high-level operational modes of the Transmuter state
+ * machine
+ */
+typedef enum
+{
+ TRANSMUTER_MODE_STARTUP = 0, //!< Initial powerup mode of the transmuter
+ TRANSMUTER_MODE_STANDBY, //!< Transmuter is in standby mode
+ TRANSMUTER_MODE_PREFLIGHT, //!< Transmuter is in preflight check mode
+ TRANSMUTER_MODE_STARTING, //!< Transmuter is attempting to start the engine
+ TRANSMUTER_MODE_WARMUP, //!< Transmuter is in warmup mode
+ TRANSMUTER_MODE_RPM, //!< Transmuter is running in RPM control mode
+ TRANSMUTER_MODE_CURRENT, //!< Transmuter is running in CURRENT control mode
+ TRANSMUTER_MODE_PWM, //!< Transmuter is running in PWM control mode
+ TRANSMUTER_MODE_NUM_MODES //!< Number of transmuter operational modes
+} TransmuterModes;
+
+//! \return the label of a 'TransmuterModes' enum entry, based on its value
+const char* TransmuterModes_EnumLabel(int value);
+
+//! \return the title of a 'TransmuterModes' enum entry, based on its value
+const char* TransmuterModes_EnumTitle(int value);
+
+/*!
+ * Defines the various states of the transmuter engine starting state machine
+ */
+typedef enum
+{
+ TRANSMUTER_START_INIT = 0, //!< Initializing the starting routine
+ TRANSMUTER_START_PRIMING, //!< Priming engine / fuel pump / etc
+ TRANSMUTER_START_DISABLE_ECU, //!< Disabling ECU prior to engine cranking
+ TRANSMUTER_START_CRANK_GEN, //!< Spinning the generator
+ TRANSMUTER_START_ENABLE_ECU, //!< Enable ECU once the system is spinning
+ TRANSMUTER_START_FAILURE = 0x0F //!< Starting failed
+} TransmuterStartingStates;
+
+//! \return the label of a 'TransmuterStartingStates' enum entry, based on its value
+const char* TransmuterStartingStates_EnumLabel(int value);
+
+//! \return the title of a 'TransmuterStartingStates' enum entry, based on its value
+const char* TransmuterStartingStates_EnumTitle(int value);
+
+/*!
+ * Possible transmuter system standby causes
+ */
+typedef enum
+{
+ TRANSMUTER_STANDBY_CAUSE_POWERUP = 0x01, //!< System power-on (or reset)
+ TRANSMUTER_STANDBY_CAUSE_HW_DISABLE = 0x10, //!< System standby caused by hardware inhibit line
+ TRANSMUTER_STANDBY_CAUSE_SW_DISABLE, //!< System standby casued by software inhibit
+ TRANSMUTER_STANDBY_CAUSE_STARTING_RETRIES = 0x20, //!< Too many starting attempts
+ TRANSMUTER_STANDBY_CAUSE_CMD = 0x30, //!< Standby due to received command
+ TRANSMUTER_STANDBY_CAUSE_CRITICAL_RUNNING_ERROR = 0x40, //!< Standby due to critical error during running
+ TRANSMUTER_STANDBY_CAUSE_UNKNOWN_MODE = 0x80 //!< Unknown operational mode
+} TransmuterStandbyCause;
+
+//! \return the label of a 'TransmuterStandbyCause' enum entry, based on its value
+const char* TransmuterStandbyCause_EnumLabel(int value);
+
+/*!
+ * Fuel pump mode
+ */
+typedef enum
+{
+ TRANSMUTER_PUMP_TRIPLEX = 0x00, //!< Fuel pressure is regulated via triplex pump
+ TRANSMUTER_PUMP_ECU = 0x01 //!< Fuel pressure is regulated via ECU
+} TransmuterFuelPumpMode;
+
+//! \return the label of a 'TransmuterFuelPumpMode' enum entry, based on its value
+const char* TransmuterFuelPumpMode_EnumLabel(int value);
+
+/*!
+ * Transmuter packet ID values
+ */
+typedef enum
+{
+ PKT_TRANSMUTER_STANDBY = 0x10, //!< Command the transmuter to enter standby mode
+ PKT_TRANSMUTER_PREFLIGHT = 0x11, //!< Command the transmuter to enter preflight mode
+ PKT_TRANSMUTER_WARMUP = 0x12, //!< Command the transmuter to enter engine warmup mode
+ PKT_TRANSMUTER_RUN = 0x15, //!< Command the transmuter to enter running mode
+ PKT_TRANSMUTER_PWM = 0x20, //!< Command the transmuter to enter PWM mode
+ PKT_TRANSMUTER_SYSTEM_CMD = 0x50, //!< Send various system commands to the transmuter
+ PKT_TRANSMUTER_TELEMETRY_STATUS = 0x80, //!< General transmuter status information
+ PKT_TRANSMUTER_TELEMETRY_POWER = 0x81, //!< Current and power information
+ PKT_TRANSMUTER_TELEMETRY_SETPOINT = 0x82, //!< System setpoint information
+ PKT_TRANSMUTER_TELEMETRY_GEN = 0x83, //!< Generator and EFI status information
+ PKT_TRANSMUTER_TELEMETRY_CAPACITY = 0x84, //!< System capacity information
+ PKT_TRANSMUTER_TELEMETRY_CTRL_LOOP = 0x86, //!< Control loop output information
+ PKT_TRANSMUTER_TELEMETRY_APB = 0x87, //!< Power output from auxillary power board
+ PKT_TRANSMUTER_TELEMETRY_CONFIG = 0x94, //!< Telemetry settings
+ PKT_TRANSMUTER_WARNING_LEVELS = 0x95, //!< Warning threshold calibration
+ PKT_TRANSMUTER_CTRL_LOOP_SETTINGS = 0xA0, //!< Control loop settings packet
+ PKT_TRANSMUTER_BATTERY_SETTINGS = 0xB0, //!< Battery management configuration
+ PKT_TRANSMUTER_EFI_CONFIG = 0xB5, //!< EFI configuration
+ PKT_TRANSMUTER_GEN_CONFIG = 0xB6, //!< Generator motor config
+ PKT_TRANSMUTER_POWER_MAP = 0xC0, //!< Engine power map
+ PKT_TRANSMUTER_STARTING_SETTINGS = 0xCA, //!< Engine starting settings
+ PKT_TRANSMUTER_BULK_TRANSFER = 0xF0 //!< Bulk data transfer (long packets)
+} TransmuterPackets;
+
+//! \return the label of a 'TransmuterPackets' enum entry, based on its value
+const char* TransmuterPackets_EnumLabel(int value);
+
+
+// The prototypes below provide an interface to the packets.
+// They are not auto-generated functions, but must be hand-written
+
+//! \return the packet data pointer from the packet
+uint8_t* getTransmuterPacketData(void* pkt);
+
+//! \return the packet data pointer from the packet, const
+const uint8_t* getTransmuterPacketDataConst(const void* pkt);
+
+//! Complete a packet after the data have been encoded
+void finishTransmuterPacket(void* pkt, int size, uint32_t packetID);
+
+//! \return the size of a packet from the packet header
+int getTransmuterPacketSize(const void* pkt);
+
+//! \return the ID of a packet from the packet header
+uint32_t getTransmuterPacketID(const void* pkt);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // _TRANSMUTERPROTOCOL_H
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.c b/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.c
index 5f39ecc78c..b9ac8fe8b8 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.c
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.c
@@ -1,4 +1,4 @@
-// fielddecode.c was generated by ProtoGen version 3.2.a
+// fielddecode.c was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.h b/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.h
index 75b27c5555..70eef52f7a 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.h
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/fielddecode.h
@@ -1,4 +1,4 @@
-// fielddecode.h was generated by ProtoGen version 3.2.a
+// fielddecode.h was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
@@ -61,7 +61,6 @@ extern "C" {
* extension.
*/
-
#define __STDC_CONSTANT_MACROS
#include
#include
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.c b/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.c
index 670ca49b05..4c48d0b640 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.c
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.c
@@ -1,4 +1,4 @@
-// fieldencode.c was generated by ProtoGen version 3.2.a
+// fieldencode.c was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.h b/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.h
index 6c6e2500d4..4a174f727b 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.h
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/fieldencode.h
@@ -1,4 +1,4 @@
-// fieldencode.h was generated by ProtoGen version 3.2.a
+// fieldencode.h was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
@@ -59,7 +59,6 @@ extern "C" {
* re-ordered for the data to be interpreted correctly.
*/
-
#define __STDC_CONSTANT_MACROS
#include
#include
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.c b/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.c
index e71a5cf9e5..31b71fcf41 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.c
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.c
@@ -1,4 +1,4 @@
-// scaleddecode.c was generated by ProtoGen version 3.2.a
+// scaleddecode.c was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.h b/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.h
index a0d665d3ff..2e53edaa9d 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.h
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/scaleddecode.h
@@ -1,4 +1,4 @@
-// scaleddecode.h was generated by ProtoGen version 3.2.a
+// scaleddecode.h was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
@@ -25,25 +25,27 @@
extern "C" {
#endif
-/*!
- * \file
- */
-
/*!
* \file
* scaleddecode routines extract scaled numbers from a byte stream.
- *
- * scaleddecode routines extract scaled numbers from a byte stream. The routines
- * in this module are the reverse operation of the routines in scaledencode.
- *
+ *
+ * scaleddecode routines extract scaled numbers from a byte stream. The
+ * routines in this module are the reverse operation of the routines in
+ * scaledencode.
+ *
* Code generation for this module was affected by these global flags:
- * 64-bit integers are not supported.
- * Normal bitfields are supported, long bitfields are not.
- * Double precision floating points are not supported.
+ *
+ * - 64-bit integers are not supported.
+ *
+ * - Normal bitfields are supported, long bitfields are not.
+ *
+ * - Double precision floating points are not supported.
*/
#define __STDC_CONSTANT_MACROS
#include
+#include
+
//! Compute a float using inverse floating point scaling from the base integer type used for bitfields.
float float32ScaledFromBitfield(unsigned int value, float min, float invscaler);
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.c b/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.c
index 04d905523f..432da8bcc7 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.c
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.c
@@ -1,4 +1,4 @@
-// scaledencode.c was generated by ProtoGen version 3.2.a
+// scaledencode.c was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
diff --git a/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.h b/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.h
index 587a173fd5..f88b19032f 100644
--- a/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.h
+++ b/libraries/AP_PiccoloCAN/piccolo_protocol/scaledencode.h
@@ -1,4 +1,4 @@
-// scaledencode.h was generated by ProtoGen version 3.2.a
+// scaledencode.h was generated by ProtoGen version 3.5.c
/*
* This file is free software: you can redistribute it and/or modify it
@@ -25,14 +25,10 @@
extern "C" {
#endif
-/*!
- * \file
- */
-
/*!
* \file
* scaledencode routines place scaled numbers into a byte stream.
- *
+ *
* scaledencode routines place scaled values into a big or little endian byte
* stream. The values can be any legitimate type (double, float, uint32_t,
* uint16_t, uint8_t, int32_t, int16_t, int8_t), and are encoded as either a
@@ -41,41 +37,46 @@ extern "C" {
* limitation that the maximum value must be more than the minimum. Signed
* encodings only allow the caller to specify a maximum value which gives
* maximum absolute value that can be encoded.
- *
+ *
* An example encoding would be: take a float that represents speed in meters
- * per second and encode it in two bytes from -200 to 200 meters per second.
- * In that example the encoding function would be:
- *
+ * per second and encode it in two bytes from -200 to 200 meters per second. In
+ * that example the encoding function would be:
+ *
* float32ScaledTo2SignedBeBytes(speed, bytestream, &index, 200);
- *
+ *
* This would scale the speed according to (32767/200), and copy the resulting
* two bytes to bytestream[index] as a signed 16 bit number in big endian
* order. This would result in a velocity resolution of 0.006 m/s.
- *
+ *
* Another example encoding is: take a double that represents altitude in
* meters and encode it in three bytes from -1000 to 49000 meters:
- *
+ *
* float64ScaledTo3UnsignedLeBytes(alt, bytestream, &index, -1000, 49000);
- *
- * This would transform the altitude according to (alt *(16777215/50000) + 1000)
- * and copy the resulting three bytes to bytestream[index] as an unsigned 24
- * bit number in little endian order. This would result in an altitude
+ *
+ * This would transform the altitude according to (alt *(16777215/50000) +
+ * 1000) and copy the resulting three bytes to bytestream[index] as an unsigned
+ * 24 bit number in little endian order. This would result in an altitude
* resolution of 0.003 meters.
*
* scaledencode does not include routines that increase the resolution of the
- * inmemory value. For example the function floatScaledTo5UnsignedBeBytes() does
- * not exist, because expanding a float to 5 bytes does not make any resolution
- * improvement over encoding it in 4 bytes. In general the encoded format
- * must be equal to or less than the number of bytes of the raw data.
- *
+ * inmemory value. For example the function floatScaledTo5UnsignedBeBytes()
+ * does not exist, because expanding a float to 5 bytes does not make any
+ * resolution improvement over encoding it in 4 bytes. In general the encoded
+ * format must be equal to or less than the number of bytes of the raw data.
+ *
* Code generation for this module was affected by these global flags:
- * 64-bit integers are not supported.
- * Normal bitfields are supported, long bitfields are not.
- * Double precision floating points are not supported.
+ *
+ * - 64-bit integers are not supported.
+ *
+ * - Normal bitfields are supported, long bitfields are not.
+ *
+ * - Double precision floating points are not supported.
*/
#define __STDC_CONSTANT_MACROS
#include
+#include
+
//! Scale a float using floating point scaling to the base integer type used for bitfields.
unsigned int float32ScaledToBitfield(float value, float min, float scaler, int bits);