WIP: Making RFPowerView class

This commit is contained in:
2023-12-22 12:05:24 +11:00
parent c84c2dfbdc
commit 9d507fdb0b
7 changed files with 173 additions and 63 deletions

View File

@@ -2,53 +2,14 @@
#define PACKET_PARSER_H
#include <Arduino.h>
#include <variant>
// Define packet types
enum class PacketType {
OPEN,
CLOSE,
STOP,
FIELDS,
FIELD_COMMAND,
UNKNOWN
};
enum class FieldType {
VALUE,
SET,
FETCH,
UNKNOWN
};
struct Field {
uint8_t identifier;
FieldType type;
bool hasValue;
std::variant<std::monostate, uint8_t, uint16_t> value;
};
struct FieldsParameters {
std::vector<Field> fields;
};
using PacketParameters = std::variant<std::monostate, FieldsParameters>;
// Define Message structure
struct Packet {
uint16_t source;
uint16_t destination;
PacketType type;
PacketParameters parameters;
};
#include "PacketTypes.h"
class PacketParser {
public:
PacketParser();
~PacketParser();
bool parsePacket(const uint8_t *buffer, Packet& message);
bool parsePacket(const uint8_t *buffer, Packet& packet);
private:
bool parseFields(const uint8_t *buffer, std::vector<Field>& fields);
};

View File

@@ -3,6 +3,7 @@
#define CIRCULAR_BUFFER_INT_SAFE
#include <functional>
#include <RF24.h>
#include <CircularBuffer.h>
#include "PacketCRC.h"
@@ -22,8 +23,8 @@ public:
void loop();
void read();
void setPacketCallback(void (*callback)(const uint8_t *buffer));
void setInvalidPacketCallback(void (*callback)(const uint8_t *buffer));
void setPacketCallback(std::function<void(const uint8_t*)> callback);
void setInvalidPacketCallback(std::function<void(const uint8_t*)> callback);
private:
RF24 *radio;
@@ -34,8 +35,8 @@ private:
CircularBuffer<uint8_t*, EMPTY_BUFFER_COUNT> freeBuffers;
CircularBuffer<uint8_t*, VALID_BUFFER_COUNT> receivedBuffers;
void (*packetCallback)(const uint8_t *buffer);
void (*invalidPacketCallback)(const uint8_t *buffer);
std::function<void(const uint8_t*)> packetCallback;
std::function<void(const uint8_t*)> invalidPacketCallback;
bool isSanePacket(uint8_t *buffer);
bool isValidPacket(uint8_t *buffer);

47
include/PacketTypes.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef PACKET_TYPES_H
#define PACKET_TYPES_H
#include <Arduino.h>
#include <variant>
// Define packet types
enum class PacketType {
OPEN,
CLOSE,
STOP,
FIELDS,
FIELD_COMMAND,
UNKNOWN
};
enum class FieldType {
VALUE,
SET,
FETCH,
UNKNOWN
};
struct Field {
uint8_t identifier;
FieldType type;
bool hasValue;
std::variant<std::monostate, uint8_t, uint16_t> value;
};
struct FieldsParameters {
std::vector<Field> fields;
};
using PacketParameters = std::variant<std::monostate, FieldsParameters>;
// Define Message structure
struct Packet {
uint16_t source;
uint16_t destination;
PacketType type;
PacketParameters parameters;
};
#endif // PACKET_TYPES_H

38
include/RFPowerView.h Normal file
View File

@@ -0,0 +1,38 @@
#ifndef RFPOWERVIEW_H
#define RFPOWERVIEW_H
#include <Arduino.h>
#include <RF24.h>
#include "PacketReceiver.h"
#include "PacketParser.h"
#include "PacketTypes.h"
#define DEFAULT_RF_CHANNEL (7) //this is the channel HD shades use
#define DEFAULT_RF_DATARATE (RF24_1MBPS) //this is the speed HD shades use
class RFPowerView {
public:
RFPowerView(
uint8_t cePin,
uint8_t csPin,
uint8_t irqPin,
uint16_t rfID
);
bool begin();
void loop();
void startListening();
private:
RF24 radio;
PacketReceiver packetReceiver;
PacketParser packetParser;
uint8_t irqPin;
uint8_t rfID[2];
void interruptHandler();
void processPacketBuffer(const uint8_t *buffer);
void processInvalidPacketBuffer(const uint8_t *buffer);
};
#endif // RFPOWERVIEW_H

View File

