#pragma once
#include "Arduino.h"
#include "PacketCRC.h"
typedef void (*functionPtr)();
const int8_t CONTINUE = 3;
const int8_t NEW_DATA = 2;
const int8_t NO_DATA = 1;
const int8_t CRC_ERROR = 0;
const int8_t PAYLOAD_ERROR = -1;
const int8_t STOP_BYTE_ERROR = -2;
const int8_t STALE_PACKET_ERROR = -3;
const uint8_t START_BYTE = 0x7E;
const uint8_t STOP_BYTE = 0x81;
const uint8_t PREAMBLE_SIZE = 4;
const uint8_t POSTAMBLE_SIZE = 2;
const uint8_t MAX_PACKET_SIZE = 0xFE;
const uint8_t DEFAULT_TIMEOUT = 50;
struct configST
{
Stream* debugPort = &Serial;
bool debug = true;
const functionPtr* callbacks = NULL;
uint8_t callbacksLen = 0;
uint32_t timeout = __UINT32_MAX__;
};
class Packet
{
public: uint8_t txBuff[MAX_PACKET_SIZE];
uint8_t rxBuff[MAX_PACKET_SIZE];
uint8_t preamble[PREAMBLE_SIZE] = {START_BYTE, 0, 0, 0};
uint8_t postamble[POSTAMBLE_SIZE] = {0, STOP_BYTE};
uint8_t bytesRead = 0;
int8_t status = 0;
void begin(const configST& configs);
void begin(const bool& _debug = true, Stream& _debugPort = Serial, const uint32_t& _timeout = DEFAULT_TIMEOUT);
uint8_t constructPacket(const uint16_t& messageLen, const uint8_t& packetID = 0);
uint8_t parse(const uint8_t& recChar, const bool& valid = true);
uint8_t currentPacketID();
void reset();
template <typename T>
uint16_t txObj(const T& val, const uint16_t& index = 0, const uint16_t& len = sizeof(T))
{
uint8_t* ptr = (uint8_t*)&val;
uint16_t maxIndex;
if ((len + index) > MAX_PACKET_SIZE)
maxIndex = MAX_PACKET_SIZE;
else
maxIndex = len + index;
for (uint16_t i = index; i < maxIndex; i++)
{
txBuff[i] = *ptr;
ptr++;
}
return maxIndex;
}
template <typename T>
uint16_t rxObj(const T& val, const uint16_t& index = 0, const uint16_t& len = sizeof(T))
{
uint8_t* ptr = (uint8_t*)&val;
uint16_t maxIndex;
if ((len + index) > MAX_PACKET_SIZE)
maxIndex = MAX_PACKET_SIZE;
else
maxIndex = len + index;
for (uint16_t i = index; i < maxIndex; i++)
{
*ptr = rxBuff[i];
ptr++;
}
return maxIndex;
}
private: enum fsm
{
find_start_byte,
find_id_byte,
find_overhead_byte,
find_payload_len,
find_payload,
find_crc,
find_end_byte
};
fsm state = find_start_byte;
const functionPtr* callbacks = NULL;
uint8_t callbacksLen = 0;
Stream* debugPort;
bool debug = false;
uint8_t bytesToRec = 0;
uint8_t payIndex = 0;
uint8_t idByte = 0;
uint8_t overheadByte = 0;
uint8_t recOverheadByte = 0;
uint32_t packetStart = 0;
uint32_t timeout;
void calcOverhead(uint8_t arr[], const uint8_t& len);
int16_t findLast(uint8_t arr[], const uint8_t& len);
void stuffPacket(uint8_t arr[], const uint8_t& len);
void unpackPacket(uint8_t arr[]);
};