Initial ability to send a packet from RFPowerView
This commit is contained in:
35
include/BufferFiller.h
Normal file
35
include/BufferFiller.h
Normal 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
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <RF24.h>
|
#include <RF24.h>
|
||||||
#include "PacketReceiver.h"
|
#include "PacketReceiver.h"
|
||||||
#include "PacketParser.h"
|
#include "PacketParser.h"
|
||||||
|
#include "BufferFiller.h"
|
||||||
#include "PacketTypes.h"
|
#include "PacketTypes.h"
|
||||||
|
|
||||||
#define DEFAULT_RF_CHANNEL (7) //this is the channel HD shades use
|
#define DEFAULT_RF_CHANNEL (7) //this is the channel HD shades use
|
||||||
@@ -21,19 +22,25 @@ public:
|
|||||||
|
|
||||||
bool begin();
|
bool begin();
|
||||||
void loop();
|
void loop();
|
||||||
void startListening();
|
|
||||||
|
|
||||||
void setPacketCallback(std::function<void(const Packet*)> callback);
|
void setPacketCallback(std::function<void(const Packet*)> callback);
|
||||||
|
void sendPacket(const Packet* packet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RF24 radio;
|
RF24 radio;
|
||||||
PacketReceiver packetReceiver;
|
PacketReceiver packetReceiver;
|
||||||
PacketParser packetParser;
|
PacketParser packetParser;
|
||||||
|
BufferFiller bufferFiller;
|
||||||
uint8_t irqPin;
|
uint8_t irqPin;
|
||||||
uint8_t rfID[2];
|
uint8_t rfID[2];
|
||||||
|
|
||||||
std::function<void(const Packet*)> packetCallback;
|
std::function<void(const Packet*)> packetCallback;
|
||||||
|
|
||||||
|
uint8_t sendBuffer[32];
|
||||||
|
|
||||||
|
void startListening();
|
||||||
|
void startTransmitting();
|
||||||
|
|
||||||
void interruptHandler();
|
void interruptHandler();
|
||||||
|
|
||||||
void processBuffer(const uint8_t *buffer);
|
void processBuffer(const uint8_t *buffer);
|
||||||
|
|||||||
162
src/BufferFiller.cpp
Normal file
162
src/BufferFiller.cpp
Normal 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++;
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
RFPowerView::RFPowerView(uint8_t cePin, uint8_t csPin, uint8_t irqPin, uint16_t rfID) :
|
RFPowerView::RFPowerView(uint8_t cePin, uint8_t csPin, uint8_t irqPin, uint16_t rfID) :
|
||||||
radio(cePin, csPin),
|
radio(cePin, csPin),
|
||||||
packetReceiver(&radio),
|
packetReceiver(&radio),
|
||||||
|
bufferFiller(0x00, 0x00, 0x05),
|
||||||
irqPin(irqPin),
|
irqPin(irqPin),
|
||||||
rfID{static_cast<uint8_t>(rfID & 0xFF), static_cast<uint8_t>(rfID >> 8)},
|
rfID{static_cast<uint8_t>(rfID & 0xFF), static_cast<uint8_t>(rfID >> 8)},
|
||||||
packetCallback(nullptr) {}
|
packetCallback(nullptr) {}
|
||||||
@@ -16,6 +17,18 @@ bool RFPowerView::begin() {
|
|||||||
packetReceiver.setBufferCallback([this](const uint8_t* buffer) { this->processBuffer(buffer); });
|
packetReceiver.setBufferCallback([this](const uint8_t* buffer) { this->processBuffer(buffer); });
|
||||||
packetReceiver.setInvalidBufferCallback([this](const uint8_t* buffer) { this->processInvalidBuffer(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();
|
startListening();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -26,25 +39,22 @@ void RFPowerView::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RFPowerView::startListening() {
|
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.openReadingPipe(0, rfID);
|
||||||
|
|
||||||
radio.startListening();
|
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();
|
interrupts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RFPowerView::startTransmitting() {
|
||||||
|
radio.stopListening();
|
||||||
|
|
||||||
|
radio.setPALevel(RF24_PA_HIGH, true);
|
||||||
|
|
||||||
|
radio.openWritingPipe(rfID);
|
||||||
|
radio.powerUp();
|
||||||
|
}
|
||||||
|
|
||||||
void RFPowerView::interruptHandler() {
|
void RFPowerView::interruptHandler() {
|
||||||
packetReceiver.read();
|
packetReceiver.read();
|
||||||
}
|
}
|
||||||
@@ -66,3 +76,22 @@ void RFPowerView::processInvalidBuffer(const uint8_t *buffer) {
|
|||||||
void RFPowerView::setPacketCallback(std::function<void(const Packet*)> callback) {
|
void RFPowerView::setPacketCallback(std::function<void(const Packet*)> callback) {
|
||||||
packetCallback = 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user