@@ -8,33 +8,33 @@ PacketParser::~PacketParser()
{
}
bool PacketParser::parsePacket(const uint8_t *buffer, Packet& message)
bool PacketParser::parsePacket(const uint8_t *buffer, Packet& packet)
{
message.source = (uint16_t)(buffer[14] << 8 | buffer[15]);
message.destination = (uint16_t)(buffer[12] << 8 | buffer[13]);
packet.source = (uint16_t)(buffer[14] << 8 | buffer[15]);
packet.destination = (uint16_t)(buffer[12] << 8 | buffer[13]);
if (buffer[16] == 0x52 && buffer[17] == 0x53) {
message.type = PacketType::STOP;
message.parameters = std::monostate{};
packet.type = PacketType::STOP;
packet.parameters = std::monostate{};
} else if (buffer[16] == 0x52 && buffer[17] == 0x44) {
message.type = PacketType::CLOSE;
message.parameters = std::monostate{};
packet.type = PacketType::CLOSE;
packet.parameters = std::monostate{};
} else if (buffer[16] == 0x52 && buffer[17] == 0x55) {
message.type = PacketType::OPEN;
message.parameters = std::monostate{};
packet.type = PacketType::OPEN;
packet.parameters = std::monostate{};
} else if (buffer[16] == 0x21 && buffer[17] == 0x5A) {
message.type = PacketType::FIELDS;
packet.type = PacketType::FIELDS;
std::vector<Field> fields;
parseFields(buffer, fields);
message.parameters = FieldsParameters{fields};
packet.parameters = FieldsParameters{fields};
} else if (buffer[16] == 0x3F && buffer[17] == 0x5A) {
message.type = PacketType::FIELD_COMMAND;
packet.type = PacketType::FIELD_COMMAND;
std::vector<Field> fields;
parseFields(buffer, fields);
message.parameters = FieldsParameters{fields};
packet.parameters = FieldsParameters{fields};
} else {
message.type = PacketType::UNKNOWN;
message.parameters = std::monostate{};
packet.type = PacketType::UNKNOWN;
packet.parameters = std::monostate{};
return false;
}

View File

@@ -1,6 +1,6 @@
#include "PacketReceiver.h"
PacketReceiver::PacketReceiver(RF24 *radio) : radio(radio), packetCallback(nullptr), invalidPacketCallback(nullptr) {
PacketReceiver::PacketReceiver(RF24 *radio) : radio(radio) {
for (int i = 0; i < TOTAL_BUFFER_COUNT; i++) {
if (!freeBuffers.isFull()) {
freeBuffers.push(buffers[i]);
@@ -69,11 +69,11 @@ void PacketReceiver::read() {
}
}
void PacketReceiver::setPacketCallback(void (*callback)(const uint8_t *buffer)) {
void PacketReceiver::setPacketCallback(std::function<void(const uint8_t*)> callback) {
this->packetCallback = callback;
}
void PacketReceiver::setInvalidPacketCallback(void (*callback)(const uint8_t *buffer))
void PacketReceiver::setInvalidPacketCallback(std::function<void(const uint8_t*)> callback)
{
this->invalidPacketCallback = callback;
}

63
src/RFPowerView.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "RFPowerView.h"
#include <FunctionalInterrupt.h>
RFPowerView::RFPowerView(uint8_t cePin, uint8_t csPin, uint8_t irqPin, uint16_t rfID) :
radio(cePin, csPin),
packetReceiver(&radio),
irqPin(irqPin),
rfID{static_cast<uint8_t>(rfID & 0xFF), static_cast<uint8_t>(rfID >> 8)} {}
bool RFPowerView::begin() {
if (!radio.begin()) {
return false;
}
packetReceiver.setPacketCallback([this](const uint8_t* buffer) { this->processPacketBuffer(buffer); });
packetReceiver.setInvalidPacketCallback([this](const uint8_t* buffer) { this->processInvalidPacketBuffer(buffer); });
startListening();
return true;
}
void RFPowerView::loop() {
packetReceiver.loop();
}
void RFPowerView::startListening() {
radio.setChannel(DEFAULT_RF_CHANNEL);
radio.setDataRate(DEFAULT_RF_DATARATE);
radio.setAutoAck(false);
radio.disableCRC();
radio.setPayloadSize(32);
// TODO: Verify that putting this in begin() instead of startListening() works
pinMode(irqPin, INPUT);
radio.setAddressWidth(2);
radio.openReadingPipe(0, rfID);
radio.startListening();
Serial.println("Listening");
// TODO: Verify that putting this in being() instead of startListening() works
attachInterrupt(digitalPinToInterrupt(irqPin), std::bind(&RFPowerView::interruptHandler, this), FALLING);
interrupts();
}
void RFPowerView::interruptHandler() {
packetReceiver.read();
}
void RFPowerView::processPacketBuffer(const uint8_t *buffer) {
Packet packet;
bool result = packetParser.parsePacket(buffer, packet);
if (result) {
Serial.print("Parsed packet! ");
Serial.print((int)packet.type);
Serial.println();
}
}
void RFPowerView::processInvalidPacketBuffer(const uint8_t *buffer) {
}