Added FSK4 protocol, compatible with Horus Binary 4FSK modulation
This commit is contained in:
parent
251dd438a0
commit
2de09e1b0a
3 changed files with 202 additions and 0 deletions
|
@ -97,6 +97,7 @@
|
||||||
#include "protocols/Morse/Morse.h"
|
#include "protocols/Morse/Morse.h"
|
||||||
#include "protocols/RTTY/RTTY.h"
|
#include "protocols/RTTY/RTTY.h"
|
||||||
#include "protocols/SSTV/SSTV.h"
|
#include "protocols/SSTV/SSTV.h"
|
||||||
|
#include "protocols/FSK4/FSK4.h"
|
||||||
|
|
||||||
// transport layer protocols
|
// transport layer protocols
|
||||||
#include "protocols/TransportLayer/TransportLayer.h"
|
#include "protocols/TransportLayer/TransportLayer.h"
|
||||||
|
|
119
src/protocols/FSK4/FSK4.cpp
Normal file
119
src/protocols/FSK4/FSK4.cpp
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#include "FSK4.h"
|
||||||
|
#if !defined(RADIOLIB_EXCLUDE_FSK4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FSK4Client::FSK4Client(PhysicalLayer* phy) {
|
||||||
|
_phy = phy;
|
||||||
|
#if !defined(RADIOLIB_EXCLUDE_AFSK)
|
||||||
|
_audio = nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if !defined(RADIOLIB_EXCLUDE_AFSK)
|
||||||
|
// FSK4Client::FSK4Client(AFSKClient* audio) {
|
||||||
|
// _phy = audio->_phy;
|
||||||
|
// _audio = audio;
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
int16_t FSK4Client::begin(float base, uint32_t shift, uint16_t rate) {
|
||||||
|
// save configuration
|
||||||
|
_baseHz = base;
|
||||||
|
_shiftHz = shift;
|
||||||
|
|
||||||
|
|
||||||
|
// calculate duration of 1 bit
|
||||||
|
_bitDuration = (uint32_t)1000000/rate;
|
||||||
|
|
||||||
|
// calculate module carrier frequency resolution
|
||||||
|
uint32_t step = round(_phy->getFreqStep());
|
||||||
|
|
||||||
|
// check minimum shift value
|
||||||
|
if(shift < step / 2) {
|
||||||
|
return(ERR_INVALID_RTTY_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// round shift to multiples of frequency step size
|
||||||
|
if(shift % step < (step / 2)) {
|
||||||
|
_shift = shift / step;
|
||||||
|
} else {
|
||||||
|
_shift = (shift / step) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write resultant tones into arrays for quick lookup when modulating.
|
||||||
|
_tones[0] = 0;
|
||||||
|
_tones[1] = _shift;
|
||||||
|
_tones[2] = _shift*2;
|
||||||
|
_tones[3] = _shift*3;
|
||||||
|
|
||||||
|
_tonesHz[0] = 0;
|
||||||
|
_tonesHz[1] = _shiftHz;
|
||||||
|
_tonesHz[2] = _shiftHz*2;
|
||||||
|
_tonesHz[3] = _shiftHz*3;
|
||||||
|
|
||||||
|
// calculate 24-bit frequency
|
||||||
|
_base = (base * 1000000.0) / _phy->getFreqStep();
|
||||||
|
|
||||||
|
// configure for direct mode
|
||||||
|
return(_phy->startDirect());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSK4Client::idle() {
|
||||||
|
// Idle at Tone 0.
|
||||||
|
tone(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FSK4Client::write(uint8_t* buff, size_t len) {
|
||||||
|
size_t n = 0;
|
||||||
|
for(size_t i = 0; i < len; i++) {
|
||||||
|
n += FSK4Client::write(buff[i]);
|
||||||
|
}
|
||||||
|
FSK4Client::standby();
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FSK4Client::write(uint8_t b) {
|
||||||
|
|
||||||
|
int k;
|
||||||
|
// Send symbols MSB first.
|
||||||
|
for (k=0;k<4;k++)
|
||||||
|
{
|
||||||
|
// Extract 4FSK symbol (2 bits)
|
||||||
|
uint8_t symbol = (b & 0xC0) >> 6;
|
||||||
|
// Modulate
|
||||||
|
FSK4Client::tone(symbol);
|
||||||
|
// Shift to next symbol.
|
||||||
|
b = b << 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSK4Client::tone(uint8_t i) {
|
||||||
|
uint32_t start = Module::micros();
|
||||||
|
transmitDirect(_base + _tones[i], _baseHz + _tonesHz[i]);
|
||||||
|
while(Module::micros() - start < _bitDuration) {
|
||||||
|
Module::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t FSK4Client::transmitDirect(uint32_t freq, uint32_t freqHz) {
|
||||||
|
#if !defined(RADIOLIB_EXCLUDE_AFSK)
|
||||||
|
if(_audio != nullptr) {
|
||||||
|
return(_audio->tone(freqHz));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(_phy->transmitDirect(freq));
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t FSK4Client::standby() {
|
||||||
|
#if !defined(RADIOLIB_EXCLUDE_AFSK)
|
||||||
|
if(_audio != nullptr) {
|
||||||
|
return(_audio->noTone());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(_phy->standby());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
82
src/protocols/FSK4/FSK4.h
Normal file
82
src/protocols/FSK4/FSK4.h
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
#if !defined(_RADIOLIB_FSK4_H)
|
||||||
|
#define _RADIOLIB_FSK4_H
|
||||||
|
|
||||||
|
#include "../../TypeDef.h"
|
||||||
|
|
||||||
|
#if !defined(RADIOLIB_EXCLUDE_FSK4)
|
||||||
|
|
||||||
|
#include "../PhysicalLayer/PhysicalLayer.h"
|
||||||
|
#include "../AFSK/AFSK.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class FSK4Client
|
||||||
|
|
||||||
|
\brief Client for FSK-4 communication. The public interface is the same as Arduino Serial.
|
||||||
|
*/
|
||||||
|
class FSK4Client {
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
\brief Constructor for FSK-4 mode.
|
||||||
|
|
||||||
|
\param phy Pointer to the wireless module providing PhysicalLayer communication.
|
||||||
|
*/
|
||||||
|
explicit FSK4Client(PhysicalLayer* phy);
|
||||||
|
|
||||||
|
#if !defined(RADIOLIB_EXCLUDE_AFSK)
|
||||||
|
/*!
|
||||||
|
\brief Constructor for AFSK mode.
|
||||||
|
|
||||||
|
\param audio Pointer to the AFSK instance providing audio.
|
||||||
|
*/
|
||||||
|
//explicit FSK4Client(AFSKClient* audio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// basic methods
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Initialization method.
|
||||||
|
|
||||||
|
\param base Base (space) frequency to be used in MHz (in FSK-4 mode), or the space tone frequency in Hz (in AFSK mode)
|
||||||
|
|
||||||
|
\param shift Frequency shift between each tone in Hz.
|
||||||
|
|
||||||
|
\param rate Baud rate to be used during transmission.
|
||||||
|
|
||||||
|
|
||||||
|
\returns \ref status_codes
|
||||||
|
*/
|
||||||
|
int16_t begin(float base, uint32_t shift, uint16_t rate);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Send out idle condition (RF tone at mark frequency).
|
||||||
|
*/
|
||||||
|
void idle();
|
||||||
|
|
||||||
|
size_t write(uint8_t* buff, size_t len);
|
||||||
|
size_t write(uint8_t b);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RADIOLIB_GODMODE
|
||||||
|
private:
|
||||||
|
#endif
|
||||||
|
PhysicalLayer* _phy;
|
||||||
|
#if !defined(RADIOLIB_EXCLUDE_AFSK)
|
||||||
|
AFSKClient* _audio;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t _base = 0, _baseHz = 0;
|
||||||
|
uint32_t _shift = 0, _shiftHz = 0;
|
||||||
|
uint32_t _bitDuration = 0;
|
||||||
|
uint32_t _tones[4];
|
||||||
|
uint32_t _tonesHz[4];
|
||||||
|
|
||||||
|
void tone(uint8_t i);
|
||||||
|
|
||||||
|
int16_t transmitDirect(uint32_t freq = 0, uint32_t freqHz = 0);
|
||||||
|
int16_t standby();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Loading…
Add table
Reference in a new issue