ardupilot/libraries/AP_PiccoloCAN/piccolo_protocol/ESCPackets.c

5117 lines
190 KiB
C

// ESCPackets.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 <http://www.gnu.org/licenses/>.
*
* Author: Oliver Walters / Currawong Engineering Pty Ltd
*/
#include "ESCPackets.h"
#include "fielddecode.h"
#include "fieldencode.h"
#include "scaleddecode.h"
#include "scaledencode.h"
#include "ESCDefines.h"
/*!
* \brief Encode a ESC_HallSensorPattern_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 encodeESC_HallSensorPattern_t(uint8_t* _pg_data, int* _pg_bytecount, const ESC_HallSensorPattern_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// Range of reserved is 0 to 3.
_pg_data[_pg_byteindex] = (uint8_t)_pg_user->reserved << 6;
// Range of polarity is 0 to 7.
_pg_data[_pg_byteindex] |= (uint8_t)_pg_user->polarity << 3;
_pg_byteindex += 1; // close bit field
*_pg_bytecount = _pg_byteindex;
}// encodeESC_HallSensorPattern_t
/*!
* \brief Decode a ESC_HallSensorPattern_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 decodeESC_HallSensorPattern_t(const uint8_t* _pg_data, int* _pg_bytecount, ESC_HallSensorPattern_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// Range of reserved is 0 to 3.
_pg_user->reserved = (_pg_data[_pg_byteindex] >> 6);
// Range of polarity is 0 to 7.
_pg_user->polarity = ((_pg_data[_pg_byteindex] >> 3) & 0x7);
_pg_byteindex += 1; // close bit field
*_pg_bytecount = _pg_byteindex;
return 1;
}// decodeESC_HallSensorPattern_t
/*!
* \brief Create the ESC_RPMControlLoopSettings packet
*
* RPM 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 encodeESC_RPMControlLoopSettingsPacketStructure(void* _pg_pkt, const ESC_RPMControlLoopSettings_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Core control loop settings
encodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, &_pg_user->pid);
// RPM setpoint rate limit
// Range of rpmRateLimit is 0 to 65535.
uint16ToBeBytes(_pg_user->rpmRateLimit, _pg_data, &_pg_byteindex);
// Corner frequency for RPM measurement LPF
// Range of rpmFilter is 0.0f to 500.0f.
float32ScaledTo2UnsignedBeBytes(_pg_user->rpmFilter, _pg_data, &_pg_byteindex, 0.0f, 131.07f);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_RPMControlLoopSettingsPacketID());
}// encodeESC_RPMControlLoopSettingsPacketStructure
/*!
* \brief Decode the ESC_RPMControlLoopSettings packet
*
* RPM 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 decodeESC_RPMControlLoopSettingsPacketStructure(const void* _pg_pkt, ESC_RPMControlLoopSettings_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_RPMControlLoopSettingsPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_RPMControlLoopSettingsMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// this packet has default fields, make sure they are set
_pg_user->rpmRateLimit = 0;
_pg_user->rpmFilter = 50;
// Core control loop settings
if(decodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, &_pg_user->pid) == 0)
return 0;
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// RPM setpoint rate limit
// Range of rpmRateLimit is 0 to 65535.
_pg_user->rpmRateLimit = uint16FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Corner frequency for RPM measurement LPF
// Range of rpmFilter is 0.0f to 500.0f.
_pg_user->rpmFilter = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/131.07f);
return 1;
}// decodeESC_RPMControlLoopSettingsPacketStructure
/*!
* \brief Encode a ESC_RPMControlLoopSettings_t into a byte array
*
* RPM control loop settings
* \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 encodeESC_RPMControlLoopSettings_t(uint8_t* _pg_data, int* _pg_bytecount, const ESC_RPMControlLoopSettings_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// Core control loop settings
encodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, &_pg_user->pid);
// RPM setpoint rate limit
// Range of rpmRateLimit is 0 to 65535.
uint16ToBeBytes(_pg_user->rpmRateLimit, _pg_data, &_pg_byteindex);
// Corner frequency for RPM measurement LPF
// Range of rpmFilter is 0.0f to 500.0f.
float32ScaledTo2UnsignedBeBytes(_pg_user->rpmFilter, _pg_data, &_pg_byteindex, 0.0f, 131.07f);
*_pg_bytecount = _pg_byteindex;
}// encodeESC_RPMControlLoopSettings_t
/*!
* \brief Decode a ESC_RPMControlLoopSettings_t from a byte array
*
* RPM control loop settings
* \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 decodeESC_RPMControlLoopSettings_t(const uint8_t* _pg_data, int* _pg_bytecount, ESC_RPMControlLoopSettings_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// Core control loop settings
if(decodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, &_pg_user->pid) == 0)
return 0;
// RPM setpoint rate limit
// Range of rpmRateLimit is 0 to 65535.
_pg_user->rpmRateLimit = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Corner frequency for RPM measurement LPF
// Range of rpmFilter is 0.0f to 500.0f.
_pg_user->rpmFilter = float32ScaledFrom2UnsignedBeBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/131.07f);
*_pg_bytecount = _pg_byteindex;
return 1;
}// decodeESC_RPMControlLoopSettings_t
/*!
* \brief Create the ESC_Config packet
*
* General ESC configuration 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 encodeESC_ConfigPacketStructure(void* _pg_pkt, const ESC_Config_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// 1 = ESC is inhibited (disabled) on startup
_pg_data[_pg_byteindex] = (uint8_t)((_pg_user->swInhibit == true) ? 1 : 0) << 7;
// 1 = ESC will respond to PICCOLO autopilot commands
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->piccoloCommands == true) ? 1 : 0) << 6;
// 1 = ESC will accept broadcast command messages
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->broadcastCommands == true) ? 1 : 0) << 5;
// 1 = Digital PWM input is enabled
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->enablePwmInput == true) ? 1 : 0) << 4;
// Reserved for future use
// External motor temperature sensor configuration
// Range of motorTempSensor is 0 to 7.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->motorTempSensor, 7);
_pg_byteindex += 1; // close bit field
// ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
// Range of keepalive is 0 to 255.
uint8ToBytes(_pg_user->keepalive, _pg_data, &_pg_byteindex);
// 1 = Disable LED
_pg_data[_pg_byteindex] = (uint8_t)limitMax(_pg_user->disableLED, 1) << 7;
// CAN bit (baud) rate
// Range of canBitRate is 0 to 15.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->canBitRate, 15) << 3;
// Protocol to communicate over CAN
// Range of canProtocol is 0 to 3.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->canProtocol, 3) << 1;
// Enable motor brake strength (applied when motor is off)
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->motorBraking == true) ? 1 : 0);
_pg_byteindex += 1; // close bit field
// Delay between hardware inhibit and software inhibit events
// Range of swInhibitDelay is 0 to 255.
uint8ToBytes(_pg_user->swInhibitDelay, _pg_data, &_pg_byteindex);
// Reserved for future use
uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
// Reserved for future use
uint16ToBeBytes((uint16_t)(0), _pg_data, &_pg_byteindex);
// Sets the motor beep mode for the ESC
// Range of motorBeepMode is 0 to 7.
_pg_data[_pg_byteindex] = (uint8_t)limitMax(_pg_user->motorBeepMode, 7) << 5;
// Motor beep volume
// Range of motorBeepVolume is 0 to 31.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->motorBeepVolume, 31);
_pg_byteindex += 1; // close bit field
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ConfigPacketID());
}// encodeESC_ConfigPacketStructure
/*!
* \brief Decode the ESC_Config packet
*
* General ESC configuration 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 decodeESC_ConfigPacketStructure(const void* _pg_pkt, ESC_Config_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ConfigPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_ConfigMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// 1 = ESC is inhibited (disabled) on startup
_pg_user->swInhibit = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
// 1 = ESC will respond to PICCOLO autopilot commands
_pg_user->piccoloCommands = (((_pg_data[_pg_byteindex] >> 6) & 0x1)) ? true : false;
// 1 = ESC will accept broadcast command messages
_pg_user->broadcastCommands = (((_pg_data[_pg_byteindex] >> 5) & 0x1)) ? true : false;
// 1 = Digital PWM input is enabled
_pg_user->enablePwmInput = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
// Reserved for future use
// External motor temperature sensor configuration
// Range of motorTempSensor is 0 to 7.
_pg_user->motorTempSensor = ((_pg_data[_pg_byteindex]) & 0x7);
_pg_byteindex += 1; // close bit field
// ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
// Range of keepalive is 0 to 255.
_pg_user->keepalive = uint8FromBytes(_pg_data, &_pg_byteindex);
// 1 = Disable LED
_pg_user->disableLED = (_pg_data[_pg_byteindex] >> 7);
// CAN bit (baud) rate
// Range of canBitRate is 0 to 15.
_pg_user->canBitRate = ((_pg_data[_pg_byteindex] >> 3) & 0xF);
// Protocol to communicate over CAN
// Range of canProtocol is 0 to 3.
_pg_user->canProtocol = ((_pg_data[_pg_byteindex] >> 1) & 0x3);
// Enable motor brake strength (applied when motor is off)
_pg_user->motorBraking = (((_pg_data[_pg_byteindex]) & 0x1)) ? true : false;
_pg_byteindex += 1; // close bit field
// Delay between hardware inhibit and software inhibit events
// Range of swInhibitDelay is 0 to 255.
_pg_user->swInhibitDelay = uint8FromBytes(_pg_data, &_pg_byteindex);
// Reserved for future use
_pg_byteindex += 1;
// Reserved for future use
_pg_byteindex += 2;
// Sets the motor beep mode for the ESC
// Range of motorBeepMode is 0 to 7.
_pg_user->motorBeepMode = (_pg_data[_pg_byteindex] >> 5);
// Motor beep volume
// Range of motorBeepVolume is 0 to 31.
_pg_user->motorBeepVolume = ((_pg_data[_pg_byteindex]) & 0x1F);
_pg_byteindex += 1; // close bit field
return 1;
}// decodeESC_ConfigPacketStructure
/*!
* \brief Create the ESC_Config packet
*
* General ESC configuration parameters
* \param _pg_pkt points to the packet which will be created by this function
* \param swInhibit is 1 = ESC is inhibited (disabled) on startup
* \param piccoloCommands is 1 = ESC will respond to PICCOLO autopilot commands
* \param broadcastCommands is 1 = ESC will accept broadcast command messages
* \param enablePwmInput is 1 = Digital PWM input is enabled
* \param motorTempSensor is External motor temperature sensor configuration
* \param keepalive is ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
* \param disableLED is 1 = Disable LED
* \param canBitRate is CAN bit (baud) rate
* \param canProtocol is Protocol to communicate over CAN
* \param motorBraking is Enable motor brake strength (applied when motor is off)
* \param swInhibitDelay is Delay between hardware inhibit and software inhibit events
* \param motorBeepMode is Sets the motor beep mode for the ESC
* \param motorBeepVolume is Motor beep volume
*/
void encodeESC_ConfigPacket(void* _pg_pkt, bool swInhibit, bool piccoloCommands, bool broadcastCommands, bool enablePwmInput, uint8_t motorTempSensor, uint8_t keepalive, uint8_t disableLED, uint8_t canBitRate, uint8_t canProtocol, bool motorBraking, uint8_t swInhibitDelay, uint8_t motorBeepMode, uint8_t motorBeepVolume)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// 1 = ESC is inhibited (disabled) on startup
_pg_data[_pg_byteindex] = (uint8_t)((swInhibit == true) ? 1 : 0) << 7;
// 1 = ESC will respond to PICCOLO autopilot commands
_pg_data[_pg_byteindex] |= (uint8_t)((piccoloCommands == true) ? 1 : 0) << 6;
// 1 = ESC will accept broadcast command messages
_pg_data[_pg_byteindex] |= (uint8_t)((broadcastCommands == true) ? 1 : 0) << 5;
// 1 = Digital PWM input is enabled
_pg_data[_pg_byteindex] |= (uint8_t)((enablePwmInput == true) ? 1 : 0) << 4;
// Reserved for future use
// External motor temperature sensor configuration
// Range of motorTempSensor is 0 to 7.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(motorTempSensor, 7);
_pg_byteindex += 1; // close bit field
// ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
// Range of keepalive is 0 to 255.
uint8ToBytes(keepalive, _pg_data, &_pg_byteindex);
// 1 = Disable LED
_pg_data[_pg_byteindex] = (uint8_t)limitMax(disableLED, 1) << 7;
// CAN bit (baud) rate
// Range of canBitRate is 0 to 15.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(canBitRate, 15) << 3;
// Protocol to communicate over CAN
// Range of canProtocol is 0 to 3.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(canProtocol, 3) << 1;
// Enable motor brake strength (applied when motor is off)
_pg_data[_pg_byteindex] |= (uint8_t)((motorBraking == true) ? 1 : 0);
_pg_byteindex += 1; // close bit field
// Delay between hardware inhibit and software inhibit events
// Range of swInhibitDelay is 0 to 255.
uint8ToBytes(swInhibitDelay, _pg_data, &_pg_byteindex);
// Reserved for future use
uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
// Reserved for future use
uint16ToBeBytes((uint16_t)(0), _pg_data, &_pg_byteindex);
// Sets the motor beep mode for the ESC
// Range of motorBeepMode is 0 to 7.
_pg_data[_pg_byteindex] = (uint8_t)limitMax(motorBeepMode, 7) << 5;
// Motor beep volume
// Range of motorBeepVolume is 0 to 31.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(motorBeepVolume, 31);
_pg_byteindex += 1; // close bit field
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ConfigPacketID());
}// encodeESC_ConfigPacket
/*!
* \brief Decode the ESC_Config packet
*
* General ESC configuration parameters
* \param _pg_pkt points to the packet being decoded by this function
* \param swInhibit receives 1 = ESC is inhibited (disabled) on startup
* \param piccoloCommands receives 1 = ESC will respond to PICCOLO autopilot commands
* \param broadcastCommands receives 1 = ESC will accept broadcast command messages
* \param enablePwmInput receives 1 = Digital PWM input is enabled
* \param motorTempSensor receives External motor temperature sensor configuration
* \param keepalive receives ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
* \param disableLED receives 1 = Disable LED
* \param canBitRate receives CAN bit (baud) rate
* \param canProtocol receives Protocol to communicate over CAN
* \param motorBraking receives Enable motor brake strength (applied when motor is off)
* \param swInhibitDelay receives Delay between hardware inhibit and software inhibit events
* \param motorBeepMode receives Sets the motor beep mode for the ESC
* \param motorBeepVolume receives Motor beep volume
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_ConfigPacket(const void* _pg_pkt, bool* swInhibit, bool* piccoloCommands, bool* broadcastCommands, bool* enablePwmInput, uint8_t* motorTempSensor, uint8_t* keepalive, uint8_t* disableLED, uint8_t* canBitRate, uint8_t* canProtocol, bool* motorBraking, uint8_t* swInhibitDelay, uint8_t* motorBeepMode, uint8_t* motorBeepVolume)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ConfigPacketID())
return 0;
if(_pg_numbytes < getESC_ConfigMinDataLength())
return 0;
// 1 = ESC is inhibited (disabled) on startup
(*swInhibit) = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
// 1 = ESC will respond to PICCOLO autopilot commands
(*piccoloCommands) = (((_pg_data[_pg_byteindex] >> 6) & 0x1)) ? true : false;
// 1 = ESC will accept broadcast command messages
(*broadcastCommands) = (((_pg_data[_pg_byteindex] >> 5) & 0x1)) ? true : false;
// 1 = Digital PWM input is enabled
(*enablePwmInput) = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
// Reserved for future use
// External motor temperature sensor configuration
// Range of motorTempSensor is 0 to 7.
(*motorTempSensor) = ((_pg_data[_pg_byteindex]) & 0x7);
_pg_byteindex += 1; // close bit field
// ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
// Range of keepalive is 0 to 255.
(*keepalive) = uint8FromBytes(_pg_data, &_pg_byteindex);
// 1 = Disable LED
(*disableLED) = (_pg_data[_pg_byteindex] >> 7);
// CAN bit (baud) rate
// Range of canBitRate is 0 to 15.
(*canBitRate) = ((_pg_data[_pg_byteindex] >> 3) & 0xF);
// Protocol to communicate over CAN
// Range of canProtocol is 0 to 3.
(*canProtocol) = ((_pg_data[_pg_byteindex] >> 1) & 0x3);
// Enable motor brake strength (applied when motor is off)
(*motorBraking) = (((_pg_data[_pg_byteindex]) & 0x1)) ? true : false;
_pg_byteindex += 1; // close bit field
// Delay between hardware inhibit and software inhibit events
// Range of swInhibitDelay is 0 to 255.
(*swInhibitDelay) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Reserved for future use
_pg_byteindex += 1;
// Reserved for future use
_pg_byteindex += 2;
// Sets the motor beep mode for the ESC
// Range of motorBeepMode is 0 to 7.
(*motorBeepMode) = (_pg_data[_pg_byteindex] >> 5);
// Motor beep volume
// Range of motorBeepVolume is 0 to 31.
(*motorBeepVolume) = ((_pg_data[_pg_byteindex]) & 0x1F);
_pg_byteindex += 1; // close bit field
return 1;
}// decodeESC_ConfigPacket
/*!
* \brief Encode a ESC_Config_t into a byte array
*
* General ESC configuration parameters
* \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 encodeESC_Config_t(uint8_t* _pg_data, int* _pg_bytecount, const ESC_Config_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// 1 = ESC is inhibited (disabled) on startup
_pg_data[_pg_byteindex] = (uint8_t)((_pg_user->swInhibit == true) ? 1 : 0) << 7;
// 1 = ESC will respond to PICCOLO autopilot commands
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->piccoloCommands == true) ? 1 : 0) << 6;
// 1 = ESC will accept broadcast command messages
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->broadcastCommands == true) ? 1 : 0) << 5;
// 1 = Digital PWM input is enabled
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->enablePwmInput == true) ? 1 : 0) << 4;
// Reserved for future use
// External motor temperature sensor configuration
// Range of motorTempSensor is 0 to 7.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->motorTempSensor, 7);
_pg_byteindex += 1; // close bit field
// ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
// Range of keepalive is 0 to 255.
uint8ToBytes(_pg_user->keepalive, _pg_data, &_pg_byteindex);
// 1 = Disable LED
_pg_data[_pg_byteindex] = (uint8_t)limitMax(_pg_user->disableLED, 1) << 7;
// CAN bit (baud) rate
// Range of canBitRate is 0 to 15.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->canBitRate, 15) << 3;
// Protocol to communicate over CAN
// Range of canProtocol is 0 to 3.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->canProtocol, 3) << 1;
// Enable motor brake strength (applied when motor is off)
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->motorBraking == true) ? 1 : 0);
_pg_byteindex += 1; // close bit field
// Delay between hardware inhibit and software inhibit events
// Range of swInhibitDelay is 0 to 255.
uint8ToBytes(_pg_user->swInhibitDelay, _pg_data, &_pg_byteindex);
// Reserved for future use
uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
// Reserved for future use
uint16ToBeBytes((uint16_t)(0), _pg_data, &_pg_byteindex);
// Sets the motor beep mode for the ESC
// Range of motorBeepMode is 0 to 7.
_pg_data[_pg_byteindex] = (uint8_t)limitMax(_pg_user->motorBeepMode, 7) << 5;
// Motor beep volume
// Range of motorBeepVolume is 0 to 31.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->motorBeepVolume, 31);
_pg_byteindex += 1; // close bit field
*_pg_bytecount = _pg_byteindex;
}// encodeESC_Config_t
/*!
* \brief Decode a ESC_Config_t from a byte array
*
* General ESC configuration parameters
* \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 decodeESC_Config_t(const uint8_t* _pg_data, int* _pg_bytecount, ESC_Config_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// 1 = ESC is inhibited (disabled) on startup
_pg_user->swInhibit = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
// 1 = ESC will respond to PICCOLO autopilot commands
_pg_user->piccoloCommands = (((_pg_data[_pg_byteindex] >> 6) & 0x1)) ? true : false;
// 1 = ESC will accept broadcast command messages
_pg_user->broadcastCommands = (((_pg_data[_pg_byteindex] >> 5) & 0x1)) ? true : false;
// 1 = Digital PWM input is enabled
_pg_user->enablePwmInput = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
// Reserved for future use
// External motor temperature sensor configuration
// Range of motorTempSensor is 0 to 7.
_pg_user->motorTempSensor = ((_pg_data[_pg_byteindex]) & 0x7);
_pg_byteindex += 1; // close bit field
// ESC keepalive timeout - If this is non-zero, the ESC will automatically revert to *STANDBY* mode if it does not receive a valid command for the alloted period
// Range of keepalive is 0 to 255.
_pg_user->keepalive = uint8FromBytes(_pg_data, &_pg_byteindex);
// 1 = Disable LED
_pg_user->disableLED = (_pg_data[_pg_byteindex] >> 7);
// CAN bit (baud) rate
// Range of canBitRate is 0 to 15.
_pg_user->canBitRate = ((_pg_data[_pg_byteindex] >> 3) & 0xF);
// Protocol to communicate over CAN
// Range of canProtocol is 0 to 3.
_pg_user->canProtocol = ((_pg_data[_pg_byteindex] >> 1) & 0x3);
// Enable motor brake strength (applied when motor is off)
_pg_user->motorBraking = (((_pg_data[_pg_byteindex]) & 0x1)) ? true : false;
_pg_byteindex += 1; // close bit field
// Delay between hardware inhibit and software inhibit events
// Range of swInhibitDelay is 0 to 255.
_pg_user->swInhibitDelay = uint8FromBytes(_pg_data, &_pg_byteindex);
// Reserved for future use
_pg_byteindex += 1;
// Reserved for future use
_pg_byteindex += 2;
// Sets the motor beep mode for the ESC
// Range of motorBeepMode is 0 to 7.
_pg_user->motorBeepMode = (_pg_data[_pg_byteindex] >> 5);
// Motor beep volume
// Range of motorBeepVolume is 0 to 31.
_pg_user->motorBeepVolume = ((_pg_data[_pg_byteindex]) & 0x1F);
_pg_byteindex += 1; // close bit field
*_pg_bytecount = _pg_byteindex;
return 1;
}// decodeESC_Config_t
/*!
* \brief Create the ESC_TelemetryConfig packet
*
* Telemetry settings (storage class)
* \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 encodeESC_TelemetryConfigPacketStructure(void* _pg_pkt, const ESC_TelemetryConfig_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Telemetry period code (maps indirectly to a telemetry period value)
// Range of period is 0 to 255.
uint8ToBytes(_pg_user->period, _pg_data, &_pg_byteindex);
// Telemetry silence period (delay after RESET before telemetry data is sent)
// Range of silence is 0 to 255.
uint8ToBytes(_pg_user->silence, _pg_data, &_pg_byteindex);
// Bitfield describing which telemetry packets are enabled
encodeESC_TelemetryPackets_t(_pg_data, &_pg_byteindex, &_pg_user->packets);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TelemetryConfigPacketID());
}// encodeESC_TelemetryConfigPacketStructure
/*!
* \brief Decode the ESC_TelemetryConfig packet
*
* Telemetry settings (storage class)
* \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 decodeESC_TelemetryConfigPacketStructure(const void* _pg_pkt, ESC_TelemetryConfig_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TelemetryConfigPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_TelemetryConfigMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Telemetry period code (maps indirectly to a telemetry period value)
// Range of period is 0 to 255.
_pg_user->period = uint8FromBytes(_pg_data, &_pg_byteindex);
// Telemetry silence period (delay after RESET before telemetry data is sent)
// Range of silence is 0 to 255.
_pg_user->silence = uint8FromBytes(_pg_data, &_pg_byteindex);
// Bitfield describing which telemetry packets are enabled
if(decodeESC_TelemetryPackets_t(_pg_data, &_pg_byteindex, &_pg_user->packets) == 0)
return 0;
return 1;
}// decodeESC_TelemetryConfigPacketStructure
/*!
* \brief Create the ESC_TelemetryConfig packet
*
* Telemetry settings (storage class)
* \param _pg_pkt points to the packet which will be created by this function
* \param period is Telemetry period code (maps indirectly to a telemetry period value)
* \param silence is Telemetry silence period (delay after RESET before telemetry data is sent)
* \param packets is Bitfield describing which telemetry packets are enabled
*/
void encodeESC_TelemetryConfigPacket(void* _pg_pkt, uint8_t period, uint8_t silence, const ESC_TelemetryPackets_t* packets)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Telemetry period code (maps indirectly to a telemetry period value)
// Range of period is 0 to 255.
uint8ToBytes(period, _pg_data, &_pg_byteindex);
// Telemetry silence period (delay after RESET before telemetry data is sent)
// Range of silence is 0 to 255.
uint8ToBytes(silence, _pg_data, &_pg_byteindex);
// Bitfield describing which telemetry packets are enabled
encodeESC_TelemetryPackets_t(_pg_data, &_pg_byteindex, packets);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TelemetryConfigPacketID());
}// encodeESC_TelemetryConfigPacket
/*!
* \brief Decode the ESC_TelemetryConfig packet
*
* Telemetry settings (storage class)
* \param _pg_pkt points to the packet being decoded by this function
* \param period receives Telemetry period code (maps indirectly to a telemetry period value)
* \param silence receives Telemetry silence period (delay after RESET before telemetry data is sent)
* \param packets receives Bitfield describing which telemetry packets are enabled
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_TelemetryConfigPacket(const void* _pg_pkt, uint8_t* period, uint8_t* silence, ESC_TelemetryPackets_t* packets)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TelemetryConfigPacketID())
return 0;
if(_pg_numbytes < getESC_TelemetryConfigMinDataLength())
return 0;
// Telemetry period code (maps indirectly to a telemetry period value)
// Range of period is 0 to 255.
(*period) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Telemetry silence period (delay after RESET before telemetry data is sent)
// Range of silence is 0 to 255.
(*silence) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Bitfield describing which telemetry packets are enabled
if(decodeESC_TelemetryPackets_t(_pg_data, &_pg_byteindex, packets) == 0)
return 0;
return 1;
}// decodeESC_TelemetryConfigPacket
/*!
* \brief Encode a ESC_TelemetryConfig_t into a byte array
*
* Telemetry settings (storage class)
* \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 encodeESC_TelemetryConfig_t(uint8_t* _pg_data, int* _pg_bytecount, const ESC_TelemetryConfig_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// Telemetry period code (maps indirectly to a telemetry period value)
// Range of period is 0 to 255.
uint8ToBytes(_pg_user->period, _pg_data, &_pg_byteindex);
// Telemetry silence period (delay after RESET before telemetry data is sent)
// Range of silence is 0 to 255.
uint8ToBytes(_pg_user->silence, _pg_data, &_pg_byteindex);
// Bitfield describing which telemetry packets are enabled
encodeESC_TelemetryPackets_t(_pg_data, &_pg_byteindex, &_pg_user->packets);
*_pg_bytecount = _pg_byteindex;
}// encodeESC_TelemetryConfig_t
/*!
* \brief Decode a ESC_TelemetryConfig_t from a byte array
*
* Telemetry settings (storage class)
* \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 decodeESC_TelemetryConfig_t(const uint8_t* _pg_data, int* _pg_bytecount, ESC_TelemetryConfig_t* _pg_user)
{
int _pg_byteindex = *_pg_bytecount;
// Telemetry period code (maps indirectly to a telemetry period value)
// Range of period is 0 to 255.
_pg_user->period = uint8FromBytes(_pg_data, &_pg_byteindex);
// Telemetry silence period (delay after RESET before telemetry data is sent)
// Range of silence is 0 to 255.
_pg_user->silence = uint8FromBytes(_pg_data, &_pg_byteindex);
// Bitfield describing which telemetry packets are enabled
if(decodeESC_TelemetryPackets_t(_pg_data, &_pg_byteindex, &_pg_user->packets) == 0)
return 0;
*_pg_bytecount = _pg_byteindex;
return 1;
}// decodeESC_TelemetryConfig_t
/*!
* \brief Create the ESC_CommandMultipleESCs packet
*
* This packet can be used to simultaneously command multiple ESCs which have
* sequential CAN ID values. This packet must be sent as a broadcast packet
* (address = 0xFF) such that all ESCs can receive it. These commands can be
* sent to groups of ESCs with ID values up to 64, using different
* ESC_SETPOINT_x packet ID values.
* \param _pg_pkt points to the packet which will be created by this function
* \param pwmValueA is The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 1]
* \param pwmValueB is The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 2]
* \param pwmValueC is The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 3]
* \param pwmValueD is The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 4]
* \param id is the packet identifier for _pg_pkt
*/
void encodeESC_CommandMultipleESCsPacket(void* _pg_pkt, uint16_t pwmValueA, uint16_t pwmValueB, uint16_t pwmValueC, uint16_t pwmValueD, uint32_t _pg_id)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 1]
// Range of pwmValueA is 0 to 65535.
uint16ToBeBytes(pwmValueA, _pg_data, &_pg_byteindex);
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 2]
// Range of pwmValueB is 0 to 65535.
uint16ToBeBytes(pwmValueB, _pg_data, &_pg_byteindex);
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 3]
// Range of pwmValueC is 0 to 65535.
uint16ToBeBytes(pwmValueC, _pg_data, &_pg_byteindex);
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 4]
// Range of pwmValueD is 0 to 65535.
uint16ToBeBytes(pwmValueD, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, _pg_id);
}// encodeESC_CommandMultipleESCsPacket
/*!
* \brief Decode the ESC_CommandMultipleESCs packet
*
* This packet can be used to simultaneously command multiple ESCs which have
* sequential CAN ID values. This packet must be sent as a broadcast packet
* (address = 0xFF) such that all ESCs can receive it. These commands can be
* sent to groups of ESCs with ID values up to 64, using different
* ESC_SETPOINT_x packet ID values.
* \param _pg_pkt points to the packet being decoded by this function
* \param pwmValueA receives The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 1]
* \param pwmValueB receives The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 2]
* \param pwmValueC receives The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 3]
* \param pwmValueD receives The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 4]
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_CommandMultipleESCsPacket(const void* _pg_pkt, uint16_t* pwmValueA, uint16_t* pwmValueB, uint16_t* pwmValueC, uint16_t* pwmValueD)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier, multiple options exist
uint32_t packetid = getESCVelocityPacketID(_pg_pkt);
if( packetid != PKT_ESC_SETPOINT_1 &&
packetid != PKT_ESC_SETPOINT_2 &&
packetid != PKT_ESC_SETPOINT_3 &&
packetid != PKT_ESC_SETPOINT_4 &&
packetid != PKT_ESC_SETPOINT_5 &&
packetid != PKT_ESC_SETPOINT_6 &&
packetid != PKT_ESC_SETPOINT_7 &&
packetid != PKT_ESC_SETPOINT_8 &&
packetid != PKT_ESC_SETPOINT_9 &&
packetid != PKT_ESC_SETPOINT_10 &&
packetid != PKT_ESC_SETPOINT_11 &&
packetid != PKT_ESC_SETPOINT_12 &&
packetid != PKT_ESC_SETPOINT_13 &&
packetid != PKT_ESC_SETPOINT_14 &&
packetid != PKT_ESC_SETPOINT_15 &&
packetid != PKT_ESC_SETPOINT_16 )
return 0;
if(_pg_numbytes < getESC_CommandMultipleESCsMinDataLength())
return 0;
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 1]
// Range of pwmValueA is 0 to 65535.
(*pwmValueA) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 2]
// Range of pwmValueB is 0 to 65535.
(*pwmValueB) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 3]
// Range of pwmValueC is 0 to 65535.
(*pwmValueC) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// The PWM (pulse width) command for ESC with CAN ID [PKT_ID + 4]
// Range of pwmValueD is 0 to 65535.
(*pwmValueD) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_CommandMultipleESCsPacket
/*!
* \brief Create the ESC_Disable packet
*
* Send this packet to the ESC to disable it. The ESC will not accept PWM/RPM
* commands until it is re-enabled.
* \param _pg_pkt points to the packet which will be created by this function
*/
void encodeESC_DisablePacket(void* _pg_pkt)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// This value must be set for the command to be accepted
uint8ToBytes((uint8_t)(ESC_DISABLE_A), _pg_data, &_pg_byteindex);
// This value must be set for the command to be accepted
uint8ToBytes((uint8_t)(ESC_DISABLE_B), _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_DisablePacketID());
}// encodeESC_DisablePacket
/*!
* \brief Decode the ESC_Disable packet
*
* Send this packet to the ESC to disable it. The ESC will not accept PWM/RPM
* commands until it is re-enabled.
* \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 decodeESC_DisablePacket(const void* _pg_pkt)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_DisablePacketID())
return 0;
if(_pg_numbytes < getESC_DisableMinDataLength())
return 0;
// This value must be set for the command to be accepted
if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) ESC_DISABLE_A)
return 0;
// This value must be set for the command to be accepted
if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) ESC_DISABLE_B)
return 0;
return 1;
}// decodeESC_DisablePacket
/*!
* \brief Create the ESC_Enable packet
*
* Send this packet to the ESC to enable it. The ESC will be placed in Standby
* mode.
* \param _pg_pkt points to the packet which will be created by this function
*/
void encodeESC_EnablePacket(void* _pg_pkt)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// This value must be set for the command to be accepted
uint8ToBytes((uint8_t)(ESC_ENABLE_A), _pg_data, &_pg_byteindex);
// This value must be set for the command to be included
uint8ToBytes((uint8_t)(ESC_ENABLE_B), _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_EnablePacketID());
}// encodeESC_EnablePacket
/*!
* \brief Decode the ESC_Enable packet
*
* Send this packet to the ESC to enable it. The ESC will be placed in Standby
* 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 decodeESC_EnablePacket(const void* _pg_pkt)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_EnablePacketID())
return 0;
if(_pg_numbytes < getESC_EnableMinDataLength())
return 0;
// This value must be set for the command to be accepted
if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) ESC_ENABLE_A)
return 0;
// This value must be set for the command to be included
if (uint8FromBytes(_pg_data, &_pg_byteindex) != (uint8_t) ESC_ENABLE_B)
return 0;
return 1;
}// decodeESC_EnablePacket
/*!
* \brief Create the ESC_PWMCommand packet
*
* Send a PWM (pulse width) command to an individual ESC. The pulse width value
* in specified in microseconds for compatibility with standard ESC interface.
* Use the broadcast ID (0xFF) to send this command to all ESCs on the CAN bus.
* \param _pg_pkt points to the packet which will be created by this function
* \param pwmCommand is PWM command
*/
void encodeESC_PWMCommandPacket(void* _pg_pkt, uint16_t pwmCommand)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// PWM command
// Range of pwmCommand is 0 to 65535.
uint16ToBeBytes(pwmCommand, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_PWMCommandPacketID());
}// encodeESC_PWMCommandPacket
/*!
* \brief Decode the ESC_PWMCommand packet
*
* Send a PWM (pulse width) command to an individual ESC. The pulse width value
* in specified in microseconds for compatibility with standard ESC interface.
* Use the broadcast ID (0xFF) to send this command to all ESCs on the CAN bus.
* \param _pg_pkt points to the packet being decoded by this function
* \param pwmCommand receives PWM command
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_PWMCommandPacket(const void* _pg_pkt, uint16_t* pwmCommand)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_PWMCommandPacketID())
return 0;
if(_pg_numbytes < getESC_PWMCommandMinDataLength())
return 0;
// PWM command
// Range of pwmCommand is 0 to 65535.
(*pwmCommand) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_PWMCommandPacket
/*!
* \brief Create the ESC_RPMCommand packet
*
* Send an RPM (speed) command to an individual ESC. Use the broadcast ID
* (0xFF) to send this command to all ESCs on the CAN bus
* \param _pg_pkt points to the packet which will be created by this function
* \param rpmCommand is RPM Command
*/
void encodeESC_RPMCommandPacket(void* _pg_pkt, uint16_t rpmCommand)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// RPM Command
// Range of rpmCommand is 0 to 65535.
uint16ToBeBytes(rpmCommand, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_RPMCommandPacketID());
}// encodeESC_RPMCommandPacket
/*!
* \brief Decode the ESC_RPMCommand packet
*
* Send an RPM (speed) command to an individual ESC. Use the broadcast ID
* (0xFF) to send this command to all ESCs on the CAN bus
* \param _pg_pkt points to the packet being decoded by this function
* \param rpmCommand receives RPM Command
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_RPMCommandPacket(const void* _pg_pkt, uint16_t* rpmCommand)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_RPMCommandPacketID())
return 0;
if(_pg_numbytes < getESC_RPMCommandMinDataLength())
return 0;
// RPM Command
// Range of rpmCommand is 0 to 65535.
(*rpmCommand) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_RPMCommandPacket
/*!
* \brief Create the ESC_VoltageCommand packet
*
* Send a voltage command to an individual ESC. Use the broadcast ID (0xFF) to
* send this command to all ESCs on the CAN bus
* \param _pg_pkt points to the packet which will be created by this function
* \param voltageCommand is
*/
void encodeESC_VoltageCommandPacket(void* _pg_pkt, uint16_t voltageCommand)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Range of voltageCommand is 0 to 65535.
uint16ToBeBytes(voltageCommand, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_VoltageCommandPacketID());
}// encodeESC_VoltageCommandPacket
/*!
* \brief Decode the ESC_VoltageCommand packet
*
* Send a voltage command to an individual ESC. Use the broadcast ID (0xFF) to
* send this command to all ESCs on the CAN bus
* \param _pg_pkt points to the packet being decoded by this function
* \param voltageCommand receives
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_VoltageCommandPacket(const void* _pg_pkt, uint16_t* voltageCommand)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_VoltageCommandPacketID())
return 0;
if(_pg_numbytes < getESC_VoltageCommandMinDataLength())
return 0;
// Range of voltageCommand is 0 to 65535.
(*voltageCommand) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_VoltageCommandPacket
/*!
* \brief Create the ESC_StatusA packet
*
* The ESC_STATUS_A packet contains high-priority ESC status information. This
* packet is transmitted by the ESC at regular (user-configurable) intervals.
* It can also be requested (polled) from the ESC by sending a zero-length
* packet of the same type.
* \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 encodeESC_StatusAPacketStructure(void* _pg_pkt, const ESC_StatusA_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Set to 1 to indicate a Gen-2 ESC
_pg_data[_pg_byteindex] = (uint8_t)1 << 7;
// Reserved for future use
// ESC operating mode. The lower four bits indicate the operational mode of the ESC, in accordance with the ESCOperatingModes enumeration. The upper three bits are used for debugging and should be ignored for general use.
// Range of mode is 0 to 15.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->mode, 15);
_pg_byteindex += 1; // close bit field
// ESC status bits
encodeESC_StatusBits_t(_pg_data, &_pg_byteindex, &_pg_user->status);
// ESC operational command - value depends on 'mode' available in this packet. If the ESC is disabled, data reads 0x0000. If the ESC is in open-loop PWM mode, this value is the PWM command in units of 1us, in the range 1000us to 2000us. If the ESC is in closed-loop RPM mode, this value is the RPM command in units of 1RPM
// Range of command is 0 to 65535.
uint16ToBeBytes(_pg_user->command, _pg_data, &_pg_byteindex);
// Motor speed
// Range of rpm is 0 to 65535.
uint16ToBeBytes(_pg_user->rpm, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusAPacketID());
}// encodeESC_StatusAPacketStructure
/*!
* \brief Decode the ESC_StatusA packet
*
* The ESC_STATUS_A packet contains high-priority ESC status information. This
* packet is transmitted by the ESC at regular (user-configurable) intervals.
* It can also be requested (polled) from the ESC by sending a zero-length
* packet of the same type.
* \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 decodeESC_StatusAPacketStructure(const void* _pg_pkt, ESC_StatusA_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
unsigned int _pg_tempbitfield = 0;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusAPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_StatusAMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Set to 1 to indicate a Gen-2 ESC
_pg_tempbitfield = (_pg_data[_pg_byteindex] >> 7);
// Decoded value must be 1
if(_pg_tempbitfield != 1)
return 0;
// Reserved for future use
// ESC operating mode. The lower four bits indicate the operational mode of the ESC, in accordance with the ESCOperatingModes enumeration. The upper three bits are used for debugging and should be ignored for general use.
// Range of mode is 0 to 15.
_pg_user->mode = ((_pg_data[_pg_byteindex]) & 0xF);
_pg_byteindex += 1; // close bit field
// ESC status bits
if(decodeESC_StatusBits_t(_pg_data, &_pg_byteindex, &_pg_user->status) == 0)
return 0;
// ESC operational command - value depends on 'mode' available in this packet. If the ESC is disabled, data reads 0x0000. If the ESC is in open-loop PWM mode, this value is the PWM command in units of 1us, in the range 1000us to 2000us. If the ESC is in closed-loop RPM mode, this value is the RPM command in units of 1RPM
// Range of command is 0 to 65535.
_pg_user->command = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Motor speed
// Range of rpm is 0 to 65535.
_pg_user->rpm = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_StatusAPacketStructure
/*!
* \brief Create the ESC_StatusA packet
*
* The ESC_STATUS_A packet contains high-priority ESC status information. This
* packet is transmitted by the ESC at regular (user-configurable) intervals.
* It can also be requested (polled) from the ESC by sending a zero-length
* packet of the same type.
* \param _pg_pkt points to the packet which will be created by this function
* \param mode is ESC operating mode. The lower four bits indicate the operational mode of the ESC, in accordance with the ESCOperatingModes enumeration. The upper three bits are used for debugging and should be ignored for general use.
* \param status is ESC status bits
* \param command is ESC operational command - value depends on 'mode' available in this packet. If the ESC is disabled, data reads 0x0000. If the ESC is in open-loop PWM mode, this value is the PWM command in units of 1us, in the range 1000us to 2000us. If the ESC is in closed-loop RPM mode, this value is the RPM command in units of 1RPM
* \param rpm is Motor speed
*/
void encodeESC_StatusAPacket(void* _pg_pkt, uint8_t mode, const ESC_StatusBits_t* status, uint16_t command, uint16_t rpm)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Set to 1 to indicate a Gen-2 ESC
_pg_data[_pg_byteindex] = (uint8_t)1 << 7;
// Reserved for future use
// ESC operating mode. The lower four bits indicate the operational mode of the ESC, in accordance with the ESCOperatingModes enumeration. The upper three bits are used for debugging and should be ignored for general use.
// Range of mode is 0 to 15.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(mode, 15);
_pg_byteindex += 1; // close bit field
// ESC status bits
encodeESC_StatusBits_t(_pg_data, &_pg_byteindex, status);
// ESC operational command - value depends on 'mode' available in this packet. If the ESC is disabled, data reads 0x0000. If the ESC is in open-loop PWM mode, this value is the PWM command in units of 1us, in the range 1000us to 2000us. If the ESC is in closed-loop RPM mode, this value is the RPM command in units of 1RPM
// Range of command is 0 to 65535.
uint16ToBeBytes(command, _pg_data, &_pg_byteindex);
// Motor speed
// Range of rpm is 0 to 65535.
uint16ToBeBytes(rpm, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusAPacketID());
}// encodeESC_StatusAPacket
/*!
* \brief Decode the ESC_StatusA packet
*
* The ESC_STATUS_A packet contains high-priority ESC status information. This
* packet is transmitted by the ESC at regular (user-configurable) intervals.
* It can also be requested (polled) from the ESC by sending a zero-length
* packet of the same type.
* \param _pg_pkt points to the packet being decoded by this function
* \param mode receives ESC operating mode. The lower four bits indicate the operational mode of the ESC, in accordance with the ESCOperatingModes enumeration. The upper three bits are used for debugging and should be ignored for general use.
* \param status receives ESC status bits
* \param command receives ESC operational command - value depends on 'mode' available in this packet. If the ESC is disabled, data reads 0x0000. If the ESC is in open-loop PWM mode, this value is the PWM command in units of 1us, in the range 1000us to 2000us. If the ESC is in closed-loop RPM mode, this value is the RPM command in units of 1RPM
* \param rpm receives Motor speed
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_StatusAPacket(const void* _pg_pkt, uint8_t* mode, ESC_StatusBits_t* status, uint16_t* command, uint16_t* rpm)
{
unsigned int _pg_tempbitfield = 0;
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusAPacketID())
return 0;
if(_pg_numbytes < getESC_StatusAMinDataLength())
return 0;
// Set to 1 to indicate a Gen-2 ESC
_pg_tempbitfield = (_pg_data[_pg_byteindex] >> 7);
// Decoded value must be 1
if(_pg_tempbitfield != 1)
return 0;
// Reserved for future use
// ESC operating mode. The lower four bits indicate the operational mode of the ESC, in accordance with the ESCOperatingModes enumeration. The upper three bits are used for debugging and should be ignored for general use.
// Range of mode is 0 to 15.
(*mode) = ((_pg_data[_pg_byteindex]) & 0xF);
_pg_byteindex += 1; // close bit field
// ESC status bits
if(decodeESC_StatusBits_t(_pg_data, &_pg_byteindex, status) == 0)
return 0;
// ESC operational command - value depends on 'mode' available in this packet. If the ESC is disabled, data reads 0x0000. If the ESC is in open-loop PWM mode, this value is the PWM command in units of 1us, in the range 1000us to 2000us. If the ESC is in closed-loop RPM mode, this value is the RPM command in units of 1RPM
// Range of command is 0 to 65535.
(*command) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Motor speed
// Range of rpm is 0 to 65535.
(*rpm) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_StatusAPacket
/*!
* \brief Create the ESC_StatusB packet
*
* The ESC_STATUS_B packet contains ESC operational information. This packet is
* transmitted by the ESC at regular (user-configurable) intervals. It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \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 encodeESC_StatusBPacketStructure(void* _pg_pkt, const ESC_StatusB_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// ESC Rail Voltage
// Range of voltage is 0 to 65535.
uint16ToBeBytes(_pg_user->voltage, _pg_data, &_pg_byteindex);
// ESC Current. Current IN to the ESC is positive. Current OUT of the ESC is negative
// Range of current is -32768 to 32767.
int16ToBeBytes(_pg_user->current, _pg_data, &_pg_byteindex);
// ESC Motor Duty Cycle
// Range of dutyCycle is 0 to 65535.
uint16ToBeBytes(_pg_user->dutyCycle, _pg_data, &_pg_byteindex);
// ESC Logic Board Temperature
// Range of escTemperature is -128 to 127.
int8ToBytes(_pg_user->escTemperature, _pg_data, &_pg_byteindex);
// ESC Motor Temperature
// Range of motorTemperature is 0 to 255.
uint8ToBytes(_pg_user->motorTemperature, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusBPacketID());
}// encodeESC_StatusBPacketStructure
/*!
* \brief Decode the ESC_StatusB packet
*
* The ESC_STATUS_B packet contains ESC operational information. This packet is
* transmitted by the ESC at regular (user-configurable) intervals. It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \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 decodeESC_StatusBPacketStructure(const void* _pg_pkt, ESC_StatusB_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusBPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_StatusBMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// ESC Rail Voltage
// Range of voltage is 0 to 65535.
_pg_user->voltage = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC Current. Current IN to the ESC is positive. Current OUT of the ESC is negative
// Range of current is -32768 to 32767.
_pg_user->current = int16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC Motor Duty Cycle
// Range of dutyCycle is 0 to 65535.
_pg_user->dutyCycle = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC Logic Board Temperature
// Range of escTemperature is -128 to 127.
_pg_user->escTemperature = int8FromBytes(_pg_data, &_pg_byteindex);
// ESC Motor Temperature
// Range of motorTemperature is 0 to 255.
_pg_user->motorTemperature = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_StatusBPacketStructure
/*!
* \brief Create the ESC_StatusB packet
*
* The ESC_STATUS_B packet contains ESC operational information. This packet is
* transmitted by the ESC at regular (user-configurable) intervals. It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \param _pg_pkt points to the packet which will be created by this function
* \param voltage is ESC Rail Voltage
* \param current is ESC Current. Current IN to the ESC is positive. Current OUT of the ESC is negative
* \param dutyCycle is ESC Motor Duty Cycle
* \param escTemperature is ESC Logic Board Temperature
* \param motorTemperature is ESC Motor Temperature
*/
void encodeESC_StatusBPacket(void* _pg_pkt, uint16_t voltage, int16_t current, uint16_t dutyCycle, int8_t escTemperature, uint8_t motorTemperature)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// ESC Rail Voltage
// Range of voltage is 0 to 65535.
uint16ToBeBytes(voltage, _pg_data, &_pg_byteindex);
// ESC Current. Current IN to the ESC is positive. Current OUT of the ESC is negative
// Range of current is -32768 to 32767.
int16ToBeBytes(current, _pg_data, &_pg_byteindex);
// ESC Motor Duty Cycle
// Range of dutyCycle is 0 to 65535.
uint16ToBeBytes(dutyCycle, _pg_data, &_pg_byteindex);
// ESC Logic Board Temperature
// Range of escTemperature is -128 to 127.
int8ToBytes(escTemperature, _pg_data, &_pg_byteindex);
// ESC Motor Temperature
// Range of motorTemperature is 0 to 255.
uint8ToBytes(motorTemperature, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusBPacketID());
}// encodeESC_StatusBPacket
/*!
* \brief Decode the ESC_StatusB packet
*
* The ESC_STATUS_B packet contains ESC operational information. This packet is
* transmitted by the ESC at regular (user-configurable) intervals. It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \param _pg_pkt points to the packet being decoded by this function
* \param voltage receives ESC Rail Voltage
* \param current receives ESC Current. Current IN to the ESC is positive. Current OUT of the ESC is negative
* \param dutyCycle receives ESC Motor Duty Cycle
* \param escTemperature receives ESC Logic Board Temperature
* \param motorTemperature receives ESC Motor Temperature
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_StatusBPacket(const void* _pg_pkt, uint16_t* voltage, int16_t* current, uint16_t* dutyCycle, int8_t* escTemperature, uint8_t* motorTemperature)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusBPacketID())
return 0;
if(_pg_numbytes < getESC_StatusBMinDataLength())
return 0;
// ESC Rail Voltage
// Range of voltage is 0 to 65535.
(*voltage) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC Current. Current IN to the ESC is positive. Current OUT of the ESC is negative
// Range of current is -32768 to 32767.
(*current) = int16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC Motor Duty Cycle
// Range of dutyCycle is 0 to 65535.
(*dutyCycle) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC Logic Board Temperature
// Range of escTemperature is -128 to 127.
(*escTemperature) = int8FromBytes(_pg_data, &_pg_byteindex);
// ESC Motor Temperature
// Range of motorTemperature is 0 to 255.
(*motorTemperature) = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_StatusBPacket
/*!
* \brief Create the ESC_StatusC packet
*
* The ESC_STATUS_C packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \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 encodeESC_StatusCPacketStructure(void* _pg_pkt, const ESC_StatusC_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Reserved for future use
int16ToBeBytes((int16_t)(0), _pg_data, &_pg_byteindex);
// ESC Phase Board Temperature
// Range of fetTemperature is -50.0f to 205.0f.
float32ScaledTo1UnsignedBytes(_pg_user->fetTemperature, _pg_data, &_pg_byteindex, -50.0f, 1.0f);
// Current motor PWM frequency (10 Hz per bit)
// Range of pwmFrequency is 0 to 65535.
uint16ToBeBytes(_pg_user->pwmFrequency, _pg_data, &_pg_byteindex);
// Current timing advance (0.1 degree per bit)
// Range of timingAdvance is 0 to 65535.
uint16ToBeBytes(_pg_user->timingAdvance, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusCPacketID());
}// encodeESC_StatusCPacketStructure
/*!
* \brief Decode the ESC_StatusC packet
*
* The ESC_STATUS_C packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \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 decodeESC_StatusCPacketStructure(const void* _pg_pkt, ESC_StatusC_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusCPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_StatusCMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Reserved for future use
_pg_byteindex += 2;
// ESC Phase Board Temperature
// Range of fetTemperature is -50.0f to 205.0f.
_pg_user->fetTemperature = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, -50.0f, 1.0f/1.0f);
// Current motor PWM frequency (10 Hz per bit)
// Range of pwmFrequency is 0 to 65535.
_pg_user->pwmFrequency = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Current timing advance (0.1 degree per bit)
// Range of timingAdvance is 0 to 65535.
_pg_user->timingAdvance = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_StatusCPacketStructure
/*!
* \brief Create the ESC_StatusC packet
*
* The ESC_STATUS_C packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \param _pg_pkt points to the packet which will be created by this function
* \param fetTemperature is ESC Phase Board Temperature
* \param pwmFrequency is Current motor PWM frequency (10 Hz per bit)
* \param timingAdvance is Current timing advance (0.1 degree per bit)
*/
void encodeESC_StatusCPacket(void* _pg_pkt, float fetTemperature, uint16_t pwmFrequency, uint16_t timingAdvance)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Reserved for future use
int16ToBeBytes((int16_t)(0), _pg_data, &_pg_byteindex);
// ESC Phase Board Temperature
// Range of fetTemperature is -50.0f to 205.0f.
float32ScaledTo1UnsignedBytes(fetTemperature, _pg_data, &_pg_byteindex, -50.0f, 1.0f);
// Current motor PWM frequency (10 Hz per bit)
// Range of pwmFrequency is 0 to 65535.
uint16ToBeBytes(pwmFrequency, _pg_data, &_pg_byteindex);
// Current timing advance (0.1 degree per bit)
// Range of timingAdvance is 0 to 65535.
uint16ToBeBytes(timingAdvance, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusCPacketID());
}// encodeESC_StatusCPacket
/*!
* \brief Decode the ESC_StatusC packet
*
* The ESC_STATUS_C packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \param _pg_pkt points to the packet being decoded by this function
* \param fetTemperature receives ESC Phase Board Temperature
* \param pwmFrequency receives Current motor PWM frequency (10 Hz per bit)
* \param timingAdvance receives Current timing advance (0.1 degree per bit)
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_StatusCPacket(const void* _pg_pkt, float* fetTemperature, uint16_t* pwmFrequency, uint16_t* timingAdvance)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusCPacketID())
return 0;
if(_pg_numbytes < getESC_StatusCMinDataLength())
return 0;
// Reserved for future use
_pg_byteindex += 2;
// ESC Phase Board Temperature
// Range of fetTemperature is -50.0f to 205.0f.
(*fetTemperature) = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, -50.0f, 1.0f/1.0f);
// Current motor PWM frequency (10 Hz per bit)
// Range of pwmFrequency is 0 to 65535.
(*pwmFrequency) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Current timing advance (0.1 degree per bit)
// Range of timingAdvance is 0 to 65535.
(*timingAdvance) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_StatusCPacket
/*!
* \brief Create the ESC_StatusD packet
*
* The ESC_STATUS_D packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \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 encodeESC_StatusDPacketStructure(void* _pg_pkt, const ESC_StatusD_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned _pg_i = 0;
// Reserved for future use
_pg_data[_pg_byteindex] = 0;
// Measured demag angle of motor
// Range of demagAngle is 0 to 127.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->demagAngle, 127);
_pg_byteindex += 1; // close bit field
// Reserved for future packet expansion
for(_pg_i = 0; _pg_i < 7; _pg_i++)
uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusDPacketID());
}// encodeESC_StatusDPacketStructure
/*!
* \brief Decode the ESC_StatusD packet
*
* The ESC_STATUS_D packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \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 decodeESC_StatusDPacketStructure(const void* _pg_pkt, ESC_StatusD_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusDPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_StatusDMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Reserved for future use
// Measured demag angle of motor
// Range of demagAngle is 0 to 127.
_pg_user->demagAngle = ((_pg_data[_pg_byteindex]) & 0x7F);
_pg_byteindex += 1; // close bit field
// Reserved for future packet expansion
_pg_byteindex += 1*7;
return 1;
}// decodeESC_StatusDPacketStructure
/*!
* \brief Create the ESC_StatusD packet
*
* The ESC_STATUS_D packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \param _pg_pkt points to the packet which will be created by this function
* \param demagAngle is Measured demag angle of motor
*/
void encodeESC_StatusDPacket(void* _pg_pkt, uint8_t demagAngle)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned _pg_i = 0;
// Reserved for future use
_pg_data[_pg_byteindex] = 0;
// Measured demag angle of motor
// Range of demagAngle is 0 to 127.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(demagAngle, 127);
_pg_byteindex += 1; // close bit field
// Reserved for future packet expansion
for(_pg_i = 0; _pg_i < 7; _pg_i++)
uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_StatusDPacketID());
}// encodeESC_StatusDPacket
/*!
* \brief Decode the ESC_StatusD packet
*
* The ESC_STATUS_D packet contains ESC operational information. This packet is
* transmitted by the ESC at regular intervals (user-configurable). It can also
* be requested (polled) from the ESC by sending a zero-length packet of the
* same type.
* \param _pg_pkt points to the packet being decoded by this function
* \param demagAngle receives Measured demag angle of motor
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_StatusDPacket(const void* _pg_pkt, uint8_t* demagAngle)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_StatusDPacketID())
return 0;
if(_pg_numbytes < getESC_StatusDMinDataLength())
return 0;
// Reserved for future use
// Measured demag angle of motor
// Range of demagAngle is 0 to 127.
(*demagAngle) = ((_pg_data[_pg_byteindex]) & 0x7F);
_pg_byteindex += 1; // close bit field
// Reserved for future packet expansion
_pg_byteindex += 1*7;
return 1;
}// decodeESC_StatusDPacket
/*!
* \brief Create the ESC_WarningErrorStatus packet
*
* Warning and error status information. If any warning or error flags are set,
* this packet is transmitted by the ESC at 10Hz. If there are no warning or
* error flags set, the packet is transmitted by the ESC at 1Hz.
* \param _pg_pkt points to the packet which will be created by this function
* \param warnings is ESC warning bitfield
* \param errors is ESC error bitfield
* \param extended is Set to indicate that this packet contains extended warning and error information
* \param warningsExtended is Extension of ESC warning bitfield
* \param errorsExtended is Extension of ESC error bifield
*/
void encodeESC_WarningErrorStatusPacket(void* _pg_pkt, const ESC_WarningBits_t* warnings, const ESC_ErrorBits_t* errors, uint8_t extended, const ESC_WarningBits_t* warningsExtended, const ESC_ErrorBits_t* errorsExtended)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// ESC warning bitfield
encodeESC_WarningBits_t(_pg_data, &_pg_byteindex, warnings);
// ESC error bitfield
encodeESC_ErrorBits_t(_pg_data, &_pg_byteindex, errors);
// Set to indicate that this packet contains extended warning and error information
// Range of extended is 0 to 255.
uint8ToBytes(extended, _pg_data, &_pg_byteindex);
// Extension of ESC warning bitfield
if(extended)
{
encodeESC_ExtendedWarningBits_t(_pg_data, &_pg_byteindex, warningsExtended);
}
// Extension of ESC error bifield
if(extended)
{
encodeESC_ExtendedErrorBits_t(_pg_data, &_pg_byteindex, errorsExtended);
}
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_WarningErrorStatusPacketID());
}// encodeESC_WarningErrorStatusPacket
/*!
* \brief Decode the ESC_WarningErrorStatus packet
*
* Warning and error status information. If any warning or error flags are set,
* this packet is transmitted by the ESC at 10Hz. If there are no warning or
* error flags set, the packet is transmitted by the ESC at 1Hz.
* \param _pg_pkt points to the packet being decoded by this function
* \param warnings receives ESC warning bitfield
* \param errors receives ESC error bitfield
* \param extended receives Set to indicate that this packet contains extended warning and error information
* \param warningsExtended receives Extension of ESC warning bitfield
* \param errorsExtended receives Extension of ESC error bifield
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_WarningErrorStatusPacket(const void* _pg_pkt, ESC_WarningBits_t* warnings, ESC_ErrorBits_t* errors, uint8_t* extended, ESC_WarningBits_t* warningsExtended, ESC_ErrorBits_t* errorsExtended)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_WarningErrorStatusPacketID())
return 0;
if(_pg_numbytes < getESC_WarningErrorStatusMinDataLength())
return 0;
// this packet has default fields, make sure they are set
(*extended) = 0;
// ESC warning bitfield
if(decodeESC_WarningBits_t(_pg_data, &_pg_byteindex, warnings) == 0)
return 0;
// ESC error bitfield
if(decodeESC_ErrorBits_t(_pg_data, &_pg_byteindex, errors) == 0)
return 0;
if(_pg_byteindex + 1 > _pg_numbytes)
return 1;
// Set to indicate that this packet contains extended warning and error information
// Range of extended is 0 to 255.
(*extended) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Extension of ESC warning bitfield
if((*extended))
{
if(decodeESC_ExtendedWarningBits_t(_pg_data, &_pg_byteindex, warningsExtended) == 0)
return 0;
}
// Extension of ESC error bifield
if((*extended))
{
if(decodeESC_ExtendedErrorBits_t(_pg_data, &_pg_byteindex, errorsExtended) == 0)
return 0;
}
return 1;
}// decodeESC_WarningErrorStatusPacket
/*!
* \brief Create the ESC_ControlLoopOutputs packet
*
* This packet contains the current output values for the RPM controller.
* \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 encodeESC_ControlLoopOutputsPacketStructure(void* _pg_pkt, const ESC_ControlLoopOutputs_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Range of pTerm is -500.0f to 500.0f.
float32ScaledTo2SignedBeBytes(_pg_user->pTerm, _pg_data, &_pg_byteindex, 65.534f);
// Range of iTerm is -500.0f to 500.0f.
float32ScaledTo2SignedBeBytes(_pg_user->iTerm, _pg_data, &_pg_byteindex, 65.534f);
// Range of fTerm is -500.0f to 500.0f.
float32ScaledTo2SignedBeBytes(_pg_user->fTerm, _pg_data, &_pg_byteindex, 65.534f);
// Output duty cycle
// Range of output is -32768 to 32767.
int16ToBeBytes(_pg_user->output, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ControlLoopOutputsPacketID());
}// encodeESC_ControlLoopOutputsPacketStructure
/*!
* \brief Decode the ESC_ControlLoopOutputs packet
*
* This packet contains the current output values for the RPM controller.
* \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 decodeESC_ControlLoopOutputsPacketStructure(const void* _pg_pkt, ESC_ControlLoopOutputs_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ControlLoopOutputsPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_ControlLoopOutputsMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Range of pTerm is -500.0f to 500.0f.
_pg_user->pTerm = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
// Range of iTerm is -500.0f to 500.0f.
_pg_user->iTerm = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
// Range of fTerm is -500.0f to 500.0f.
_pg_user->fTerm = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
// Output duty cycle
// Range of output is -32768 to 32767.
_pg_user->output = int16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_ControlLoopOutputsPacketStructure
/*!
* \brief Create the ESC_ControlLoopOutputs packet
*
* This packet contains the current output values for the RPM controller.
* \param _pg_pkt points to the packet which will be created by this function
* \param pTerm is
* \param iTerm is
* \param fTerm is
* \param output is Output duty cycle
*/
void encodeESC_ControlLoopOutputsPacket(void* _pg_pkt, float pTerm, float iTerm, float fTerm, int16_t output)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Range of pTerm is -500.0f to 500.0f.
float32ScaledTo2SignedBeBytes(pTerm, _pg_data, &_pg_byteindex, 65.534f);
// Range of iTerm is -500.0f to 500.0f.
float32ScaledTo2SignedBeBytes(iTerm, _pg_data, &_pg_byteindex, 65.534f);
// Range of fTerm is -500.0f to 500.0f.
float32ScaledTo2SignedBeBytes(fTerm, _pg_data, &_pg_byteindex, 65.534f);
// Output duty cycle
// Range of output is -32768 to 32767.
int16ToBeBytes(output, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ControlLoopOutputsPacketID());
}// encodeESC_ControlLoopOutputsPacket
/*!
* \brief Decode the ESC_ControlLoopOutputs packet
*
* This packet contains the current output values for the RPM controller.
* \param _pg_pkt points to the packet being decoded by this function
* \param pTerm receives
* \param iTerm receives
* \param fTerm receives
* \param output receives Output duty cycle
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_ControlLoopOutputsPacket(const void* _pg_pkt, float* pTerm, float* iTerm, float* fTerm, int16_t* output)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ControlLoopOutputsPacketID())
return 0;
if(_pg_numbytes < getESC_ControlLoopOutputsMinDataLength())
return 0;
// Range of pTerm is -500.0f to 500.0f.
(*pTerm) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
// Range of iTerm is -500.0f to 500.0f.
(*iTerm) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
// Range of fTerm is -500.0f to 500.0f.
(*fTerm) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/65.534f);
// Output duty cycle
// Range of output is -32768 to 32767.
(*output) = int16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_ControlLoopOutputsPacket
/*!
* \brief Create the ESC_HallSensorInfo packet
*
* This packet contains information on the hall sensor
* \param _pg_pkt points to the packet which will be created by this function
* \param detectedPattern is
*/
void encodeESC_HallSensorInfoPacket(void* _pg_pkt, const ESC_HallSensorPattern_t* detectedPattern)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
encodeESC_HallSensorPattern_t(_pg_data, &_pg_byteindex, detectedPattern);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_HallSensorInfoPacketID());
}// encodeESC_HallSensorInfoPacket
/*!
* \brief Decode the ESC_HallSensorInfo packet
*
* This packet contains information on the hall sensor
* \param _pg_pkt points to the packet being decoded by this function
* \param detectedPattern receives
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_HallSensorInfoPacket(const void* _pg_pkt, ESC_HallSensorPattern_t* detectedPattern)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_HallSensorInfoPacketID())
return 0;
if(_pg_numbytes < getESC_HallSensorInfoMinDataLength())
return 0;
if(decodeESC_HallSensorPattern_t(_pg_data, &_pg_byteindex, detectedPattern) == 0)
return 0;
return 1;
}// decodeESC_HallSensorInfoPacket
/*!
* \brief Create the ESC_MotorStatusFlags packet
*
* Motor status flags. If any warning or error flags are set, this packet is
* transmitted by the ESC at 10Hz. If there are no warning or error flags set,
* the packet is transmitted by the ESC at 1Hz.
* \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 encodeESC_MotorStatusFlagsPacketStructure(void* _pg_pkt, const ESC_MotorStatusFlags_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Cause of most recent standby event
// Range of standbyCause is 0 to 65535.
uint16ToBeBytes(_pg_user->standbyCause, _pg_data, &_pg_byteindex);
// Cause of most recent disable event
// Range of disableCause is 0 to 65535.
uint16ToBeBytes(_pg_user->disableCause, _pg_data, &_pg_byteindex);
// Cause of most recent motor-stop event
// Range of offCause is 0 to 65535.
uint16ToBeBytes(_pg_user->offCause, _pg_data, &_pg_byteindex);
// Cause of most recent failed-start
// Range of failedStartCause is 0 to 65535.
uint16ToBeBytes(_pg_user->failedStartCause, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_MotorStatusFlagsPacketID());
}// encodeESC_MotorStatusFlagsPacketStructure
/*!
* \brief Decode the ESC_MotorStatusFlags packet
*
* Motor status flags. If any warning or error flags are set, this packet is
* transmitted by the ESC at 10Hz. If there are no warning or error flags set,
* the packet is transmitted by the ESC at 1Hz.
* \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 decodeESC_MotorStatusFlagsPacketStructure(const void* _pg_pkt, ESC_MotorStatusFlags_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_MotorStatusFlagsPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_MotorStatusFlagsMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Cause of most recent standby event
// Range of standbyCause is 0 to 65535.
_pg_user->standbyCause = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Cause of most recent disable event
// Range of disableCause is 0 to 65535.
_pg_user->disableCause = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Cause of most recent motor-stop event
// Range of offCause is 0 to 65535.
_pg_user->offCause = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Cause of most recent failed-start
// Range of failedStartCause is 0 to 65535.
_pg_user->failedStartCause = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_MotorStatusFlagsPacketStructure
/*!
* \brief Create the ESC_MotorStatusFlags packet
*
* Motor status flags. If any warning or error flags are set, this packet is
* transmitted by the ESC at 10Hz. If there are no warning or error flags set,
* the packet is transmitted by the ESC at 1Hz.
* \param _pg_pkt points to the packet which will be created by this function
* \param standbyCause is Cause of most recent standby event
* \param disableCause is Cause of most recent disable event
* \param offCause is Cause of most recent motor-stop event
* \param failedStartCause is Cause of most recent failed-start
*/
void encodeESC_MotorStatusFlagsPacket(void* _pg_pkt, uint16_t standbyCause, uint16_t disableCause, uint16_t offCause, uint16_t failedStartCause)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Cause of most recent standby event
// Range of standbyCause is 0 to 65535.
uint16ToBeBytes(standbyCause, _pg_data, &_pg_byteindex);
// Cause of most recent disable event
// Range of disableCause is 0 to 65535.
uint16ToBeBytes(disableCause, _pg_data, &_pg_byteindex);
// Cause of most recent motor-stop event
// Range of offCause is 0 to 65535.
uint16ToBeBytes(offCause, _pg_data, &_pg_byteindex);
// Cause of most recent failed-start
// Range of failedStartCause is 0 to 65535.
uint16ToBeBytes(failedStartCause, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_MotorStatusFlagsPacketID());
}// encodeESC_MotorStatusFlagsPacket
/*!
* \brief Decode the ESC_MotorStatusFlags packet
*
* Motor status flags. If any warning or error flags are set, this packet is
* transmitted by the ESC at 10Hz. If there are no warning or error flags set,
* the packet is transmitted by the ESC at 1Hz.
* \param _pg_pkt points to the packet being decoded by this function
* \param standbyCause receives Cause of most recent standby event
* \param disableCause receives Cause of most recent disable event
* \param offCause receives Cause of most recent motor-stop event
* \param failedStartCause receives Cause of most recent failed-start
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_MotorStatusFlagsPacket(const void* _pg_pkt, uint16_t* standbyCause, uint16_t* disableCause, uint16_t* offCause, uint16_t* failedStartCause)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_MotorStatusFlagsPacketID())
return 0;
if(_pg_numbytes < getESC_MotorStatusFlagsMinDataLength())
return 0;
// Cause of most recent standby event
// Range of standbyCause is 0 to 65535.
(*standbyCause) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Cause of most recent disable event
// Range of disableCause is 0 to 65535.
(*disableCause) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Cause of most recent motor-stop event
// Range of offCause is 0 to 65535.
(*offCause) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Cause of most recent failed-start
// Range of failedStartCause is 0 to 65535.
(*failedStartCause) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_MotorStatusFlagsPacket
/*!
* \brief Create the ESC_VoltageControlLoopSettings packet
*
* Voltage 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 encodeESC_VoltageControlLoopSettingsPacketStructure(void* _pg_pkt, const ESC_VoltageControlLoopSettings_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Core control loop settings
encodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, &_pg_user->pid);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_VoltageControlLoopSettingsPacketID());
}// encodeESC_VoltageControlLoopSettingsPacketStructure
/*!
* \brief Decode the ESC_VoltageControlLoopSettings packet
*
* Voltage 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 decodeESC_VoltageControlLoopSettingsPacketStructure(const void* _pg_pkt, ESC_VoltageControlLoopSettings_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_VoltageControlLoopSettingsPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_VoltageControlLoopSettingsMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Core control loop settings
if(decodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, &_pg_user->pid) == 0)
return 0;
return 1;
}// decodeESC_VoltageControlLoopSettingsPacketStructure
/*!
* \brief Create the ESC_VoltageControlLoopSettings packet
*
* Voltage control loop settings
* \param _pg_pkt points to the packet which will be created by this function
* \param pid is Core control loop settings
*/
void encodeESC_VoltageControlLoopSettingsPacket(void* _pg_pkt, const ESC_ControlLoopCommon_t* pid)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Core control loop settings
encodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, pid);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_VoltageControlLoopSettingsPacketID());
}// encodeESC_VoltageControlLoopSettingsPacket
/*!
* \brief Decode the ESC_VoltageControlLoopSettings packet
*
* Voltage control loop settings
* \param _pg_pkt points to the packet being decoded by this function
* \param pid receives Core control loop settings
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_VoltageControlLoopSettingsPacket(const void* _pg_pkt, ESC_ControlLoopCommon_t* pid)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_VoltageControlLoopSettingsPacketID())
return 0;
if(_pg_numbytes < getESC_VoltageControlLoopSettingsMinDataLength())
return 0;
// Core control loop settings
if(decodeESC_ControlLoopCommon_t(_pg_data, &_pg_byteindex, pid) == 0)
return 0;
return 1;
}// decodeESC_VoltageControlLoopSettingsPacket
/*!
* \brief Create the ESC_ProtectionValues packet
*
* ESC self-protection 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 encodeESC_ProtectionValuesPacketStructure(void* _pg_pkt, const ESC_ProtectionValues_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Maximum allowable DC bus current
// Range of overcurrentBus is 0.0f to 1275.0f.
float32ScaledTo1UnsignedBytes(_pg_user->overcurrentBus, _pg_data, &_pg_byteindex, 0.0f, 0.2f);
// Maximum allowable motor phase current
// Range of overcurrentPhase is 0.0f to 1275.0f.
float32ScaledTo1UnsignedBytes(_pg_user->overcurrentPhase, _pg_data, &_pg_byteindex, 0.0f, 0.2f);
// Maximum allowable regen current
// Range of overcurrentRegen is 0.0f to 1275.0f.
float32ScaledTo1UnsignedBytes(_pg_user->overcurrentRegen, _pg_data, &_pg_byteindex, 0.0f, 0.2f);
// Maximum allowable internal temperature
// Range of overtemperatureInternal is 0 to 255.
uint8ToBytes(_pg_user->overtemperatureInternal, _pg_data, &_pg_byteindex);
// Maximum allowable motor temperature
// Range of overtemperatureMotor is 0 to 255.
uint8ToBytes(_pg_user->overtemperatureMotor, _pg_data, &_pg_byteindex);
// Maximum motor speed
// Range of overspeed is 0 to 65535.
uint16ToBeBytes(_pg_user->overspeed, _pg_data, &_pg_byteindex);
// ESC undervoltage warning threshold
// Range of undervoltage is 0 to 255.
uint8ToBytes(_pg_user->undervoltage, _pg_data, &_pg_byteindex);
// ESC overvoltage warning threshold
// Range of overvoltage is 0 to 255.
uint8ToBytes(_pg_user->overvoltage, _pg_data, &_pg_byteindex);
// Maximum allowable demag angle
// Range of demagAngle is 0 to 255.
uint8ToBytes(_pg_user->demagAngle, _pg_data, &_pg_byteindex);
// Maximum allowable timing advance
// Range of timingAdvance is 0 to 255.
uint8ToBytes(_pg_user->timingAdvance, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ProtectionValuesPacketID());
}// encodeESC_ProtectionValuesPacketStructure
/*!
* \brief Decode the ESC_ProtectionValues packet
*
* ESC self-protection 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 decodeESC_ProtectionValuesPacketStructure(const void* _pg_pkt, ESC_ProtectionValues_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ProtectionValuesPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_ProtectionValuesMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// this packet has default fields, make sure they are set
_pg_user->timingAdvance = 20;
// Maximum allowable DC bus current
// Range of overcurrentBus is 0.0f to 1275.0f.
_pg_user->overcurrentBus = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/0.2f);
// Maximum allowable motor phase current
// Range of overcurrentPhase is 0.0f to 1275.0f.
_pg_user->overcurrentPhase = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/0.2f);
// Maximum allowable regen current
// Range of overcurrentRegen is 0.0f to 1275.0f.
_pg_user->overcurrentRegen = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/0.2f);
// Maximum allowable internal temperature
// Range of overtemperatureInternal is 0 to 255.
_pg_user->overtemperatureInternal = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum allowable motor temperature
// Range of overtemperatureMotor is 0 to 255.
_pg_user->overtemperatureMotor = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum motor speed
// Range of overspeed is 0 to 65535.
_pg_user->overspeed = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC undervoltage warning threshold
// Range of undervoltage is 0 to 255.
_pg_user->undervoltage = uint8FromBytes(_pg_data, &_pg_byteindex);
// ESC overvoltage warning threshold
// Range of overvoltage is 0 to 255.
_pg_user->overvoltage = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum allowable demag angle
// Range of demagAngle is 0 to 255.
_pg_user->demagAngle = uint8FromBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 1 > _pg_numbytes)
return 1;
// Maximum allowable timing advance
// Range of timingAdvance is 0 to 255.
_pg_user->timingAdvance = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_ProtectionValuesPacketStructure
/*!
* \brief Create the ESC_ProtectionValues packet
*
* ESC self-protection settings
* \param _pg_pkt points to the packet which will be created by this function
* \param overcurrentBus is Maximum allowable DC bus current
* \param overcurrentPhase is Maximum allowable motor phase current
* \param overcurrentRegen is Maximum allowable regen current
* \param overtemperatureInternal is Maximum allowable internal temperature
* \param overtemperatureMotor is Maximum allowable motor temperature
* \param overspeed is Maximum motor speed
* \param undervoltage is ESC undervoltage warning threshold
* \param overvoltage is ESC overvoltage warning threshold
* \param demagAngle is Maximum allowable demag angle
* \param timingAdvance is Maximum allowable timing advance
*/
void encodeESC_ProtectionValuesPacket(void* _pg_pkt, float overcurrentBus, float overcurrentPhase, float overcurrentRegen, uint8_t overtemperatureInternal, uint8_t overtemperatureMotor, uint16_t overspeed, uint8_t undervoltage, uint8_t overvoltage, uint8_t demagAngle, uint8_t timingAdvance)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Maximum allowable DC bus current
// Range of overcurrentBus is 0.0f to 1275.0f.
float32ScaledTo1UnsignedBytes(overcurrentBus, _pg_data, &_pg_byteindex, 0.0f, 0.2f);
// Maximum allowable motor phase current
// Range of overcurrentPhase is 0.0f to 1275.0f.
float32ScaledTo1UnsignedBytes(overcurrentPhase, _pg_data, &_pg_byteindex, 0.0f, 0.2f);
// Maximum allowable regen current
// Range of overcurrentRegen is 0.0f to 1275.0f.
float32ScaledTo1UnsignedBytes(overcurrentRegen, _pg_data, &_pg_byteindex, 0.0f, 0.2f);
// Maximum allowable internal temperature
// Range of overtemperatureInternal is 0 to 255.
uint8ToBytes(overtemperatureInternal, _pg_data, &_pg_byteindex);
// Maximum allowable motor temperature
// Range of overtemperatureMotor is 0 to 255.
uint8ToBytes(overtemperatureMotor, _pg_data, &_pg_byteindex);
// Maximum motor speed
// Range of overspeed is 0 to 65535.
uint16ToBeBytes(overspeed, _pg_data, &_pg_byteindex);
// ESC undervoltage warning threshold
// Range of undervoltage is 0 to 255.
uint8ToBytes(undervoltage, _pg_data, &_pg_byteindex);
// ESC overvoltage warning threshold
// Range of overvoltage is 0 to 255.
uint8ToBytes(overvoltage, _pg_data, &_pg_byteindex);
// Maximum allowable demag angle
// Range of demagAngle is 0 to 255.
uint8ToBytes(demagAngle, _pg_data, &_pg_byteindex);
// Maximum allowable timing advance
// Range of timingAdvance is 0 to 255.
uint8ToBytes(timingAdvance, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ProtectionValuesPacketID());
}// encodeESC_ProtectionValuesPacket
/*!
* \brief Decode the ESC_ProtectionValues packet
*
* ESC self-protection settings
* \param _pg_pkt points to the packet being decoded by this function
* \param overcurrentBus receives Maximum allowable DC bus current
* \param overcurrentPhase receives Maximum allowable motor phase current
* \param overcurrentRegen receives Maximum allowable regen current
* \param overtemperatureInternal receives Maximum allowable internal temperature
* \param overtemperatureMotor receives Maximum allowable motor temperature
* \param overspeed receives Maximum motor speed
* \param undervoltage receives ESC undervoltage warning threshold
* \param overvoltage receives ESC overvoltage warning threshold
* \param demagAngle receives Maximum allowable demag angle
* \param timingAdvance receives Maximum allowable timing advance
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_ProtectionValuesPacket(const void* _pg_pkt, float* overcurrentBus, float* overcurrentPhase, float* overcurrentRegen, uint8_t* overtemperatureInternal, uint8_t* overtemperatureMotor, uint16_t* overspeed, uint8_t* undervoltage, uint8_t* overvoltage, uint8_t* demagAngle, uint8_t* timingAdvance)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ProtectionValuesPacketID())
return 0;
if(_pg_numbytes < getESC_ProtectionValuesMinDataLength())
return 0;
// this packet has default fields, make sure they are set
(*timingAdvance) = 20;
// Maximum allowable DC bus current
// Range of overcurrentBus is 0.0f to 1275.0f.
(*overcurrentBus) = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/0.2f);
// Maximum allowable motor phase current
// Range of overcurrentPhase is 0.0f to 1275.0f.
(*overcurrentPhase) = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/0.2f);
// Maximum allowable regen current
// Range of overcurrentRegen is 0.0f to 1275.0f.
(*overcurrentRegen) = float32ScaledFrom1UnsignedBytes(_pg_data, &_pg_byteindex, 0.0f, 1.0f/0.2f);
// Maximum allowable internal temperature
// Range of overtemperatureInternal is 0 to 255.
(*overtemperatureInternal) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum allowable motor temperature
// Range of overtemperatureMotor is 0 to 255.
(*overtemperatureMotor) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum motor speed
// Range of overspeed is 0 to 65535.
(*overspeed) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// ESC undervoltage warning threshold
// Range of undervoltage is 0 to 255.
(*undervoltage) = uint8FromBytes(_pg_data, &_pg_byteindex);
// ESC overvoltage warning threshold
// Range of overvoltage is 0 to 255.
(*overvoltage) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum allowable demag angle
// Range of demagAngle is 0 to 255.
(*demagAngle) = uint8FromBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 1 > _pg_numbytes)
return 1;
// Maximum allowable timing advance
// Range of timingAdvance is 0 to 255.
(*timingAdvance) = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_ProtectionValuesPacket
/*!
* \brief Create the ESC_ProtectionActions packet
*
* ESC protection actions
* \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 encodeESC_ProtectionActionsPacketStructure(void* _pg_pkt, const ESC_ProtectionActions_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned int _pg_tempbitfield = 0;
// Action when bus current exceeds limit
// Range of overcurrentBus is 0 to 7.
_pg_data[_pg_byteindex] = (uint8_t)limitMax(_pg_user->overcurrentBus, 7) << 5;
// Action when phase current exceeds limit
// Range of overcurrentPhase is 0 to 7.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->overcurrentPhase, 7) << 2;
// Action when regen current exceeds limit
// Range of overcurrentRegen is 0 to 7.
_pg_tempbitfield = (unsigned int)limitMax(_pg_user->overcurrentRegen, 7);
_pg_data[_pg_byteindex + 1] = (uint8_t)(_pg_tempbitfield << 7);
_pg_tempbitfield >>= 1;
_pg_data[_pg_byteindex] |= (uint8_t)_pg_tempbitfield;
// Action when ESC temperature exceeds limit
// Range of overtemperatureInternal is 0 to 7.
_pg_data[_pg_byteindex + 1] |= (uint8_t)limitMax(_pg_user->overtemperatureInternal, 7) << 4;
// Action when motor temperature exceeds limit
// Range of overtemperatureMotor is 0 to 7.
_pg_data[_pg_byteindex + 1] |= (uint8_t)limitMax(_pg_user->overtemperatureMotor, 7) << 1;
// Action when motor speed exceeds limit
// Range of overspeed is 0 to 7.
_pg_tempbitfield = (unsigned int)limitMax(_pg_user->overspeed, 7);
_pg_data[_pg_byteindex + 2] = (uint8_t)(_pg_tempbitfield << 6);
_pg_tempbitfield >>= 2;
_pg_data[_pg_byteindex + 1] |= (uint8_t)_pg_tempbitfield;
// Action when DC voltage falls below configured lower limit
// Range of undervoltage is 0 to 7.
_pg_data[_pg_byteindex + 2] |= (uint8_t)limitMax(_pg_user->undervoltage, 7) << 3;
// Action when DC voltage exceeds configured upper limit
// Range of overvoltage is 0 to 7.
_pg_data[_pg_byteindex + 2] |= (uint8_t)limitMax(_pg_user->overvoltage, 7);
// Action when motor demag angle exceeds limit
// Range of demagAngle is 0 to 7.
_pg_data[_pg_byteindex + 3] = (uint8_t)limitMax(_pg_user->demagAngle, 7) << 5;
// Action on motor commutation estimator failure
// Range of commutationLoss is 0 to 7.
_pg_data[_pg_byteindex + 3] |= (uint8_t)limitMax(_pg_user->commutationLoss, 7) << 2;
_pg_byteindex += 4; // close bit field
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ProtectionActionsPacketID());
}// encodeESC_ProtectionActionsPacketStructure
/*!
* \brief Decode the ESC_ProtectionActions packet
*
* ESC protection actions
* \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 decodeESC_ProtectionActionsPacketStructure(const void* _pg_pkt, ESC_ProtectionActions_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
unsigned int _pg_tempbitfield = 0;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ProtectionActionsPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_ProtectionActionsMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// this packet has default fields, make sure they are set
_pg_user->commutationLoss = ESC_PROTECTION_WARNING;
// Action when bus current exceeds limit
// Range of overcurrentBus is 0 to 7.
_pg_user->overcurrentBus = (_pg_data[_pg_byteindex] >> 5);
// Action when phase current exceeds limit
// Range of overcurrentPhase is 0 to 7.
_pg_user->overcurrentPhase = ((_pg_data[_pg_byteindex] >> 2) & 0x7);
// Action when regen current exceeds limit
// Range of overcurrentRegen is 0 to 7.
_pg_tempbitfield = (_pg_data[_pg_byteindex] & 0x3);
_pg_tempbitfield <<= 1;
_pg_tempbitfield |= (_pg_data[_pg_byteindex + 1] >> 7);
_pg_user->overcurrentRegen = _pg_tempbitfield;
// Action when ESC temperature exceeds limit
// Range of overtemperatureInternal is 0 to 7.
_pg_user->overtemperatureInternal = ((_pg_data[_pg_byteindex + 1] >> 4) & 0x7);
// Action when motor temperature exceeds limit
// Range of overtemperatureMotor is 0 to 7.
_pg_user->overtemperatureMotor = ((_pg_data[_pg_byteindex + 1] >> 1) & 0x7);
// Action when motor speed exceeds limit
// Range of overspeed is 0 to 7.
_pg_tempbitfield = (_pg_data[_pg_byteindex + 1] & 0x1);
_pg_tempbitfield <<= 2;
_pg_tempbitfield |= (_pg_data[_pg_byteindex + 2] >> 6);
_pg_user->overspeed = _pg_tempbitfield;
// Action when DC voltage falls below configured lower limit
// Range of undervoltage is 0 to 7.
_pg_user->undervoltage = ((_pg_data[_pg_byteindex + 2] >> 3) & 0x7);
// Action when DC voltage exceeds configured upper limit
// Range of overvoltage is 0 to 7.
_pg_user->overvoltage = ((_pg_data[_pg_byteindex + 2]) & 0x7);
// Action when motor demag angle exceeds limit
// Range of demagAngle is 0 to 7.
_pg_user->demagAngle = (_pg_data[_pg_byteindex + 3] >> 5);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// Action on motor commutation estimator failure
// Range of commutationLoss is 0 to 7.
_pg_user->commutationLoss = ((_pg_data[_pg_byteindex + 3] >> 2) & 0x7);
_pg_byteindex += 4; // close bit field
return 1;
}// decodeESC_ProtectionActionsPacketStructure
/*!
* \brief Create the ESC_ProtectionActions packet
*
* ESC protection actions
* \param _pg_pkt points to the packet which will be created by this function
* \param overcurrentBus is Action when bus current exceeds limit
* \param overcurrentPhase is Action when phase current exceeds limit
* \param overcurrentRegen is Action when regen current exceeds limit
* \param overtemperatureInternal is Action when ESC temperature exceeds limit
* \param overtemperatureMotor is Action when motor temperature exceeds limit
* \param overspeed is Action when motor speed exceeds limit
* \param undervoltage is Action when DC voltage falls below configured lower limit
* \param overvoltage is Action when DC voltage exceeds configured upper limit
* \param demagAngle is Action when motor demag angle exceeds limit
* \param commutationLoss is Action on motor commutation estimator failure
*/
void encodeESC_ProtectionActionsPacket(void* _pg_pkt, uint8_t overcurrentBus, uint8_t overcurrentPhase, uint8_t overcurrentRegen, uint8_t overtemperatureInternal, uint8_t overtemperatureMotor, uint8_t overspeed, uint8_t undervoltage, uint8_t overvoltage, uint8_t demagAngle, uint8_t commutationLoss)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned int _pg_tempbitfield = 0;
// Action when bus current exceeds limit
// Range of overcurrentBus is 0 to 7.
_pg_data[_pg_byteindex] = (uint8_t)limitMax(overcurrentBus, 7) << 5;
// Action when phase current exceeds limit
// Range of overcurrentPhase is 0 to 7.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(overcurrentPhase, 7) << 2;
// Action when regen current exceeds limit
// Range of overcurrentRegen is 0 to 7.
_pg_tempbitfield = (unsigned int)limitMax(overcurrentRegen, 7);
_pg_data[_pg_byteindex + 1] = (uint8_t)(_pg_tempbitfield << 7);
_pg_tempbitfield >>= 1;
_pg_data[_pg_byteindex] |= (uint8_t)_pg_tempbitfield;
// Action when ESC temperature exceeds limit
// Range of overtemperatureInternal is 0 to 7.
_pg_data[_pg_byteindex + 1] |= (uint8_t)limitMax(overtemperatureInternal, 7) << 4;
// Action when motor temperature exceeds limit
// Range of overtemperatureMotor is 0 to 7.
_pg_data[_pg_byteindex + 1] |= (uint8_t)limitMax(overtemperatureMotor, 7) << 1;
// Action when motor speed exceeds limit
// Range of overspeed is 0 to 7.
_pg_tempbitfield = (unsigned int)limitMax(overspeed, 7);
_pg_data[_pg_byteindex + 2] = (uint8_t)(_pg_tempbitfield << 6);
_pg_tempbitfield >>= 2;
_pg_data[_pg_byteindex + 1] |= (uint8_t)_pg_tempbitfield;
// Action when DC voltage falls below configured lower limit
// Range of undervoltage is 0 to 7.
_pg_data[_pg_byteindex + 2] |= (uint8_t)limitMax(undervoltage, 7) << 3;
// Action when DC voltage exceeds configured upper limit
// Range of overvoltage is 0 to 7.
_pg_data[_pg_byteindex + 2] |= (uint8_t)limitMax(overvoltage, 7);
// Action when motor demag angle exceeds limit
// Range of demagAngle is 0 to 7.
_pg_data[_pg_byteindex + 3] = (uint8_t)limitMax(demagAngle, 7) << 5;
// Action on motor commutation estimator failure
// Range of commutationLoss is 0 to 7.
_pg_data[_pg_byteindex + 3] |= (uint8_t)limitMax(commutationLoss, 7) << 2;
_pg_byteindex += 4; // close bit field
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_ProtectionActionsPacketID());
}// encodeESC_ProtectionActionsPacket
/*!
* \brief Decode the ESC_ProtectionActions packet
*
* ESC protection actions
* \param _pg_pkt points to the packet being decoded by this function
* \param overcurrentBus receives Action when bus current exceeds limit
* \param overcurrentPhase receives Action when phase current exceeds limit
* \param overcurrentRegen receives Action when regen current exceeds limit
* \param overtemperatureInternal receives Action when ESC temperature exceeds limit
* \param overtemperatureMotor receives Action when motor temperature exceeds limit
* \param overspeed receives Action when motor speed exceeds limit
* \param undervoltage receives Action when DC voltage falls below configured lower limit
* \param overvoltage receives Action when DC voltage exceeds configured upper limit
* \param demagAngle receives Action when motor demag angle exceeds limit
* \param commutationLoss receives Action on motor commutation estimator failure
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_ProtectionActionsPacket(const void* _pg_pkt, uint8_t* overcurrentBus, uint8_t* overcurrentPhase, uint8_t* overcurrentRegen, uint8_t* overtemperatureInternal, uint8_t* overtemperatureMotor, uint8_t* overspeed, uint8_t* undervoltage, uint8_t* overvoltage, uint8_t* demagAngle, uint8_t* commutationLoss)
{
unsigned int _pg_tempbitfield = 0;
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_ProtectionActionsPacketID())
return 0;
if(_pg_numbytes < getESC_ProtectionActionsMinDataLength())
return 0;
// this packet has default fields, make sure they are set
(*commutationLoss) = ESC_PROTECTION_WARNING;
// Action when bus current exceeds limit
// Range of overcurrentBus is 0 to 7.
(*overcurrentBus) = (_pg_data[_pg_byteindex] >> 5);
// Action when phase current exceeds limit
// Range of overcurrentPhase is 0 to 7.
(*overcurrentPhase) = ((_pg_data[_pg_byteindex] >> 2) & 0x7);
// Action when regen current exceeds limit
// Range of overcurrentRegen is 0 to 7.
_pg_tempbitfield = (_pg_data[_pg_byteindex] & 0x3);
_pg_tempbitfield <<= 1;
_pg_tempbitfield |= (_pg_data[_pg_byteindex + 1] >> 7);
(*overcurrentRegen) = _pg_tempbitfield;
// Action when ESC temperature exceeds limit
// Range of overtemperatureInternal is 0 to 7.
(*overtemperatureInternal) = ((_pg_data[_pg_byteindex + 1] >> 4) & 0x7);
// Action when motor temperature exceeds limit
// Range of overtemperatureMotor is 0 to 7.
(*overtemperatureMotor) = ((_pg_data[_pg_byteindex + 1] >> 1) & 0x7);
// Action when motor speed exceeds limit
// Range of overspeed is 0 to 7.
_pg_tempbitfield = (_pg_data[_pg_byteindex + 1] & 0x1);
_pg_tempbitfield <<= 2;
_pg_tempbitfield |= (_pg_data[_pg_byteindex + 2] >> 6);
(*overspeed) = _pg_tempbitfield;
// Action when DC voltage falls below configured lower limit
// Range of undervoltage is 0 to 7.
(*undervoltage) = ((_pg_data[_pg_byteindex + 2] >> 3) & 0x7);
// Action when DC voltage exceeds configured upper limit
// Range of overvoltage is 0 to 7.
(*overvoltage) = ((_pg_data[_pg_byteindex + 2]) & 0x7);
// Action when motor demag angle exceeds limit
// Range of demagAngle is 0 to 7.
(*demagAngle) = (_pg_data[_pg_byteindex + 3] >> 5);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// Action on motor commutation estimator failure
// Range of commutationLoss is 0 to 7.
(*commutationLoss) = ((_pg_data[_pg_byteindex + 3] >> 2) & 0x7);
_pg_byteindex += 4; // close bit field
return 1;
}// decodeESC_ProtectionActionsPacket
/*!
* \brief Create the ESC_MotorParameters packet
*
* Motor and system 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 encodeESC_MotorParametersPacketStructure(void* _pg_pkt, const ESC_MotorParameters_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Reserved for future packet expansion
uint8ToBytes((uint8_t)(0), _pg_data, &_pg_byteindex);
// Motor RPM constant
// Range of motorKv is 0 to 65535.
uint16ToBeBytes(_pg_user->motorKv, _pg_data, &_pg_byteindex);
// Motor pole pairs count
// Range of polePairs is 0 to 255.
uint8ToBytes(_pg_user->polePairs, _pg_data, &_pg_byteindex);
// Maximum motor speed
// Range of maxSpeed is 0 to 65535.
uint16ToBeBytes(_pg_user->maxSpeed, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_MotorParametersPacketID());
}// encodeESC_MotorParametersPacketStructure
/*!
* \brief Decode the ESC_MotorParameters packet
*
* Motor and system 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 decodeESC_MotorParametersPacketStructure(const void* _pg_pkt, ESC_MotorParameters_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_MotorParametersPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_MotorParametersMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// this packet has default fields, make sure they are set
_pg_user->maxSpeed = 20000;
// Reserved for future packet expansion
// Range of reserved is 0 to 255.
_pg_user->reserved = uint8FromBytes(_pg_data, &_pg_byteindex);
// Motor RPM constant
// Range of motorKv is 0 to 65535.
_pg_user->motorKv = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Motor pole pairs count
// Range of polePairs is 0 to 255.
_pg_user->polePairs = uint8FromBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Maximum motor speed
// Range of maxSpeed is 0 to 65535.
_pg_user->maxSpeed = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_MotorParametersPacketStructure
/*!
* \brief Create the ESC_MotorHallSensorConfig packet
*
* Hall sensor configuration options
* \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 encodeESC_MotorHallSensorConfigPacketStructure(void* _pg_pkt, const ESC_MotorHallSensorConfig_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Reserved for future use
_pg_data[_pg_byteindex] = 0;
// Bypass extra checks for starting in hall sensor mode
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->bypassStartingChecks == true) ? 1 : 0) << 5;
// Hall sensor operational mode
// Range of mode is 0 to 31.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->mode, 31);
_pg_byteindex += 1; // close bit field
// Hall sensor U/V/W polarity
// Range of polarity is 0 to 255.
uint8ToBytes(_pg_user->polarity, _pg_data, &_pg_byteindex);
// Time (in milliseconds) for no hall sensor transitions to trigger an error (0 = forever)
// Range of timeout is 0 to 65535.
uint16ToBeBytes(_pg_user->timeout, _pg_data, &_pg_byteindex);
// Maximum electrical RPM when running under hall sensor control
// Range of maxSpeed is 0 to 65535.
uint16ToBeBytes(_pg_user->maxSpeed, _pg_data, &_pg_byteindex);
// RPM threshold for transferring to sensorless motor control
// Range of transitionSpeed is 0 to 65535.
uint16ToBeBytes(_pg_user->transitionSpeed, _pg_data, &_pg_byteindex);
// RPM hysteresis for switching between sensored and sensorless control
// Range of transitionHysteresis is 0 to 255.
uint8ToBytes(_pg_user->transitionHysteresis, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_MotorHallSensorConfigPacketID());
}// encodeESC_MotorHallSensorConfigPacketStructure
/*!
* \brief Decode the ESC_MotorHallSensorConfig packet
*
* Hall sensor configuration options
* \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 decodeESC_MotorHallSensorConfigPacketStructure(const void* _pg_pkt, ESC_MotorHallSensorConfig_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_MotorHallSensorConfigPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_MotorHallSensorConfigMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Reserved for future use
// Bypass extra checks for starting in hall sensor mode
_pg_user->bypassStartingChecks = (((_pg_data[_pg_byteindex] >> 5) & 0x1)) ? true : false;
// Hall sensor operational mode
// Range of mode is 0 to 31.
_pg_user->mode = ((_pg_data[_pg_byteindex]) & 0x1F);
_pg_byteindex += 1; // close bit field
// Hall sensor U/V/W polarity
// Range of polarity is 0 to 255.
_pg_user->polarity = uint8FromBytes(_pg_data, &_pg_byteindex);
// Time (in milliseconds) for no hall sensor transitions to trigger an error (0 = forever)
// Range of timeout is 0 to 65535.
_pg_user->timeout = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Maximum electrical RPM when running under hall sensor control
// Range of maxSpeed is 0 to 65535.
_pg_user->maxSpeed = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// RPM threshold for transferring to sensorless motor control
// Range of transitionSpeed is 0 to 65535.
_pg_user->transitionSpeed = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// RPM hysteresis for switching between sensored and sensorless control
// Range of transitionHysteresis is 0 to 255.
_pg_user->transitionHysteresis = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_MotorHallSensorConfigPacketStructure
/*!
* \brief Create the ESC_Address packet
*
* This packet contains the serial number for the ESC. Additionally there are
* two extra values (each 16-bit) which can be programmed by the user for any
* purpose.
* \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 encodeESC_AddressPacketStructure(void* _pg_pkt, const ESC_Address_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// ESC hardware revision (OTP - not configurable by user)
// Range of HardwareRevision is 0 to 255.
uint8ToBytes(_pg_user->HardwareRevision, _pg_data, &_pg_byteindex);
// ESC model (OTP - not configurable by user)
// Range of Model is 0 to 255.
uint8ToBytes(_pg_user->Model, _pg_data, &_pg_byteindex);
// ESC Serial Number (OTP - not configurable by user)
// Range of SerialNumber is 0 to 65535.
uint16ToBeBytes(_pg_user->SerialNumber, _pg_data, &_pg_byteindex);
// User ID Value A - user can set this value to any value
// Range of UserIDA is 0 to 65535.
uint16ToBeBytes(_pg_user->UserIDA, _pg_data, &_pg_byteindex);
// User ID Value B - user can set this value to any value
// Range of UserIDB is 0 to 65535.
uint16ToBeBytes(_pg_user->UserIDB, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_AddressPacketID());
}// encodeESC_AddressPacketStructure
/*!
* \brief Decode the ESC_Address packet
*
* This packet contains the serial number for the ESC. Additionally there are
* two extra values (each 16-bit) which can be programmed by the user for any
* purpose.
* \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 decodeESC_AddressPacketStructure(const void* _pg_pkt, ESC_Address_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_AddressPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_AddressMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// ESC hardware revision (OTP - not configurable by user)
// Range of HardwareRevision is 0 to 255.
_pg_user->HardwareRevision = uint8FromBytes(_pg_data, &_pg_byteindex);
// ESC model (OTP - not configurable by user)
// Range of Model is 0 to 255.
_pg_user->Model = uint8FromBytes(_pg_data, &_pg_byteindex);
// ESC Serial Number (OTP - not configurable by user)
// Range of SerialNumber is 0 to 65535.
_pg_user->SerialNumber = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// User ID Value A - user can set this value to any value
// Range of UserIDA is 0 to 65535.
_pg_user->UserIDA = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// User ID Value B - user can set this value to any value
// Range of UserIDB is 0 to 65535.
_pg_user->UserIDB = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_AddressPacketStructure
/*!
* \brief Create the ESC_Address packet
*
* This packet contains the serial number for the ESC. Additionally there are
* two extra values (each 16-bit) which can be programmed by the user for any
* purpose.
* \param _pg_pkt points to the packet which will be created by this function
* \param HardwareRevision is ESC hardware revision (OTP - not configurable by user)
* \param Model is ESC model (OTP - not configurable by user)
* \param SerialNumber is ESC Serial Number (OTP - not configurable by user)
* \param UserIDA is User ID Value A - user can set this value to any value
* \param UserIDB is User ID Value B - user can set this value to any value
*/
void encodeESC_AddressPacket(void* _pg_pkt, uint8_t HardwareRevision, uint8_t Model, uint16_t SerialNumber, uint16_t UserIDA, uint16_t UserIDB)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// ESC hardware revision (OTP - not configurable by user)
// Range of HardwareRevision is 0 to 255.
uint8ToBytes(HardwareRevision, _pg_data, &_pg_byteindex);
// ESC model (OTP - not configurable by user)
// Range of Model is 0 to 255.
uint8ToBytes(Model, _pg_data, &_pg_byteindex);
// ESC Serial Number (OTP - not configurable by user)
// Range of SerialNumber is 0 to 65535.
uint16ToBeBytes(SerialNumber, _pg_data, &_pg_byteindex);
// User ID Value A - user can set this value to any value
// Range of UserIDA is 0 to 65535.
uint16ToBeBytes(UserIDA, _pg_data, &_pg_byteindex);
// User ID Value B - user can set this value to any value
// Range of UserIDB is 0 to 65535.
uint16ToBeBytes(UserIDB, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_AddressPacketID());
}// encodeESC_AddressPacket
/*!
* \brief Decode the ESC_Address packet
*
* This packet contains the serial number for the ESC. Additionally there are
* two extra values (each 16-bit) which can be programmed by the user for any
* purpose.
* \param _pg_pkt points to the packet being decoded by this function
* \param HardwareRevision receives ESC hardware revision (OTP - not configurable by user)
* \param Model receives ESC model (OTP - not configurable by user)
* \param SerialNumber receives ESC Serial Number (OTP - not configurable by user)
* \param UserIDA receives User ID Value A - user can set this value to any value
* \param UserIDB receives User ID Value B - user can set this value to any value
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_AddressPacket(const void* _pg_pkt, uint8_t* HardwareRevision, uint8_t* Model, uint16_t* SerialNumber, uint16_t* UserIDA, uint16_t* UserIDB)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_AddressPacketID())
return 0;
if(_pg_numbytes < getESC_AddressMinDataLength())
return 0;
// ESC hardware revision (OTP - not configurable by user)
// Range of HardwareRevision is 0 to 255.
(*HardwareRevision) = uint8FromBytes(_pg_data, &_pg_byteindex);
// ESC model (OTP - not configurable by user)
// Range of Model is 0 to 255.
(*Model) = uint8FromBytes(_pg_data, &_pg_byteindex);
// ESC Serial Number (OTP - not configurable by user)
// Range of SerialNumber is 0 to 65535.
(*SerialNumber) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// User ID Value A - user can set this value to any value
// Range of UserIDA is 0 to 65535.
(*UserIDA) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// User ID Value B - user can set this value to any value
// Range of UserIDB is 0 to 65535.
(*UserIDB) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_AddressPacket
/*!
* \brief Create the ESC_Title packet
*
* This packet contains a zero-terminated string (max-length 8) used to
* identify the particular ESC.
* \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 encodeESC_TitlePacketStructure(void* _pg_pkt, const ESC_Title_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned _pg_i = 0;
// Description of this ESC
// Range of ESCTitle is 0 to 255.
for(_pg_i = 0; _pg_i < 8; _pg_i++)
uint8ToBytes(_pg_user->ESCTitle[_pg_i], _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TitlePacketID());
}// encodeESC_TitlePacketStructure
/*!
* \brief Decode the ESC_Title packet
*
* This packet contains a zero-terminated string (max-length 8) used to
* identify the particular ESC.
* \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 decodeESC_TitlePacketStructure(const void* _pg_pkt, ESC_Title_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
unsigned _pg_i = 0;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TitlePacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_TitleMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Description of this ESC
// Range of ESCTitle is 0 to 255.
for(_pg_i = 0; _pg_i < 8; _pg_i++)
_pg_user->ESCTitle[_pg_i] = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_TitlePacketStructure
/*!
* \brief Create the ESC_Title packet
*
* This packet contains a zero-terminated string (max-length 8) used to
* identify the particular ESC.
* \param _pg_pkt points to the packet which will be created by this function
* \param ESCTitle is Description of this ESC
*/
void encodeESC_TitlePacket(void* _pg_pkt, const uint8_t ESCTitle[8])
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned _pg_i = 0;
// Description of this ESC
// Range of ESCTitle is 0 to 255.
for(_pg_i = 0; _pg_i < 8; _pg_i++)
uint8ToBytes(ESCTitle[_pg_i], _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TitlePacketID());
}// encodeESC_TitlePacket
/*!
* \brief Decode the ESC_Title packet
*
* This packet contains a zero-terminated string (max-length 8) used to
* identify the particular ESC.
* \param _pg_pkt points to the packet being decoded by this function
* \param ESCTitle receives Description of this ESC
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_TitlePacket(const void* _pg_pkt, uint8_t ESCTitle[8])
{
unsigned _pg_i = 0;
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TitlePacketID())
return 0;
if(_pg_numbytes < getESC_TitleMinDataLength())
return 0;
// Description of this ESC
// Range of ESCTitle is 0 to 255.
for(_pg_i = 0; _pg_i < 8; _pg_i++)
ESCTitle[_pg_i] = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_TitlePacket
/*!
* \brief Create the ESC_Firmware packet
*
* This packet contains the firmware version of the ESC
* \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 encodeESC_FirmwarePacketStructure(void* _pg_pkt, const ESC_Firmware_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Major firmware version number
// Range of versionMajor is 0 to 255.
uint8ToBytes(_pg_user->versionMajor, _pg_data, &_pg_byteindex);
// Minor firmware version numner
// Range of versionMinor is 0 to 255.
uint8ToBytes(_pg_user->versionMinor, _pg_data, &_pg_byteindex);
// Firmware release date, day-of-month
// Range of versionDay is 0 to 255.
uint8ToBytes(_pg_user->versionDay, _pg_data, &_pg_byteindex);
// Firmware release data, month-of-year
// Range of versionMonth is 0 to 255.
uint8ToBytes(_pg_user->versionMonth, _pg_data, &_pg_byteindex);
// Firmware release date, year
// Range of versionYear is 0 to 65535.
uint16ToBeBytes(_pg_user->versionYear, _pg_data, &_pg_byteindex);
// Firmware checksum
// Range of firmwareChecksum is 0 to 65535.
uint16ToBeBytes(_pg_user->firmwareChecksum, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_FirmwarePacketID());
}// encodeESC_FirmwarePacketStructure
/*!
* \brief Decode the ESC_Firmware packet
*
* This packet contains the firmware version of the ESC
* \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 decodeESC_FirmwarePacketStructure(const void* _pg_pkt, ESC_Firmware_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_FirmwarePacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_FirmwareMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Major firmware version number
// Range of versionMajor is 0 to 255.
_pg_user->versionMajor = uint8FromBytes(_pg_data, &_pg_byteindex);
// Minor firmware version numner
// Range of versionMinor is 0 to 255.
_pg_user->versionMinor = uint8FromBytes(_pg_data, &_pg_byteindex);
// Firmware release date, day-of-month
// Range of versionDay is 0 to 255.
_pg_user->versionDay = uint8FromBytes(_pg_data, &_pg_byteindex);
// Firmware release data, month-of-year
// Range of versionMonth is 0 to 255.
_pg_user->versionMonth = uint8FromBytes(_pg_data, &_pg_byteindex);
// Firmware release date, year
// Range of versionYear is 0 to 65535.
_pg_user->versionYear = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Firmware checksum
// Range of firmwareChecksum is 0 to 65535.
_pg_user->firmwareChecksum = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_FirmwarePacketStructure
/*!
* \brief Create the ESC_Firmware packet
*
* This packet contains the firmware version of the ESC
* \param _pg_pkt points to the packet which will be created by this function
* \param versionMajor is Major firmware version number
* \param versionMinor is Minor firmware version numner
* \param versionDay is Firmware release date, day-of-month
* \param versionMonth is Firmware release data, month-of-year
* \param versionYear is Firmware release date, year
* \param firmwareChecksum is Firmware checksum
*/
void encodeESC_FirmwarePacket(void* _pg_pkt, uint8_t versionMajor, uint8_t versionMinor, uint8_t versionDay, uint8_t versionMonth, uint16_t versionYear, uint16_t firmwareChecksum)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Major firmware version number
// Range of versionMajor is 0 to 255.
uint8ToBytes(versionMajor, _pg_data, &_pg_byteindex);
// Minor firmware version numner
// Range of versionMinor is 0 to 255.
uint8ToBytes(versionMinor, _pg_data, &_pg_byteindex);
// Firmware release date, day-of-month
// Range of versionDay is 0 to 255.
uint8ToBytes(versionDay, _pg_data, &_pg_byteindex);
// Firmware release data, month-of-year
// Range of versionMonth is 0 to 255.
uint8ToBytes(versionMonth, _pg_data, &_pg_byteindex);
// Firmware release date, year
// Range of versionYear is 0 to 65535.
uint16ToBeBytes(versionYear, _pg_data, &_pg_byteindex);
// Firmware checksum
// Range of firmwareChecksum is 0 to 65535.
uint16ToBeBytes(firmwareChecksum, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_FirmwarePacketID());
}// encodeESC_FirmwarePacket
/*!
* \brief Decode the ESC_Firmware packet
*
* This packet contains the firmware version of the ESC
* \param _pg_pkt points to the packet being decoded by this function
* \param versionMajor receives Major firmware version number
* \param versionMinor receives Minor firmware version numner
* \param versionDay receives Firmware release date, day-of-month
* \param versionMonth receives Firmware release data, month-of-year
* \param versionYear receives Firmware release date, year
* \param firmwareChecksum receives Firmware checksum
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_FirmwarePacket(const void* _pg_pkt, uint8_t* versionMajor, uint8_t* versionMinor, uint8_t* versionDay, uint8_t* versionMonth, uint16_t* versionYear, uint16_t* firmwareChecksum)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_FirmwarePacketID())
return 0;
if(_pg_numbytes < getESC_FirmwareMinDataLength())
return 0;
// Major firmware version number
// Range of versionMajor is 0 to 255.
(*versionMajor) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Minor firmware version numner
// Range of versionMinor is 0 to 255.
(*versionMinor) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Firmware release date, day-of-month
// Range of versionDay is 0 to 255.
(*versionDay) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Firmware release data, month-of-year
// Range of versionMonth is 0 to 255.
(*versionMonth) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Firmware release date, year
// Range of versionYear is 0 to 65535.
(*versionYear) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Firmware checksum
// Range of firmwareChecksum is 0 to 65535.
(*firmwareChecksum) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_FirmwarePacket
/*!
* \brief Create the ESC_SystemInfo packet
*
* This packet contains system runtime 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 encodeESC_SystemInfoPacketStructure(void* _pg_pkt, const ESC_SystemInfo_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Number of milliseconds since the ESC last experienced a reset/power-on event
// Range of millisecondsSinceReset is 0 to 4294967295.
uint32ToBeBytes(_pg_user->millisecondsSinceReset, _pg_data, &_pg_byteindex);
// Number of power cycle events that the ESC has experienced
// Range of powerCycles is 0 to 65535.
uint16ToBeBytes(_pg_user->powerCycles, _pg_data, &_pg_byteindex);
// Processor RESET code for debug purposes
// Range of resetCode is 0 to 255.
uint8ToBytes(_pg_user->resetCode, _pg_data, &_pg_byteindex);
// Processor usage
// Range of cpuOccupancy is 0 to 255.
uint8ToBytes(_pg_user->cpuOccupancy, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_SystemInfoPacketID());
}// encodeESC_SystemInfoPacketStructure
/*!
* \brief Decode the ESC_SystemInfo packet
*
* This packet contains system runtime 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 decodeESC_SystemInfoPacketStructure(const void* _pg_pkt, ESC_SystemInfo_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_SystemInfoPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_SystemInfoMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Number of milliseconds since the ESC last experienced a reset/power-on event
// Range of millisecondsSinceReset is 0 to 4294967295.
_pg_user->millisecondsSinceReset = uint32FromBeBytes(_pg_data, &_pg_byteindex);
// Number of power cycle events that the ESC has experienced
// Range of powerCycles is 0 to 65535.
_pg_user->powerCycles = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Processor RESET code for debug purposes
// Range of resetCode is 0 to 255.
_pg_user->resetCode = uint8FromBytes(_pg_data, &_pg_byteindex);
// Processor usage
// Range of cpuOccupancy is 0 to 255.
_pg_user->cpuOccupancy = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_SystemInfoPacketStructure
/*!
* \brief Create the ESC_SystemInfo packet
*
* This packet contains system runtime information
* \param _pg_pkt points to the packet which will be created by this function
* \param millisecondsSinceReset is Number of milliseconds since the ESC last experienced a reset/power-on event
* \param powerCycles is Number of power cycle events that the ESC has experienced
* \param resetCode is Processor RESET code for debug purposes
* \param cpuOccupancy is Processor usage
*/
void encodeESC_SystemInfoPacket(void* _pg_pkt, uint32_t millisecondsSinceReset, uint16_t powerCycles, uint8_t resetCode, uint8_t cpuOccupancy)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Number of milliseconds since the ESC last experienced a reset/power-on event
// Range of millisecondsSinceReset is 0 to 4294967295.
uint32ToBeBytes(millisecondsSinceReset, _pg_data, &_pg_byteindex);
// Number of power cycle events that the ESC has experienced
// Range of powerCycles is 0 to 65535.
uint16ToBeBytes(powerCycles, _pg_data, &_pg_byteindex);
// Processor RESET code for debug purposes
// Range of resetCode is 0 to 255.
uint8ToBytes(resetCode, _pg_data, &_pg_byteindex);
// Processor usage
// Range of cpuOccupancy is 0 to 255.
uint8ToBytes(cpuOccupancy, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_SystemInfoPacketID());
}// encodeESC_SystemInfoPacket
/*!
* \brief Decode the ESC_SystemInfo packet
*
* This packet contains system runtime information
* \param _pg_pkt points to the packet being decoded by this function
* \param millisecondsSinceReset receives Number of milliseconds since the ESC last experienced a reset/power-on event
* \param powerCycles receives Number of power cycle events that the ESC has experienced
* \param resetCode receives Processor RESET code for debug purposes
* \param cpuOccupancy receives Processor usage
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_SystemInfoPacket(const void* _pg_pkt, uint32_t* millisecondsSinceReset, uint16_t* powerCycles, uint8_t* resetCode, uint8_t* cpuOccupancy)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_SystemInfoPacketID())
return 0;
if(_pg_numbytes < getESC_SystemInfoMinDataLength())
return 0;
// Number of milliseconds since the ESC last experienced a reset/power-on event
// Range of millisecondsSinceReset is 0 to 4294967295.
(*millisecondsSinceReset) = uint32FromBeBytes(_pg_data, &_pg_byteindex);
// Number of power cycle events that the ESC has experienced
// Range of powerCycles is 0 to 65535.
(*powerCycles) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Processor RESET code for debug purposes
// Range of resetCode is 0 to 255.
(*resetCode) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Processor usage
// Range of cpuOccupancy is 0 to 255.
(*cpuOccupancy) = uint8FromBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_SystemInfoPacket
/*!
* \brief Create the ESC_TelemetrySettings packet
*
* This packet contains the telemetry packet configuration
* \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 encodeESC_TelemetrySettingsPacketStructure(void* _pg_pkt, const ESC_TelemetrySettings_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Telemetry settings
encodeESC_TelemetryConfig_t(_pg_data, &_pg_byteindex, &_pg_user->settings);
// The API version of the ESC
stringToBytes(getESCVelocityVersion(), _pg_data, &_pg_byteindex, 5, 0);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TelemetrySettingsPacketID());
}// encodeESC_TelemetrySettingsPacketStructure
/*!
* \brief Decode the ESC_TelemetrySettings packet
*
* This packet contains the telemetry packet configuration
* \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 decodeESC_TelemetrySettingsPacketStructure(const void* _pg_pkt, ESC_TelemetrySettings_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TelemetrySettingsPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_TelemetrySettingsMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Telemetry settings
if(decodeESC_TelemetryConfig_t(_pg_data, &_pg_byteindex, &_pg_user->settings) == 0)
return 0;
// The API version of the ESC
stringFromBytes(_pg_user->apiVersion, _pg_data, &_pg_byteindex, 5, 0);
return 1;
}// decodeESC_TelemetrySettingsPacketStructure
/*!
* \brief Create the ESC_TelemetrySettings packet
*
* This packet contains the telemetry packet configuration
* \param _pg_pkt points to the packet which will be created by this function
* \param settings is Telemetry settings
*/
void encodeESC_TelemetrySettingsPacket(void* _pg_pkt, const ESC_TelemetryConfig_t* settings)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Telemetry settings
encodeESC_TelemetryConfig_t(_pg_data, &_pg_byteindex, settings);
// The API version of the ESC
stringToBytes(getESCVelocityVersion(), _pg_data, &_pg_byteindex, 5, 0);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TelemetrySettingsPacketID());
}// encodeESC_TelemetrySettingsPacket
/*!
* \brief Decode the ESC_TelemetrySettings packet
*
* This packet contains the telemetry packet configuration
* \param _pg_pkt points to the packet being decoded by this function
* \param settings receives Telemetry settings
* \param apiVersion receives The API version of the ESC
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_TelemetrySettingsPacket(const void* _pg_pkt, ESC_TelemetryConfig_t* settings, char apiVersion[5])
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TelemetrySettingsPacketID())
return 0;
if(_pg_numbytes < getESC_TelemetrySettingsMinDataLength())
return 0;
// Telemetry settings
if(decodeESC_TelemetryConfig_t(_pg_data, &_pg_byteindex, settings) == 0)
return 0;
// The API version of the ESC
stringFromBytes(apiVersion, _pg_data, &_pg_byteindex, 5, 0);
return 1;
}// decodeESC_TelemetrySettingsPacket
/*!
* \brief Create the ESC_EEPROMSettings packet
*
* This packet contains information on the non-volatile ESC 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 encodeESC_EEPROMSettingsPacketStructure(void* _pg_pkt, const ESC_EEPROMSettings_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Set if the ESC settings are locked
_pg_data[_pg_byteindex] = (uint8_t)((_pg_user->settingsLocked == true) ? 1 : 0) << 7;
// Version of EEPROM data
// Range of version is 0 to 127.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(_pg_user->version, 127);
_pg_byteindex += 1; // close bit field
// Size of settings data
// Range of size is 0 to 65535.
uint16ToBeBytes(_pg_user->size, _pg_data, &_pg_byteindex);
// Settings checksum
// Range of checksum is 0 to 65535.
uint16ToBeBytes(_pg_user->checksum, _pg_data, &_pg_byteindex);
// Validated settings checksum
// Range of validatedChecksum is 0 to 65535.
uint16ToBeBytes(_pg_user->validatedChecksum, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_EEPROMSettingsPacketID());
}// encodeESC_EEPROMSettingsPacketStructure
/*!
* \brief Decode the ESC_EEPROMSettings packet
*
* This packet contains information on the non-volatile ESC 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 decodeESC_EEPROMSettingsPacketStructure(const void* _pg_pkt, ESC_EEPROMSettings_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_EEPROMSettingsPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_EEPROMSettingsMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// this packet has default fields, make sure they are set
_pg_user->validatedChecksum = 0;
// Set if the ESC settings are locked
_pg_user->settingsLocked = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
// Version of EEPROM data
// Range of version is 0 to 127.
_pg_user->version = ((_pg_data[_pg_byteindex]) & 0x7F);
_pg_byteindex += 1; // close bit field
// Size of settings data
// Range of size is 0 to 65535.
_pg_user->size = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Settings checksum
// Range of checksum is 0 to 65535.
_pg_user->checksum = uint16FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Validated settings checksum
// Range of validatedChecksum is 0 to 65535.
_pg_user->validatedChecksum = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_EEPROMSettingsPacketStructure
/*!
* \brief Create the ESC_EEPROMSettings packet
*
* This packet contains information on the non-volatile ESC settings
* \param _pg_pkt points to the packet which will be created by this function
* \param settingsLocked is Set if the ESC settings are locked
* \param version is Version of EEPROM data
* \param size is Size of settings data
* \param checksum is Settings checksum
* \param validatedChecksum is Validated settings checksum
*/
void encodeESC_EEPROMSettingsPacket(void* _pg_pkt, bool settingsLocked, uint8_t version, uint16_t size, uint16_t checksum, uint16_t validatedChecksum)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Set if the ESC settings are locked
_pg_data[_pg_byteindex] = (uint8_t)((settingsLocked == true) ? 1 : 0) << 7;
// Version of EEPROM data
// Range of version is 0 to 127.
_pg_data[_pg_byteindex] |= (uint8_t)limitMax(version, 127);
_pg_byteindex += 1; // close bit field
// Size of settings data
// Range of size is 0 to 65535.
uint16ToBeBytes(size, _pg_data, &_pg_byteindex);
// Settings checksum
// Range of checksum is 0 to 65535.
uint16ToBeBytes(checksum, _pg_data, &_pg_byteindex);
// Validated settings checksum
// Range of validatedChecksum is 0 to 65535.
uint16ToBeBytes(validatedChecksum, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_EEPROMSettingsPacketID());
}// encodeESC_EEPROMSettingsPacket
/*!
* \brief Decode the ESC_EEPROMSettings packet
*
* This packet contains information on the non-volatile ESC settings
* \param _pg_pkt points to the packet being decoded by this function
* \param settingsLocked receives Set if the ESC settings are locked
* \param version receives Version of EEPROM data
* \param size receives Size of settings data
* \param checksum receives Settings checksum
* \param validatedChecksum receives Validated settings checksum
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_EEPROMSettingsPacket(const void* _pg_pkt, bool* settingsLocked, uint8_t* version, uint16_t* size, uint16_t* checksum, uint16_t* validatedChecksum)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_EEPROMSettingsPacketID())
return 0;
if(_pg_numbytes < getESC_EEPROMSettingsMinDataLength())
return 0;
// this packet has default fields, make sure they are set
(*validatedChecksum) = 0;
// Set if the ESC settings are locked
(*settingsLocked) = ((_pg_data[_pg_byteindex] >> 7)) ? true : false;
// Version of EEPROM data
// Range of version is 0 to 127.
(*version) = ((_pg_data[_pg_byteindex]) & 0x7F);
_pg_byteindex += 1; // close bit field
// Size of settings data
// Range of size is 0 to 65535.
(*size) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// Settings checksum
// Range of checksum is 0 to 65535.
(*checksum) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Validated settings checksum
// Range of validatedChecksum is 0 to 65535.
(*validatedChecksum) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_EEPROMSettingsPacket
/*!
* \brief Create the ESC_TempSensorConfig packet
*
* Motor temperature sensor 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 encodeESC_TempSensorConfigPacketStructure(void* _pg_pkt, const ESC_TempSensorConfig_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned _pg_i = 0;
// Reference temperature values
// Range of NTC_T is -32768 to 32767.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
int16ToBeBytes(_pg_user->NTC_T[_pg_i], _pg_data, &_pg_byteindex);
// Reference resistance values
// Range of NTC_R is -3.402823466e+38f to 3.402823466e+38f.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
float32ToBeBytes((float)_pg_user->NTC_R[_pg_i], _pg_data, &_pg_byteindex);
// Beta constant
// Range of Beta is 0 to 65535.
uint16ToBeBytes(_pg_user->Beta, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TempSensorConfigPacketID());
}// encodeESC_TempSensorConfigPacketStructure
/*!
* \brief Decode the ESC_TempSensorConfig packet
*
* Motor temperature sensor 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 decodeESC_TempSensorConfigPacketStructure(const void* _pg_pkt, ESC_TempSensorConfig_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
unsigned _pg_i = 0;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TempSensorConfigPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_TempSensorConfigMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Reference temperature values
// Range of NTC_T is -32768 to 32767.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
_pg_user->NTC_T[_pg_i] = int16FromBeBytes(_pg_data, &_pg_byteindex);
// Reference resistance values
// Range of NTC_R is -3.402823466e+38f to 3.402823466e+38f.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
_pg_user->NTC_R[_pg_i] = float32FromBeBytes(_pg_data, &_pg_byteindex);
// Beta constant
// Range of Beta is 0 to 65535.
_pg_user->Beta = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_TempSensorConfigPacketStructure
/*!
* \brief Create the ESC_TempSensorConfig packet
*
* Motor temperature sensor settings
* \param _pg_pkt points to the packet which will be created by this function
* \param NTC_T is Reference temperature values
* \param NTC_R is Reference resistance values
* \param Beta is Beta constant
*/
void encodeESC_TempSensorConfigPacket(void* _pg_pkt, const int16_t NTC_T[3], const float NTC_R[3], uint16_t Beta)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
unsigned _pg_i = 0;
// Reference temperature values
// Range of NTC_T is -32768 to 32767.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
int16ToBeBytes(NTC_T[_pg_i], _pg_data, &_pg_byteindex);
// Reference resistance values
// Range of NTC_R is -3.402823466e+38f to 3.402823466e+38f.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
float32ToBeBytes((float)NTC_R[_pg_i], _pg_data, &_pg_byteindex);
// Beta constant
// Range of Beta is 0 to 65535.
uint16ToBeBytes(Beta, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TempSensorConfigPacketID());
}// encodeESC_TempSensorConfigPacket
/*!
* \brief Decode the ESC_TempSensorConfig packet
*
* Motor temperature sensor settings
* \param _pg_pkt points to the packet being decoded by this function
* \param NTC_T receives Reference temperature values
* \param NTC_R receives Reference resistance values
* \param Beta receives Beta constant
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_TempSensorConfigPacket(const void* _pg_pkt, int16_t NTC_T[3], float NTC_R[3], uint16_t* Beta)
{
unsigned _pg_i = 0;
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TempSensorConfigPacketID())
return 0;
if(_pg_numbytes < getESC_TempSensorConfigMinDataLength())
return 0;
// Reference temperature values
// Range of NTC_T is -32768 to 32767.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
NTC_T[_pg_i] = int16FromBeBytes(_pg_data, &_pg_byteindex);
// Reference resistance values
// Range of NTC_R is -3.402823466e+38f to 3.402823466e+38f.
for(_pg_i = 0; _pg_i < 3; _pg_i++)
NTC_R[_pg_i] = float32FromBeBytes(_pg_data, &_pg_byteindex);
// Beta constant
// Range of Beta is 0 to 65535.
(*Beta) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_TempSensorConfigPacket
/*!
* \brief Create the ESC_TelltaleValues packet
*
* ESC telltale 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 encodeESC_TelltaleValuesPacketStructure(void* _pg_pkt, const ESC_TelltaleValues_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Maximum recorded internal temperature
// Range of maxTemperature is 0 to 255.
uint8ToBytes(_pg_user->maxTemperature, _pg_data, &_pg_byteindex);
// Maximum recorded MOSFET temperature
// Range of maxFetTemperature is 0 to 255.
uint8ToBytes(_pg_user->maxFetTemperature, _pg_data, &_pg_byteindex);
// Maximum recorded motor temperature
// Range of maxMotorTemperature is 0 to 255.
uint8ToBytes(_pg_user->maxMotorTemperature, _pg_data, &_pg_byteindex);
// Maximum recorded battery voltage
// Range of maxRippleVoltage is 0 to 255.
uint8ToBytes(_pg_user->maxRippleVoltage, _pg_data, &_pg_byteindex);
// Maximum recorded battery current
// Range of maxBatteryCurrent is -3276.7f to 3276.7f.
float32ScaledTo2SignedBeBytes(_pg_user->maxBatteryCurrent, _pg_data, &_pg_byteindex, 10.0f);
// Maximum recorded regen current
// Range of maxRegenCurrent is -3276.7f to 3276.7f.
float32ScaledTo2SignedBeBytes(_pg_user->maxRegenCurrent, _pg_data, &_pg_byteindex, 10.0f);
// Number of successful motor start events
// Range of totalStarts is 0 to 65535.
uint16ToBeBytes(_pg_user->totalStarts, _pg_data, &_pg_byteindex);
// Number of failed motor start events
// Range of failedStarts is 0 to 65535.
uint16ToBeBytes(_pg_user->failedStarts, _pg_data, &_pg_byteindex);
// ESC run time
// Range of escRunTime is 0 to 4294967295.
uint32ToBeBytes(_pg_user->escRunTime, _pg_data, &_pg_byteindex);
// Motor run time
// Range of motorRunTime is 0 to 4294967295.
uint32ToBeBytes(_pg_user->motorRunTime, _pg_data, &_pg_byteindex);
// Number of recorded motor desync events
// Range of desyncEvents is 0 to 4294967295.
uint32ToBeBytes(_pg_user->desyncEvents, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TelltaleValuesPacketID());
}// encodeESC_TelltaleValuesPacketStructure
/*!
* \brief Decode the ESC_TelltaleValues packet
*
* ESC telltale 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 decodeESC_TelltaleValuesPacketStructure(const void* _pg_pkt, ESC_TelltaleValues_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TelltaleValuesPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_TelltaleValuesMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// this packet has default fields, make sure they are set
_pg_user->maxRippleVoltage = 0;
_pg_user->maxBatteryCurrent = 0;
_pg_user->maxRegenCurrent = 0;
_pg_user->totalStarts = 0;
_pg_user->failedStarts = 0;
_pg_user->escRunTime = 0;
_pg_user->motorRunTime = 0;
_pg_user->desyncEvents = 0;
// Maximum recorded internal temperature
// Range of maxTemperature is 0 to 255.
_pg_user->maxTemperature = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum recorded MOSFET temperature
// Range of maxFetTemperature is 0 to 255.
_pg_user->maxFetTemperature = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum recorded motor temperature
// Range of maxMotorTemperature is 0 to 255.
_pg_user->maxMotorTemperature = uint8FromBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 1 > _pg_numbytes)
return 1;
// Maximum recorded battery voltage
// Range of maxRippleVoltage is 0 to 255.
_pg_user->maxRippleVoltage = uint8FromBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Maximum recorded battery current
// Range of maxBatteryCurrent is -3276.7f to 3276.7f.
_pg_user->maxBatteryCurrent = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/10.0f);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Maximum recorded regen current
// Range of maxRegenCurrent is -3276.7f to 3276.7f.
_pg_user->maxRegenCurrent = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/10.0f);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Number of successful motor start events
// Range of totalStarts is 0 to 65535.
_pg_user->totalStarts = uint16FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Number of failed motor start events
// Range of failedStarts is 0 to 65535.
_pg_user->failedStarts = uint16FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// ESC run time
// Range of escRunTime is 0 to 4294967295.
_pg_user->escRunTime = uint32FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// Motor run time
// Range of motorRunTime is 0 to 4294967295.
_pg_user->motorRunTime = uint32FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// Number of recorded motor desync events
// Range of desyncEvents is 0 to 4294967295.
_pg_user->desyncEvents = uint32FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_TelltaleValuesPacketStructure
/*!
* \brief Create the ESC_TelltaleValues packet
*
* ESC telltale values
* \param _pg_pkt points to the packet which will be created by this function
* \param maxTemperature is Maximum recorded internal temperature
* \param maxFetTemperature is Maximum recorded MOSFET temperature
* \param maxMotorTemperature is Maximum recorded motor temperature
* \param maxRippleVoltage is Maximum recorded battery voltage
* \param maxBatteryCurrent is Maximum recorded battery current
* \param maxRegenCurrent is Maximum recorded regen current
* \param totalStarts is Number of successful motor start events
* \param failedStarts is Number of failed motor start events
* \param escRunTime is ESC run time
* \param motorRunTime is Motor run time
* \param desyncEvents is Number of recorded motor desync events
*/
void encodeESC_TelltaleValuesPacket(void* _pg_pkt, uint8_t maxTemperature, uint8_t maxFetTemperature, uint8_t maxMotorTemperature, uint8_t maxRippleVoltage, float maxBatteryCurrent, float maxRegenCurrent, uint16_t totalStarts, uint16_t failedStarts, uint32_t escRunTime, uint32_t motorRunTime, uint32_t desyncEvents)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Maximum recorded internal temperature
// Range of maxTemperature is 0 to 255.
uint8ToBytes(maxTemperature, _pg_data, &_pg_byteindex);
// Maximum recorded MOSFET temperature
// Range of maxFetTemperature is 0 to 255.
uint8ToBytes(maxFetTemperature, _pg_data, &_pg_byteindex);
// Maximum recorded motor temperature
// Range of maxMotorTemperature is 0 to 255.
uint8ToBytes(maxMotorTemperature, _pg_data, &_pg_byteindex);
// Maximum recorded battery voltage
// Range of maxRippleVoltage is 0 to 255.
uint8ToBytes(maxRippleVoltage, _pg_data, &_pg_byteindex);
// Maximum recorded battery current
// Range of maxBatteryCurrent is -3276.7f to 3276.7f.
float32ScaledTo2SignedBeBytes(maxBatteryCurrent, _pg_data, &_pg_byteindex, 10.0f);
// Maximum recorded regen current
// Range of maxRegenCurrent is -3276.7f to 3276.7f.
float32ScaledTo2SignedBeBytes(maxRegenCurrent, _pg_data, &_pg_byteindex, 10.0f);
// Number of successful motor start events
// Range of totalStarts is 0 to 65535.
uint16ToBeBytes(totalStarts, _pg_data, &_pg_byteindex);
// Number of failed motor start events
// Range of failedStarts is 0 to 65535.
uint16ToBeBytes(failedStarts, _pg_data, &_pg_byteindex);
// ESC run time
// Range of escRunTime is 0 to 4294967295.
uint32ToBeBytes(escRunTime, _pg_data, &_pg_byteindex);
// Motor run time
// Range of motorRunTime is 0 to 4294967295.
uint32ToBeBytes(motorRunTime, _pg_data, &_pg_byteindex);
// Number of recorded motor desync events
// Range of desyncEvents is 0 to 4294967295.
uint32ToBeBytes(desyncEvents, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_TelltaleValuesPacketID());
}// encodeESC_TelltaleValuesPacket
/*!
* \brief Decode the ESC_TelltaleValues packet
*
* ESC telltale values
* \param _pg_pkt points to the packet being decoded by this function
* \param maxTemperature receives Maximum recorded internal temperature
* \param maxFetTemperature receives Maximum recorded MOSFET temperature
* \param maxMotorTemperature receives Maximum recorded motor temperature
* \param maxRippleVoltage receives Maximum recorded battery voltage
* \param maxBatteryCurrent receives Maximum recorded battery current
* \param maxRegenCurrent receives Maximum recorded regen current
* \param totalStarts receives Number of successful motor start events
* \param failedStarts receives Number of failed motor start events
* \param escRunTime receives ESC run time
* \param motorRunTime receives Motor run time
* \param desyncEvents receives Number of recorded motor desync events
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_TelltaleValuesPacket(const void* _pg_pkt, uint8_t* maxTemperature, uint8_t* maxFetTemperature, uint8_t* maxMotorTemperature, uint8_t* maxRippleVoltage, float* maxBatteryCurrent, float* maxRegenCurrent, uint16_t* totalStarts, uint16_t* failedStarts, uint32_t* escRunTime, uint32_t* motorRunTime, uint32_t* desyncEvents)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_TelltaleValuesPacketID())
return 0;
if(_pg_numbytes < getESC_TelltaleValuesMinDataLength())
return 0;
// this packet has default fields, make sure they are set
(*maxRippleVoltage) = 0;
(*maxBatteryCurrent) = 0;
(*maxRegenCurrent) = 0;
(*totalStarts) = 0;
(*failedStarts) = 0;
(*escRunTime) = 0;
(*motorRunTime) = 0;
(*desyncEvents) = 0;
// Maximum recorded internal temperature
// Range of maxTemperature is 0 to 255.
(*maxTemperature) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum recorded MOSFET temperature
// Range of maxFetTemperature is 0 to 255.
(*maxFetTemperature) = uint8FromBytes(_pg_data, &_pg_byteindex);
// Maximum recorded motor temperature
// Range of maxMotorTemperature is 0 to 255.
(*maxMotorTemperature) = uint8FromBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 1 > _pg_numbytes)
return 1;
// Maximum recorded battery voltage
// Range of maxRippleVoltage is 0 to 255.
(*maxRippleVoltage) = uint8FromBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Maximum recorded battery current
// Range of maxBatteryCurrent is -3276.7f to 3276.7f.
(*maxBatteryCurrent) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/10.0f);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Maximum recorded regen current
// Range of maxRegenCurrent is -3276.7f to 3276.7f.
(*maxRegenCurrent) = float32ScaledFrom2SignedBeBytes(_pg_data, &_pg_byteindex, 1.0f/10.0f);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Number of successful motor start events
// Range of totalStarts is 0 to 65535.
(*totalStarts) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 2 > _pg_numbytes)
return 1;
// Number of failed motor start events
// Range of failedStarts is 0 to 65535.
(*failedStarts) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// ESC run time
// Range of escRunTime is 0 to 4294967295.
(*escRunTime) = uint32FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// Motor run time
// Range of motorRunTime is 0 to 4294967295.
(*motorRunTime) = uint32FromBeBytes(_pg_data, &_pg_byteindex);
if(_pg_byteindex + 4 > _pg_numbytes)
return 1;
// Number of recorded motor desync events
// Range of desyncEvents is 0 to 4294967295.
(*desyncEvents) = uint32FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_TelltaleValuesPacket
/*!
* \brief Create the ESC_GitHash packet
*
* Git commit hash for the ESC firmware
* \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 encodeESC_GitHashPacketStructure(void* _pg_pkt, const ESC_GitHash_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// git commit hash
stringToBytes(_pg_user->hash, _pg_data, &_pg_byteindex, 8, 0);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_GitHashPacketID());
}// encodeESC_GitHashPacketStructure
/*!
* \brief Decode the ESC_GitHash packet
*
* Git commit hash for the ESC firmware
* \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 decodeESC_GitHashPacketStructure(const void* _pg_pkt, ESC_GitHash_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_GitHashPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_GitHashMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// git commit hash
stringFromBytes(_pg_user->hash, _pg_data, &_pg_byteindex, 8, 0);
return 1;
}// decodeESC_GitHashPacketStructure
/*!
* \brief Create the ESC_GitHash packet
*
* Git commit hash for the ESC firmware
* \param _pg_pkt points to the packet which will be created by this function
* \param hash is git commit hash
*/
void encodeESC_GitHashPacket(void* _pg_pkt, const char hash[8])
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// git commit hash
stringToBytes(hash, _pg_data, &_pg_byteindex, 8, 0);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_GitHashPacketID());
}// encodeESC_GitHashPacket
/*!
* \brief Decode the ESC_GitHash packet
*
* Git commit hash for the ESC firmware
* \param _pg_pkt points to the packet being decoded by this function
* \param hash receives git commit hash
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_GitHashPacket(const void* _pg_pkt, char hash[8])
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_GitHashPacketID())
return 0;
if(_pg_numbytes < getESC_GitHashMinDataLength())
return 0;
// git commit hash
stringFromBytes(hash, _pg_data, &_pg_byteindex, 8, 0);
return 1;
}// decodeESC_GitHashPacket
/*!
* \brief Create the ESC_PWMInputCalibration packet
*
* PWM input calibration
* \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 encodeESC_PWMInputCalibrationPacketStructure(void* _pg_pkt, const ESC_PWMInputCalibration_t* _pg_user)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Reserved bits for future use
_pg_data[_pg_byteindex] = 0;
// Enable median glitch filter for PWM input
_pg_data[_pg_byteindex] |= (uint8_t)((_pg_user->glitchFilter == true) ? 1 : 0) << 4;
// Protocol version (reserved for future use)
_pg_byteindex += 1; // close bit field
// PWM offset compensation value
// Range of pwmOffset is -128 to 127.
int8ToBytes(_pg_user->pwmOffset, _pg_data, &_pg_byteindex);
// PWM value corresponding with 0% throttle
// Range of inputMin is 0 to 65535.
uint16ToBeBytes(_pg_user->inputMin, _pg_data, &_pg_byteindex);
// PWM value corresponding with 1000% throttle
// Range of inputMax is 0 to 65535.
uint16ToBeBytes(_pg_user->inputMax, _pg_data, &_pg_byteindex);
// PWM arming threshold
// Range of armThreshold is 0 to 65535.
uint16ToBeBytes(_pg_user->armThreshold, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_PWMInputCalibrationPacketID());
}// encodeESC_PWMInputCalibrationPacketStructure
/*!
* \brief Decode the ESC_PWMInputCalibration packet
*
* PWM input calibration
* \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 decodeESC_PWMInputCalibrationPacketStructure(const void* _pg_pkt, ESC_PWMInputCalibration_t* _pg_user)
{
int _pg_numbytes;
int _pg_byteindex = 0;
const uint8_t* _pg_data;
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_PWMInputCalibrationPacketID())
return 0;
// Verify the packet size
_pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
if(_pg_numbytes < getESC_PWMInputCalibrationMinDataLength())
return 0;
// The raw data from the packet
_pg_data = getESCVelocityPacketDataConst(_pg_pkt);
// Reserved bits for future use
// Enable median glitch filter for PWM input
_pg_user->glitchFilter = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
// Protocol version (reserved for future use)
// Range of protocol is 0 to 15.
_pg_user->protocol = ((_pg_data[_pg_byteindex]) & 0xF);
_pg_byteindex += 1; // close bit field
// PWM offset compensation value
// Range of pwmOffset is -128 to 127.
_pg_user->pwmOffset = int8FromBytes(_pg_data, &_pg_byteindex);
// PWM value corresponding with 0% throttle
// Range of inputMin is 0 to 65535.
_pg_user->inputMin = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// PWM value corresponding with 1000% throttle
// Range of inputMax is 0 to 65535.
_pg_user->inputMax = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// PWM arming threshold
// Range of armThreshold is 0 to 65535.
_pg_user->armThreshold = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_PWMInputCalibrationPacketStructure
/*!
* \brief Create the ESC_PWMInputCalibration packet
*
* PWM input calibration
* \param _pg_pkt points to the packet which will be created by this function
* \param glitchFilter is Enable median glitch filter for PWM input
* \param pwmOffset is PWM offset compensation value
* \param inputMin is PWM value corresponding with 0% throttle
* \param inputMax is PWM value corresponding with 1000% throttle
* \param armThreshold is PWM arming threshold
*/
void encodeESC_PWMInputCalibrationPacket(void* _pg_pkt, bool glitchFilter, int8_t pwmOffset, uint16_t inputMin, uint16_t inputMax, uint16_t armThreshold)
{
uint8_t* _pg_data = getESCVelocityPacketData(_pg_pkt);
int _pg_byteindex = 0;
// Reserved bits for future use
_pg_data[_pg_byteindex] = 0;
// Enable median glitch filter for PWM input
_pg_data[_pg_byteindex] |= (uint8_t)((glitchFilter == true) ? 1 : 0) << 4;
// Protocol version (reserved for future use)
_pg_byteindex += 1; // close bit field
// PWM offset compensation value
// Range of pwmOffset is -128 to 127.
int8ToBytes(pwmOffset, _pg_data, &_pg_byteindex);
// PWM value corresponding with 0% throttle
// Range of inputMin is 0 to 65535.
uint16ToBeBytes(inputMin, _pg_data, &_pg_byteindex);
// PWM value corresponding with 1000% throttle
// Range of inputMax is 0 to 65535.
uint16ToBeBytes(inputMax, _pg_data, &_pg_byteindex);
// PWM arming threshold
// Range of armThreshold is 0 to 65535.
uint16ToBeBytes(armThreshold, _pg_data, &_pg_byteindex);
// complete the process of creating the packet
finishESCVelocityPacket(_pg_pkt, _pg_byteindex, getESC_PWMInputCalibrationPacketID());
}// encodeESC_PWMInputCalibrationPacket
/*!
* \brief Decode the ESC_PWMInputCalibration packet
*
* PWM input calibration
* \param _pg_pkt points to the packet being decoded by this function
* \param glitchFilter receives Enable median glitch filter for PWM input
* \param protocol receives Protocol version (reserved for future use)
* \param pwmOffset receives PWM offset compensation value
* \param inputMin receives PWM value corresponding with 0% throttle
* \param inputMax receives PWM value corresponding with 1000% throttle
* \param armThreshold receives PWM arming threshold
* \return 0 is returned if the packet ID or size is wrong, else 1
*/
int decodeESC_PWMInputCalibrationPacket(const void* _pg_pkt, bool* glitchFilter, uint8_t* protocol, int8_t* pwmOffset, uint16_t* inputMin, uint16_t* inputMax, uint16_t* armThreshold)
{
int _pg_byteindex = 0;
const uint8_t* _pg_data = getESCVelocityPacketDataConst(_pg_pkt);
int _pg_numbytes = getESCVelocityPacketSize(_pg_pkt);
// Verify the packet identifier
if(getESCVelocityPacketID(_pg_pkt) != getESC_PWMInputCalibrationPacketID())
return 0;
if(_pg_numbytes < getESC_PWMInputCalibrationMinDataLength())
return 0;
// Reserved bits for future use
// Enable median glitch filter for PWM input
(*glitchFilter) = (((_pg_data[_pg_byteindex] >> 4) & 0x1)) ? true : false;
// Protocol version (reserved for future use)
// Range of protocol is 0 to 15.
(*protocol) = ((_pg_data[_pg_byteindex]) & 0xF);
_pg_byteindex += 1; // close bit field
// PWM offset compensation value
// Range of pwmOffset is -128 to 127.
(*pwmOffset) = int8FromBytes(_pg_data, &_pg_byteindex);
// PWM value corresponding with 0% throttle
// Range of inputMin is 0 to 65535.
(*inputMin) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// PWM value corresponding with 1000% throttle
// Range of inputMax is 0 to 65535.
(*inputMax) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
// PWM arming threshold
// Range of armThreshold is 0 to 65535.
(*armThreshold) = uint16FromBeBytes(_pg_data, &_pg_byteindex);
return 1;
}// decodeESC_PWMInputCalibrationPacket
// end of ESCPackets.c