Initial ability to send a packet from RFPowerView

This commit is contained in:
2023-12-31 10:21:23 +11:00
parent 09fd491fdc
commit 2ccbbd18dd
4 changed files with 247 additions and 14 deletions

35
include/BufferFiller.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef BUFFERFILLER_H
#define BUFFERFILLER_H
#include <Arduino.h>
#include "PacketCRC.h"
#include "PacketTypes.h"
class BufferFiller {
public:
BufferFiller(uint8_t rollingCode1, uint8_t rollingCode2, uint8_t protocolVersion);
~BufferFiller();
bool fill(uint8_t *buffer, const Packet* packet);
private:
uint8_t rollingCode1;
uint8_t rollingCode2;
uint8_t protocolVersion;
PacketCRC packetCRC;
void setPacketSize(uint8_t *buffer, uint8_t);
void setConstants(uint8_t *buffer);
void setSourceAddress(uint8_t *buffer, uint16_t);
void setDestinationAddress(uint8_t *buffer, uint16_t);
void setRollingCodes(uint8_t *buffer);
void setProtocolVersion(uint8_t *buffer, uint8_t);
void setOpenPacketData(uint8_t *buffer);
void setClosePacketData(uint8_t *buffer);
void setStopPacketData(uint8_t *buffer);
void calculateCRC(uint8_t *buffer);
void incrementRollingCodes();
};
#endif // BUFFERFILLER_H

View File

@@ -5,6 +5,7 @@
#include <RF24.h>
#include "PacketReceiver.h"
#include "PacketParser.h"
#include "BufferFiller.h"
#include "PacketTypes.h"
#define DEFAULT_RF_CHANNEL (7) //this is the channel HD shades use
@@ -21,19 +22,25 @@ public:
bool begin();
void loop();
void startListening();
void setPacketCallback(std::function<void(const Packet*)> callback);
void sendPacket(const Packet* packet);
private:
RF24 radio;
PacketReceiver packetReceiver;
PacketParser packetParser;
BufferFiller bufferFiller;
uint8_t irqPin;
uint8_t rfID[2];
std::function<void(const Packet*)> packetCallback;
uint8_t sendBuffer[32];
void startListening();
void startTransmitting();
void interruptHandler();
void processBuffer(const uint8_t *buffer);

162
src/BufferFiller.cpp Normal file
View File

