RadioLib/src/protocols/RTTY/RTTY.cpp

128 wiersze
2.8 KiB
C++
Czysty Zwykły widok Historia

2018-08-20 18:42:14 +00:00
#include "RTTY.h"
2023-04-30 09:34:58 +00:00
2023-04-30 09:37:38 +00:00
#include <math.h>
2020-06-30 08:45:52 +00:00
#if !defined(RADIOLIB_EXCLUDE_RTTY)
2018-08-20 18:42:14 +00:00
RTTYClient::RTTYClient(PhysicalLayer* phy) {
phyLayer = phy;
2023-04-29 20:54:27 +00:00
lineFeed = "\r\n";
2020-07-04 19:19:23 +00:00
#if !defined(RADIOLIB_EXCLUDE_AFSK)
audioClient = nullptr;
2020-07-04 19:19:23 +00:00
#endif
2020-04-30 15:11:09 +00:00
}
2020-06-30 08:45:52 +00:00
#if !defined(RADIOLIB_EXCLUDE_AFSK)
2020-04-30 15:11:09 +00:00
RTTYClient::RTTYClient(AFSKClient* audio) {
phyLayer = audio->phyLayer;
2023-04-29 20:54:27 +00:00
lineFeed = "\r\n";
audioClient = audio;
2018-08-20 18:42:14 +00:00
}
2020-06-30 08:45:52 +00:00
#endif
2018-08-20 18:42:14 +00:00
int16_t RTTYClient::begin(float base, uint32_t shift, uint16_t rate, uint8_t enc, uint8_t stopBits) {
2018-08-20 18:42:14 +00:00
// save configuration
2023-04-29 20:54:27 +00:00
RadioLibPrint::encoding = enc;
stopBitsNum = stopBits;
baseFreqHz = base;
shiftFreqHz = shift;
2018-08-20 18:42:14 +00:00
// calculate duration of 1 bit
bitDuration = (uint32_t)1000000/rate;
2018-12-26 10:19:30 +00:00
// calculate module carrier frequency resolution
uint32_t step = round(phyLayer->getFreqStep());
2018-12-26 10:19:30 +00:00
// check minimum shift value
if(shift < step / 2) {
2021-11-14 10:40:52 +00:00
return(RADIOLIB_ERR_INVALID_RTTY_SHIFT);
2018-12-26 10:19:30 +00:00
}
2018-12-26 10:19:30 +00:00
// round shift to multiples of frequency step size
if(shift % step < (step / 2)) {
shiftFreq = shift / step;
2018-12-26 10:19:30 +00:00
} else {
shiftFreq = (shift / step) + 1;
2018-12-26 10:19:30 +00:00
}
2018-08-20 18:42:14 +00:00
// calculate 24-bit frequency
baseFreq = (base * 1000000.0) / phyLayer->getFreqStep();
2018-08-20 18:42:14 +00:00
2021-02-13 16:43:05 +00:00
// configure for direct mode
return(phyLayer->startDirect());
2018-08-20 18:42:14 +00:00
}
2018-08-23 07:21:05 +00:00
void RTTYClient::idle() {
2018-08-20 18:42:14 +00:00
mark();
}
size_t RTTYClient::write(uint8_t b) {
2023-04-29 20:54:27 +00:00
uint8_t dataBitsNum = 0;
switch(RadioLibPrint::encoding) {
case RADIOLIB_ASCII:
dataBitsNum = 7;
break;
case RADIOLIB_ASCII_EXTENDED:
dataBitsNum = 8;
break;
case RADIOLIB_ITA2:
dataBitsNum = 5;
break;
default:
return(0);
}
2018-08-20 18:42:14 +00:00
space();
uint16_t maxDataMask = 0x01 << (dataBitsNum - 1);
2020-09-12 11:53:28 +00:00
for(uint16_t mask = 0x01; mask <= maxDataMask; mask <<= 1) {
2018-08-20 18:42:14 +00:00
if(b & mask) {
mark();
} else {
space();
}
}
for(uint8_t i = 0; i < stopBitsNum; i++) {
2018-08-20 18:42:14 +00:00
mark();
}
2018-08-20 18:42:14 +00:00
return(1);
}
void RTTYClient::mark() {
Module* mod = phyLayer->getMod();
2023-04-11 02:51:29 +00:00
uint32_t start = mod->hal->micros();
transmitDirect(baseFreq + shiftFreq, baseFreqHz + shiftFreqHz);
mod->waitForMicroseconds(start, bitDuration);
2018-08-20 18:42:14 +00:00
}
void RTTYClient::space() {
Module* mod = phyLayer->getMod();
2023-04-11 02:51:29 +00:00
uint32_t start = mod->hal->micros();
transmitDirect(baseFreq, baseFreqHz);
mod->waitForMicroseconds(start, bitDuration);
2018-08-20 18:42:14 +00:00
}
2020-04-30 15:11:09 +00:00
int16_t RTTYClient::transmitDirect(uint32_t freq, uint32_t freqHz) {
2020-07-04 19:19:23 +00:00
#if !defined(RADIOLIB_EXCLUDE_AFSK)
if(audioClient != nullptr) {
return(audioClient->tone(freqHz));
2020-04-30 15:11:09 +00:00
}
2020-07-04 19:19:23 +00:00
#endif
return(phyLayer->transmitDirect(freq));
2020-04-30 15:11:09 +00:00
}
int16_t RTTYClient::standby() {
// ensure everything is stopped in interrupt timing mode
Module* mod = phyLayer->getMod();
mod->waitForMicroseconds(0, 0);
2020-07-04 19:19:23 +00:00
#if !defined(RADIOLIB_EXCLUDE_AFSK)
if(audioClient != nullptr) {
return(audioClient->noTone());
2020-04-30 15:11:09 +00:00
}
2020-07-04 19:19:23 +00:00
#endif
return(phyLayer->standby());
2020-04-30 15:11:09 +00:00
}
2020-06-30 08:45:52 +00:00
#endif