From 9d507fdb0bddd8d4d46270121ccc0fa51c8c2562 Mon Sep 17 00:00:00 2001 From: Matt Way Date: Fri, 22 Dec 2023 12:05:24 +1100 Subject: [PATCH] WIP: Making RFPowerView class --- include/PacketParser.h | 43 ++------------------------- include/PacketReceiver.h | 9 +++--- include/PacketTypes.h | 47 ++++++++++++++++++++++++++++++ include/RFPowerView.h | 38 ++++++++++++++++++++++++ src/PacketParser.cpp | 30 +++++++++---------- src/PacketReceiver.cpp | 6 ++-- src/RFPowerView.cpp | 63 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 173 insertions(+), 63 deletions(-) create mode 100644 include/PacketTypes.h create mode 100644 include/RFPowerView.h create mode 100644 src/RFPowerView.cpp diff --git a/include/PacketParser.h b/include/PacketParser.h index ca02433..3d63e57 100644 --- a/include/PacketParser.h +++ b/include/PacketParser.h @@ -2,53 +2,14 @@ #define PACKET_PARSER_H #include -#include - -// 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 value; -}; - -struct FieldsParameters { - std::vector fields; -}; - -using PacketParameters = std::variant; - - -// 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& fields); }; diff --git a/include/PacketReceiver.h b/include/PacketReceiver.h index 774be91..db1fdbf 100644 --- a/include/PacketReceiver.h +++ b/include/PacketReceiver.h @@ -3,6 +3,7 @@ #define CIRCULAR_BUFFER_INT_SAFE +#include #include #include #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 callback); + void setInvalidPacketCallback(std::function callback); private: RF24 *radio; @@ -34,8 +35,8 @@ private: CircularBuffer freeBuffers; CircularBuffer receivedBuffers; - void (*packetCallback)(const uint8_t *buffer); - void (*invalidPacketCallback)(const uint8_t *buffer); + std::function packetCallback; + std::function invalidPacketCallback; bool isSanePacket(uint8_t *buffer); bool isValidPacket(uint8_t *buffer); diff --git a/include/PacketTypes.h b/include/PacketTypes.h new file mode 100644 index 0000000..8d7109e --- /dev/null +++ b/include/PacketTypes.h @@ -0,0 +1,47 @@ +#ifndef PACKET_TYPES_H +#define PACKET_TYPES_H + +#include +#include + +// 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 value; +}; + +struct FieldsParameters { + std::vector fields; +}; + +using PacketParameters = std::variant; + + +// Define Message structure +struct Packet { + uint16_t source; + uint16_t destination; + PacketType type; + PacketParameters parameters; +}; + + +#endif // PACKET_TYPES_H \ No newline at end of file diff --git a/include/RFPowerView.h b/include/RFPowerView.h new file mode 100644 index 0000000..b7c6351 --- /dev/null +++ b/include/RFPowerView.h @@ -0,0 +1,38 @@ +#ifndef RFPOWERVIEW_H +#define RFPOWERVIEW_H + +#include +#include +#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 \ No newline at end of file diff --git a/src/PacketParser.cpp b/src/PacketParser.cpp index 18bb790..2c3c51c 100644 --- a/src/PacketParser.cpp +++ b/src/PacketParser.cpp @@ -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 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 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; } diff --git a/src/PacketReceiver.cpp b/src/PacketReceiver.cpp index 844deea..ef1ba59 100644 --- a/src/PacketReceiver.cpp +++ b/src/PacketReceiver.cpp @@ -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 callback) { this->packetCallback = callback; } -void PacketReceiver::setInvalidPacketCallback(void (*callback)(const uint8_t *buffer)) +void PacketReceiver::setInvalidPacketCallback(std::function callback) { this->invalidPacketCallback = callback; } diff --git a/src/RFPowerView.cpp b/src/RFPowerView.cpp new file mode 100644 index 0000000..955e255 --- /dev/null +++ b/src/RFPowerView.cpp @@ -0,0 +1,63 @@ +#include "RFPowerView.h" +#include + +RFPowerView::RFPowerView(uint8_t cePin, uint8_t csPin, uint8_t irqPin, uint16_t rfID) : + radio(cePin, csPin), + packetReceiver(&radio), + irqPin(irqPin), + rfID{static_cast(rfID & 0xFF), static_cast(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) { + +} \ No newline at end of file