@@ -0,0 +1,162 @@
#include "BufferFiller.h"
BufferFiller::BufferFiller(uint8_t rollingCode1, uint8_t rollingCode2, uint8_t protocolVersion) :
rollingCode1(rollingCode1),
rollingCode2(rollingCode2),
protocolVersion(protocolVersion)
{
}
BufferFiller::~BufferFiller()
{
}
bool BufferFiller::fill(uint8_t *buffer, const Packet* packet) {
uint8_t packetSize = 0;
switch(packet->type) {
case PacketType::STOP:
case PacketType::OPEN:
case PacketType::CLOSE:
packetSize = 0x11;
break;
// TODO: Calculate fields length in buffer
default:
return false;
}
setPacketSize(buffer, packetSize);
setConstants(buffer);
setProtocolVersion(buffer, protocolVersion);
setSourceAddress(buffer, packet->source);
setDestinationAddress(buffer, packet->destination);
switch(packet->type) {
case PacketType::STOP:
setStopPacketData(buffer);
break;
case PacketType::CLOSE:
setClosePacketData(buffer);
break;
case PacketType::OPEN:
setOpenPacketData(buffer);
break;
default:
return false;
}
setRollingCodes(buffer);
calculateCRC(buffer);
incrementRollingCodes();
return true;
}
void BufferFiller::setOpenPacketData(uint8_t *buffer)
{
buffer[16] = 0x52;
buffer[17] = 0x55;
buffer[18] = 0x00;
}
void BufferFiller::setClosePacketData(uint8_t *buffer)
{
buffer[16] = 0x52;
buffer[17] = 0x44;
buffer[18] = 0x00;
}
void BufferFiller::setStopPacketData(uint8_t *buffer)
{
buffer[16] = 0x52;
buffer[17] = 0x53;
buffer[18] = 0x00;
}
/*
void BufferFiller::setPositionCommand(uint8_t *buffer, float percentage)
{
// packetSize = 0x15;
buffer[16] = 0x3F; // Field command
buffer[17] = 0x5A; // Constant
buffer[18] = 0x04; // Field of 4 bytes
buffer[19] = 0x40; // Field type (0x40 is set)
buffer[20] = 0x50; // ID of position field
uint16_t position = (uint16_t)(0xFFFF * percentage);
buffer[21] = (uint8_t)(position & 0x00FF);
buffer[22] = (uint8_t)((position & 0xFF00) >> 8);
}
void BufferFiller::setFetchPositionCommand(uint8_t *buffer) {
// packetSize = 0x13;
buffer[16] = 0x3F; // Field command
buffer[17] = 0x5A; // Constant
buffer[18] = 0x02; // Field of 2 bytes
buffer[19] = 0x3F; // Field type (0x3F is fetch)
buffer[20] = 0x50; // ID of position field
}
*/
void BufferFiller::setPacketSize(uint8_t *buffer, uint8_t length) {
buffer[1] = length; // Packet size
}
void BufferFiller::setConstants(uint8_t *buffer) {
buffer[0] = 0xC0; // Header byte
buffer[2] = 0x00; // Constant when sending, can be 0x10 when receiving a packet
buffer[3] = 0x05; // Constant
buffer[5] = 0xFF; // Constant
buffer[6] = 0xFF; // Constant
buffer[9] = 0x86; // Constant?
}
void BufferFiller::setSourceAddress(uint8_t *buffer, uint16_t sourceID) {
// Physical source address (could be the address of a repeater when receiving a packet)
buffer[7] = (uint8_t)((sourceID & 0xFF00) >> 8);
buffer[8] = (uint8_t)(sourceID & 0x00FF);
// Logical source address (usually the same as the physical source address)
buffer[14] = (uint8_t)((sourceID & 0xFF00) >> 8);
buffer[15] = (uint8_t)(sourceID & 0x00FF);
}
void BufferFiller::setDestinationAddress(uint8_t *buffer, uint16_t targetID) {
// Logical target address
buffer[12] = (uint8_t)((targetID & 0xFF00) >> 8);
buffer[13] = (uint8_t)(targetID & 0x00FF);
}
void BufferFiller::setRollingCodes(uint8_t *buffer) {
buffer[4] = rollingCode1; // Rolling code 1
buffer[11] = rollingCode2; // Rolling code 2
}
void BufferFiller::setProtocolVersion(uint8_t *buffer, uint8_t version) {
buffer[10] = version; // Protocol version?
}
void BufferFiller::calculateCRC(uint8_t *buffer) { // must be called after the buffer has been filled
uint8_t length = buffer[1];
uint16_t result = packetCRC.calculate(buffer);
uint8_t checksum1 = (uint8_t)((result & 0xFF00) >> 8);
uint8_t checksum2 = (uint8_t)(result & 0x00FF);
buffer[length + 2] = checksum1; // Checksum
buffer[length + 3] = checksum2; // Checksum
}
void BufferFiller::incrementRollingCodes() {
rollingCode1++;
rollingCode2++;
}

View File

@@ -4,6 +4,7 @@
RFPowerView::RFPowerView(uint8_t cePin, uint8_t csPin, uint8_t irqPin, uint16_t rfID) :
radio(cePin, csPin),
packetReceiver(&radio),
bufferFiller(0x00, 0x00, 0x05),
irqPin(irqPin),
rfID{static_cast<uint8_t>(rfID & 0xFF), static_cast<uint8_t>(rfID >> 8)},
packetCallback(nullptr) {}
@@ -16,6 +17,18 @@ bool RFPowerView::begin() {
packetReceiver.setBufferCallback([this](const uint8_t* buffer) { this->processBuffer(buffer); });
packetReceiver.setInvalidBufferCallback([this](const uint8_t* buffer) { this->processInvalidBuffer(buffer); });
pinMode(irqPin, INPUT);
attachInterrupt(digitalPinToInterrupt(irqPin), std::bind(&RFPowerView::interruptHandler, this), FALLING);
radio.setChannel(DEFAULT_RF_CHANNEL);
radio.setDataRate(DEFAULT_RF_DATARATE);
radio.setAutoAck(false);
radio.disableCRC();
radio.setRetries(0, 0);
radio.setPayloadSize(32);
radio.setAddressWidth(2);
startListening();
return true;
@@ -26,25 +39,22 @@ void RFPowerView::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::startTransmitting() {
radio.stopListening();
radio.setPALevel(RF24_PA_HIGH, true);
radio.openWritingPipe(rfID);
radio.powerUp();
}
void RFPowerView::interruptHandler() {
packetReceiver.read();
}
@@ -66,3 +76,22 @@ void RFPowerView::processInvalidBuffer(const uint8_t *buffer) {
void RFPowerView::setPacketCallback(std::function<void(const Packet*)> callback) {
packetCallback = callback;
}
void RFPowerView::sendPacket(const Packet* packet) {
if (bufferFiller.fill(sendBuffer, packet)) {
startTransmitting();
uint8_t bytecount = sendBuffer[1] + 4;
for (int j = 1; j < 5; j++) {
radio.openWritingPipe(rfID);
for (int i = 1; i < 200; i++) {
radio.writeFast(sendBuffer, bytecount);
}
delay(100);
radio.flush_tx();
radio.txStandBy();
}
startListening();
}
}