init
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef ESP32
|
||||
#include <HardwareSerial.h>
|
||||
typedef HardwareSerial SerialType;
|
||||
#define SERIAL_TYPE HardwareSerial
|
||||
#elif defined(ESP8266)
|
||||
#include <HardwareSerial.h>
|
||||
typedef HardwareSerial SerialType;
|
||||
#define SERIAL_TYPE HardwareSerial
|
||||
#else
|
||||
#error "Unsupported platform. Only ESP32 and ESP8266 are supported."
|
||||
#endif
|
||||
|
||||
#include <pb_encode.h>
|
||||
#include <pb_decode.h>
|
||||
#include "hardware.pb.h"
|
||||
|
||||
// Define the role of this device
|
||||
// Uncomment one of the following defines to set the role
|
||||
#define HARDWARE_SERIAL_ROLE_CONTROL
|
||||
// #define HARDWARE_SERIAL_ROLE_SENSOR
|
||||
|
||||
// Based on role, define the message types
|
||||
#if defined(HARDWARE_SERIAL_ROLE_CONTROL)
|
||||
typedef hardware_SensorToControlMessage IncomingMessage;
|
||||
typedef hardware_ControlToSensorMessage OutgoingMessage;
|
||||
#define INCOMING_MESSAGE_SIZE hardware_SensorToControlMessage_size
|
||||
#define OUTGOING_MESSAGE_SIZE hardware_ControlToSensorMessage_size
|
||||
#define INCOMING_MESSAGE_FIELDS hardware_SensorToControlMessage_fields
|
||||
#define OUTGOING_MESSAGE_FIELDS hardware_ControlToSensorMessage_fields
|
||||
#define INCOMING_MESSAGE_INIT hardware_SensorToControlMessage_init_zero
|
||||
#define OUTGOING_MESSAGE_INIT hardware_ControlToSensorMessage_init_zero
|
||||
#elif defined(HARDWARE_SERIAL_ROLE_SENSOR)
|
||||
typedef hardware_ControlToSensorMessage IncomingMessage;
|
||||
typedef hardware_SensorToControlMessage OutgoingMessage;
|
||||
#define INCOMING_MESSAGE_SIZE hardware_ControlToSensorMessage_size
|
||||
#define OUTGOING_MESSAGE_SIZE hardware_SensorToControlMessage_size
|
||||
#define INCOMING_MESSAGE_FIELDS hardware_ControlToSensorMessage_fields
|
||||
#define OUTGOING_MESSAGE_FIELDS hardware_SensorToControlMessage_fields
|
||||
#define INCOMING_MESSAGE_INIT hardware_ControlToSensorMessage_init_zero
|
||||
#define OUTGOING_MESSAGE_INIT hardware_ControlToSensorMessage_init_zero
|
||||
#else
|
||||
#error "Must define either HARDWARE_SERIAL_ROLE_CONTROL or HARDWARE_SERIAL_ROLE_SENSOR"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @class ProtoSerial
|
||||
* @brief Manages serial communication with Protocol Buffers for ESP32/ESP8266.
|
||||
* Supports length-prefixed messages with CRC-8 checksum and sync bytes.
|
||||
* Configured for SENSOR or CONTROL role via HARDWARE_SERIAL_ROLE_* macros.
|
||||
* On ESP8266, uses UART0 (Serial, RX=GPIO3, TX=GPIO1). On ESP32, uses caller-provided UART.
|
||||
*/
|
||||
class ProtoSerial {
|
||||
public:
|
||||
using Callback = void (*)(const IncomingMessage&); ///< Callback for received messages.
|
||||
|
||||
/**
|
||||
* @brief Constructor.
|
||||
*/
|
||||
ProtoSerial();
|
||||
|
||||
/**
|
||||
* @brief Destructor. No-op (serial is managed by caller).
|
||||
*/
|
||||
~ProtoSerial();
|
||||
|
||||
/**
|
||||
* @brief Initializes serial communication with a caller-provided serial port.
|
||||
* @param serialPort Reference to a configured SerialType (e.g., Serial for ESP8266, HardwareSerial for ESP32).
|
||||
*/
|
||||
void begin(SerialType& serialPort);
|
||||
|
||||
/**
|
||||
* @brief Sends a Protocol Buffers message with sync bytes and CRC-8.
|
||||
* @param message The message to send (OutgoingMessage type).
|
||||
* @return True if sent successfully, false otherwise.
|
||||
*/
|
||||
bool sendMessage(const OutgoingMessage& message);
|
||||
|
||||
/**
|
||||
* @brief Checks for incoming messages (non-blocking).
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* @brief Checks if a message is available.
|
||||
* @return True if a message is ready to be read.
|
||||
*/
|
||||
bool hasMessage() const;
|
||||
|
||||
/**
|
||||
* @brief Gets the received message.
|
||||
* @return Reference to the received message (valid only if hasMessage() is true).
|
||||
*/
|
||||
const IncomingMessage& getMessage() const;
|
||||
|
||||
/**
|
||||
* @brief Clears the received message.
|
||||
*/
|
||||
void clearMessage();
|
||||
|
||||
/**
|
||||
* @brief Sets the callback for received messages.
|
||||
* @param cb Callback function to handle incoming messages.
|
||||
*/
|
||||
void setCallback(Callback cb);
|
||||
|
||||
/**
|
||||
* @brief Checks if the serial interface is initialized.
|
||||
* @return True if initialized.
|
||||
*/
|
||||
bool isInitialized() const { return initialized; }
|
||||
|
||||
/**
|
||||
* @brief Gets the last error message (for debugging).
|
||||
* @return Last error string or empty if none.
|
||||
*/
|
||||
const char* getLastError() const { return lastError; }
|
||||
|
||||
private:
|
||||
SerialType* serial; ///< Serial interface (pointer to caller-provided SerialType).
|
||||
bool initialized; ///< Tracks initialization state.
|
||||
char lastError[64]; ///< Last error message (fixed-size to avoid heap issues).
|
||||
Callback callback; ///< Callback for received messages.
|
||||
|
||||
// Framing constants
|
||||
static const uint8_t SYNC_START = 0xAA; ///< Start byte for message framing.
|
||||
static const uint8_t SYNC_END = 0xBB; ///< End byte for message framing.
|
||||
|
||||
// Receive state machine
|
||||
enum RxState {
|
||||
WAITING_FOR_SYNC_START, ///< Waiting for start byte (0xAA).
|
||||
WAITING_FOR_LENGTH, ///< Waiting for 2-byte length.
|
||||
READING_PAYLOAD, ///< Reading payload bytes.
|
||||
READING_CRC ///< Reading CRC-8 byte.
|
||||
};
|
||||
RxState currentState; ///< Current state of receive state machine.
|
||||
uint16_t payloadLength; ///< Length of incoming payload.
|
||||
uint8_t payloadBuffer[INCOMING_MESSAGE_SIZE + 10]; ///< Buffer for payload (plus overhead).
|
||||
IncomingMessage receivedMessage; ///< Decoded incoming message.
|
||||
bool messageAvailable; ///< True if a message is ready.
|
||||
unsigned long lastUpdate; ///< Timestamp of last update (for throttling).
|
||||
unsigned long lastByteTime; ///< Timestamp of last byte received (for timeout).
|
||||
|
||||
// Helper methods
|
||||
/**
|
||||
* @brief Processes a received payload and decodes it.
|
||||
* @param buffer Payload buffer.
|
||||
* @param length Payload length.
|
||||
*/
|
||||
void processReceivedMessage(uint8_t* buffer, uint16_t length);
|
||||
|
||||
/**
|
||||
* @brief Calculates CRC-8 for a buffer.
|
||||
* @param data Buffer to compute CRC over.
|
||||
* @param len Length of buffer.
|
||||
* @return CRC-8 value.
|
||||
*/
|
||||
uint8_t calculate_crc8(const uint8_t* data, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Logs a hex dump of a buffer (debug only).
|
||||
* @param data Buffer to dump.
|
||||
* @param len Length of buffer.
|
||||
* @param label Label for the dump.
|
||||
*/
|
||||
void dumpHex(const uint8_t* data, uint16_t len, const char* label);
|
||||
};
|
||||
|
||||
extern ProtoSerial pserial;
|
||||
Reference in New Issue
Block a user