From 7690298d25b6dd85c1ba641980b357a335c15a3e Mon Sep 17 00:00:00 2001 From: jgromes Date: Mon, 14 Jun 2021 20:59:38 +0200 Subject: [PATCH] [PHY] Added direct reception support --- keywords.txt | 3 + src/protocols/PhysicalLayer/PhysicalLayer.cpp | 52 +++++++++ src/protocols/PhysicalLayer/PhysicalLayer.h | 110 +++++++++++++----- 3 files changed, 136 insertions(+), 29 deletions(-) diff --git a/keywords.txt b/keywords.txt index 157e5ef1..d66029ac 100644 --- a/keywords.txt +++ b/keywords.txt @@ -140,6 +140,9 @@ invertIQ KEYWORD2 setOokThresholdType KEYWORD2 setOokPeakThresholdDecrement KEYWORD2 setOokFixedOrFloorThreshold KEYWORD2 +setDirectSyncWord KEYWORD2 +setDirectAction KEYWORD2 +readBit KEYWORD2 # RF69-specific setAESKey KEYWORD2 diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.cpp b/src/protocols/PhysicalLayer/PhysicalLayer.cpp index 722ee69f..9cdf7977 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.cpp +++ b/src/protocols/PhysicalLayer/PhysicalLayer.cpp @@ -3,6 +3,8 @@ PhysicalLayer::PhysicalLayer(float freqStep, size_t maxPacketLength) { _freqStep = freqStep; _maxPacketLength = maxPacketLength; + _bufferBitPos = 0; + _bufferWritePos = 0; } int16_t PhysicalLayer::transmit(__FlashStringHelper* fstr, uint8_t addr) { @@ -181,3 +183,53 @@ int16_t PhysicalLayer::startDirect() { state = setFrequencyDeviation(-1); return(state); } + +int16_t PhysicalLayer::available() { + return(_bufferWritePos); +} + +uint8_t PhysicalLayer::read() { + _gotSync = false; + _syncBuffer = 0; + _bufferWritePos--; + return(_buffer[_bufferReadPos++]); +} + +int16_t PhysicalLayer::setDirectSyncWord(uint32_t syncWord, uint8_t len) { + if((len > 32) || (len == 0)) { + return(ERR_INVALID_SYNC_WORD); + } + _directSyncWordMask = 0xFFFFFFFF >> (32 - len); + _directSyncWord = syncWord; + return(ERR_NONE); +} + +void PhysicalLayer::updateDirectBuffer(uint8_t bit) { + // check sync word + if(!_gotSync) { + _syncBuffer <<= 1; + _syncBuffer |= bit; + if((_syncBuffer & _directSyncWordMask) == _directSyncWord) { + _gotSync = true; + _bufferWritePos = 0; + _bufferReadPos = 0; + _bufferBitPos = 0; + } + + } else { + // save the bit + if(bit) { + _buffer[_bufferWritePos] |= 0x01 << _bufferBitPos; + } else { + _buffer[_bufferWritePos] &= ~(0x01 << _bufferBitPos); + } + _bufferBitPos++; + + // check complete byte + if(_bufferBitPos == 8) { + _buffer[_bufferWritePos] = Module::flipBits(_buffer[_bufferWritePos]); + _bufferWritePos++; + _bufferBitPos = 0; + } + } +} diff --git a/src/protocols/PhysicalLayer/PhysicalLayer.h b/src/protocols/PhysicalLayer/PhysicalLayer.h index b3fe2829..cc67d938 100644 --- a/src/protocols/PhysicalLayer/PhysicalLayer.h +++ b/src/protocols/PhysicalLayer/PhysicalLayer.h @@ -2,6 +2,7 @@ #define _RADIOLIB_PHYSICAL_LAYER_H #include "../../TypeDef.h" +#include "../../Module.h" /*! \class PhysicalLayer @@ -20,7 +21,7 @@ class PhysicalLayer { \param freqStep Frequency step of the synthesizer in Hz. - \param maxPacketLength Maximum length of packet that can be received by the module- + \param maxPacketLength Maximum length of packet that can be received by the module. */ PhysicalLayer(float freqStep, size_t maxPacketLength); @@ -216,53 +217,104 @@ class PhysicalLayer { float getFreqStep() const; /*! - \brief Query modem for the packet length of received payload. Must be implemented in module class. + \brief Query modem for the packet length of received payload. Must be implemented in module class. - \param update Update received packet length. Will return cached value when set to false. + \param update Update received packet length. Will return cached value when set to false. - \returns Length of last received packet in bytes. - */ - virtual size_t getPacketLength(bool update = true) = 0; + \returns Length of last received packet in bytes. + */ + virtual size_t getPacketLength(bool update = true) = 0; - /*! - \brief Get truly random number in range 0 - max. + /*! + \brief Get truly random number in range 0 - max. - \param max The maximum value of the random number (non-inclusive). + \param max The maximum value of the random number (non-inclusive). - \returns Random number. - */ - int32_t random(int32_t max); + \returns Random number. + */ + int32_t random(int32_t max); - /*! - \brief Get truly random number in range min - max. + /*! + \brief Get truly random number in range min - max. - \param min The minimum value of the random number (inclusive). + \param min The minimum value of the random number (inclusive). - \param max The maximum value of the random number (non-inclusive). + \param max The maximum value of the random number (non-inclusive). - \returns Random number. - */ - int32_t random(int32_t min, int32_t max); + \returns Random number. + */ + int32_t random(int32_t min, int32_t max); - /*! - \brief Get one truly random byte from RSSI noise. Must be implemented in module class. + /*! + \brief Get one truly random byte from RSSI noise. Must be implemented in module class. - \returns TRNG byte. - */ - virtual uint8_t random() = 0; + \returns TRNG byte. + */ + virtual uint8_t random() = 0; - /*! - \brief Configure module parameters for direct modes. Must be called prior to "ham" modes like RTTY or AX.25. Only available in FSK mode. + /*! + \brief Configure module parameters for direct modes. Must be called prior to "ham" modes like RTTY or AX.25. Only available in FSK mode. - \returns \ref status_codes - */ - int16_t startDirect(); + \returns \ref status_codes + */ + int16_t startDirect(); + + /*! + \brief Set sync word to be used to determine start of packet in direct reception mode. + + \param syncWord Sync word bits. + + \param len Sync word length in bits. + + \returns \ref status_codes + */ + int16_t setDirectSyncWord(uint32_t syncWord, uint8_t len); + + /*! + \brief Set interrupt service routine function to call when data bit is receveid in direct mode. Must be implemented in module class. + + \param func Pointer to interrupt service routine. + */ + virtual void setDirectAction(void (*func)(void)) = 0; + + /*! + \brief Function to read and process data bit in direct reception mode. Must be implemented in module class. + + \param pin Pin on which to read. + */ + virtual void readBit(uint8_t pin) = 0; + + /*! + \brief Get the number of direct mode bytes currently available in buffer. + + \returns Number of available bytes. + */ + int16_t available(); + + /*! + \brief Get data from direct mode buffer. + + \returns Byte from direct mode buffer. + */ + uint8_t read(); + + protected: + void updateDirectBuffer(uint8_t bit); #ifndef RADIOLIB_GODMODE private: #endif float _freqStep; size_t _maxPacketLength; + + uint8_t _bufferBitPos; + uint8_t _bufferWritePos; + uint8_t _bufferReadPos; + uint8_t _buffer[RADIOLIB_STATIC_ARRAY_SIZE]; + uint32_t _syncBuffer; + uint32_t _directSyncWord; + uint32_t _directSyncWordMask; + bool _gotSync; }; #endif