mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-11-18 14:15:07 -05:00
LoRa: optimize non LoRa modes. Improve preamble detection. GUI updates
This commit is contained in:
parent
bedf682ef2
commit
22a668394e
@ -239,7 +239,7 @@ void ChirpChatDemodGUI::on_clear_clicked(bool checked)
|
|||||||
{
|
{
|
||||||
(void) checked;
|
(void) checked;
|
||||||
ui->messageText->clear();
|
ui->messageText->clear();
|
||||||
ui->hexText->clear();
|
ui->messageText->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChirpChatDemodGUI::on_eomSquelch_valueChanged(int value)
|
void ChirpChatDemodGUI::on_eomSquelch_valueChanged(int value)
|
||||||
@ -410,8 +410,7 @@ ChirpChatDemodGUI::ChirpChatDemodGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUI
|
|||||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||||
|
|
||||||
ui->messageText->setReadOnly(true);
|
ui->messageText->setReadOnly(true);
|
||||||
ui->syncWord->setReadOnly(true);
|
ui->messageText->setReadOnly(true);
|
||||||
ui->hexText->setReadOnly(true);
|
|
||||||
|
|
||||||
m_channelMarker.setMovable(true);
|
m_channelMarker.setMovable(true);
|
||||||
m_channelMarker.setVisible(true);
|
m_channelMarker.setVisible(true);
|
||||||
@ -602,7 +601,6 @@ void ChirpChatDemodGUI::showLoRaMessage(const Message& message)
|
|||||||
QByteArray bytes = msg.getBytes();
|
QByteArray bytes = msg.getBytes();
|
||||||
QString syncWordStr((tr("%1").arg(msg.getSyncWord(), 2, 16, QChar('0'))));
|
QString syncWordStr((tr("%1").arg(msg.getSyncWord(), 2, 16, QChar('0'))));
|
||||||
|
|
||||||
ui->syncWord->setText(tr("%1").arg(syncWordStr));
|
|
||||||
ui->sText->setText(tr("%1").arg(msg.getSingalDb(), 0, 'f', 1));
|
ui->sText->setText(tr("%1").arg(msg.getSingalDb(), 0, 'f', 1));
|
||||||
ui->snrText->setText(tr("%1").arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1));
|
ui->snrText->setText(tr("%1").arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1));
|
||||||
unsigned int packetLength;
|
unsigned int packetLength;
|
||||||
@ -650,7 +648,8 @@ void ChirpChatDemodGUI::showLoRaMessage(const Message& message)
|
|||||||
.arg(getParityStr(msg.getPayloadParityStatus()))
|
.arg(getParityStr(msg.getPayloadParityStatus()))
|
||||||
.arg(msg.getPayloadCRCStatus() ? "ok" : "err");
|
.arg(msg.getPayloadCRCStatus() ? "ok" : "err");
|
||||||
|
|
||||||
displayBytes(loRaHeader, bytes);
|
displayStatus(loRaHeader);
|
||||||
|
displayBytes(bytes);
|
||||||
|
|
||||||
QByteArray bytesCopy(bytes);
|
QByteArray bytesCopy(bytes);
|
||||||
bytesCopy.truncate(packetLength);
|
bytesCopy.truncate(packetLength);
|
||||||
@ -658,7 +657,7 @@ void ChirpChatDemodGUI::showLoRaMessage(const Message& message)
|
|||||||
QString str = QString(bytesCopy.toStdString().c_str());
|
QString str = QString(bytesCopy.toStdString().c_str());
|
||||||
QString textHeader(tr("%1 (%2)").arg(dateStr).arg(syncWordStr));
|
QString textHeader(tr("%1 (%2)").arg(dateStr).arg(syncWordStr));
|
||||||
|
|
||||||
displayText(textHeader, str);
|
displayText(str);
|
||||||
displayLoRaStatus(msg.getHeaderParityStatus(), msg.getHeaderCRCStatus(), msg.getPayloadParityStatus(), msg.getPayloadCRCStatus());
|
displayLoRaStatus(msg.getHeaderParityStatus(), msg.getHeaderCRCStatus(), msg.getPayloadParityStatus(), msg.getPayloadCRCStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -672,10 +671,6 @@ void ChirpChatDemodGUI::showTextMessage(const Message& message)
|
|||||||
|
|
||||||
QDateTime dt = QDateTime::currentDateTime();
|
QDateTime dt = QDateTime::currentDateTime();
|
||||||
QString dateStr = dt.toString("HH:mm:ss");
|
QString dateStr = dt.toString("HH:mm:ss");
|
||||||
QString syncWordStr((tr("%1").arg(msg.getSyncWord(), 2, 16, QChar('0'))));
|
|
||||||
QString textHeader(tr("%1 (%2)").arg(dateStr).arg(syncWordStr));
|
|
||||||
displayText(textHeader, msg.getString());
|
|
||||||
ui->syncWord->setText(syncWordStr);
|
|
||||||
ui->sText->setText(tr("%1").arg(msg.getSingalDb(), 0, 'f', 1));
|
ui->sText->setText(tr("%1").arg(msg.getSingalDb(), 0, 'f', 1));
|
||||||
ui->snrText->setText(tr("%1").arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1));
|
ui->snrText->setText(tr("%1").arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1));
|
||||||
|
|
||||||
@ -683,30 +678,31 @@ void ChirpChatDemodGUI::showTextMessage(const Message& message)
|
|||||||
.arg(dateStr)
|
.arg(dateStr)
|
||||||
.arg(msg.getSingalDb(), 0, 'f', 1)
|
.arg(msg.getSingalDb(), 0, 'f', 1)
|
||||||
.arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1);
|
.arg(msg.getSingalDb() - msg.getNoiseDb(), 0, 'f', 1);
|
||||||
|
|
||||||
displayStatus(status);
|
displayStatus(status);
|
||||||
|
displayText(msg.getString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChirpChatDemodGUI::displayText(const QString& header, const QString& text)
|
void ChirpChatDemodGUI::displayText(const QString& text)
|
||||||
{
|
{
|
||||||
QTextCursor cursor = ui->messageText->textCursor();
|
QTextCursor cursor = ui->messageText->textCursor();
|
||||||
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
||||||
if (!ui->messageText->document()->isEmpty()) {
|
if (!ui->messageText->document()->isEmpty()) {
|
||||||
cursor.insertText("\n");
|
cursor.insertText("\n");
|
||||||
}
|
}
|
||||||
cursor.insertText(tr("%1 %2").arg(header).arg(text));
|
cursor.insertText(tr("TXT|%1").arg(text));
|
||||||
ui->messageText->verticalScrollBar()->setValue(ui->messageText->verticalScrollBar()->maximum());
|
ui->messageText->verticalScrollBar()->setValue(ui->messageText->verticalScrollBar()->maximum());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChirpChatDemodGUI::displayBytes(const QString& header, const QByteArray& bytes)
|
void ChirpChatDemodGUI::displayBytes(const QByteArray& bytes)
|
||||||
{
|
{
|
||||||
QTextCursor cursor = ui->hexText->textCursor();
|
QTextCursor cursor = ui->messageText->textCursor();
|
||||||
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
||||||
|
|
||||||
if (!ui->hexText->document()->isEmpty()) {
|
if (!ui->messageText->document()->isEmpty()) {
|
||||||
cursor.insertText("\n");
|
cursor.insertText("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.insertText(tr(">%1\n").arg(header));
|
|
||||||
QByteArray::const_iterator it = bytes.begin();
|
QByteArray::const_iterator it = bytes.begin();
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
@ -729,20 +725,20 @@ void ChirpChatDemodGUI::displayBytes(const QString& header, const QByteArray& by
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->hexText->verticalScrollBar()->setValue(ui->hexText->verticalScrollBar()->maximum());
|
ui->messageText->verticalScrollBar()->setValue(ui->messageText->verticalScrollBar()->maximum());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChirpChatDemodGUI::displayStatus(const QString& status)
|
void ChirpChatDemodGUI::displayStatus(const QString& status)
|
||||||
{
|
{
|
||||||
QTextCursor cursor = ui->hexText->textCursor();
|
QTextCursor cursor = ui->messageText->textCursor();
|
||||||
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
||||||
|
|
||||||
if (!ui->hexText->document()->isEmpty()) {
|
if (!ui->messageText->document()->isEmpty()) {
|
||||||
cursor.insertText("\n");
|
cursor.insertText("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.insertText(tr(">%1").arg(status));
|
cursor.insertText(tr(">%1").arg(status));
|
||||||
ui->hexText->verticalScrollBar()->setValue(ui->hexText->verticalScrollBar()->maximum());
|
ui->messageText->verticalScrollBar()->setValue(ui->messageText->verticalScrollBar()->maximum());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ChirpChatDemodGUI::getParityStr(int parityStatus)
|
QString ChirpChatDemodGUI::getParityStr(int parityStatus)
|
||||||
|
|||||||
@ -112,8 +112,8 @@ private:
|
|||||||
void setBandwidths();
|
void setBandwidths();
|
||||||
void showLoRaMessage(const Message& message);
|
void showLoRaMessage(const Message& message);
|
||||||
void showTextMessage(const Message& message); //!< For TTY and ASCII
|
void showTextMessage(const Message& message); //!< For TTY and ASCII
|
||||||
void displayText(const QString& header, const QString& text);
|
void displayText(const QString& text);
|
||||||
void displayBytes(const QString& header, const QByteArray& bytes);
|
void displayBytes(const QByteArray& bytes);
|
||||||
void displayStatus(const QString& status);
|
void displayStatus(const QString& status);
|
||||||
void displayLoRaStatus(int headerParityStatus, bool headerCRCStatus, int payloadParityStatus, bool payloadCRCStatus);
|
void displayLoRaStatus(int headerParityStatus, bool headerCRCStatus, int payloadParityStatus, bool payloadCRCStatus);
|
||||||
QString getParityStr(int parityStatus);
|
QString getParityStr(int parityStatus);
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>552</width>
|
<width>532</width>
|
||||||
<height>680</height>
|
<height>680</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -562,28 +562,20 @@
|
|||||||
<string>Msg</string>
|
<string>Msg</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="hexLabel">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>2</x>
|
|
||||||
<y>145</y>
|
|
||||||
<width>32</width>
|
|
||||||
<height>16</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Hex</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QPlainTextEdit" name="messageText">
|
<widget class="QPlainTextEdit" name="messageText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>30</x>
|
<x>30</x>
|
||||||
<y>60</y>
|
<y>60</y>
|
||||||
<width>490</width>
|
<width>490</width>
|
||||||
<height>80</height>
|
<height>161</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Liberation Mono</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="schemeLabel">
|
<widget class="QLabel" name="schemeLabel">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
@ -784,28 +776,6 @@
|
|||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLineEdit" name="syncWord">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>492</x>
|
|
||||||
<y>10</y>
|
|
||||||
<width>25</width>
|
|
||||||
<height>20</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::ClickFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Sync word (1 byte hex)</string>
|
|
||||||
</property>
|
|
||||||
<property name="inputMask">
|
|
||||||
<string>HH</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>00</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" name="loraLabel">
|
<widget class="QLabel" name="loraLabel">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
@ -902,22 +872,6 @@
|
|||||||
<string>FEC</string>
|
<string>FEC</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QPlainTextEdit" name="hexText">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>30</x>
|
|
||||||
<y>145</y>
|
|
||||||
<width>490</width>
|
|
||||||
<height>75</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>Liberation Mono</family>
|
|
||||||
<pointsize>9</pointsize>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" name="packetLengthLabel">
|
<widget class="QLabel" name="packetLengthLabel">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
@ -969,19 +923,6 @@
|
|||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="syncWordLabel">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>456</x>
|
|
||||||
<y>10</y>
|
|
||||||
<width>30</width>
|
|
||||||
<height>19</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Sync</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLabel" name="headerHammingStatus">
|
<widget class="QLabel" name="headerHammingStatus">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
|
|||||||
@ -202,3 +202,19 @@ bool ChirpChatDemodSettings::deserialize(const QByteArray& data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ChirpChatDemodSettings::getNbSFDFourths() const
|
||||||
|
{
|
||||||
|
switch (m_codingScheme)
|
||||||
|
{
|
||||||
|
case CodingLoRa:
|
||||||
|
return 9;
|
||||||
|
default:
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChirpChatDemodSettings::hasSyncWord() const
|
||||||
|
{
|
||||||
|
return m_codingScheme == CodingLoRa;
|
||||||
|
}
|
||||||
@ -72,6 +72,8 @@ struct ChirpChatDemodSettings
|
|||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||||
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
|
void setSpectrumGUI(Serializable *spectrumGUI) { m_spectrumGUI = spectrumGUI; }
|
||||||
|
unsigned int getNbSFDFourths() const; //!< Get the number of SFD period fourths (depends on coding scheme)
|
||||||
|
bool hasSyncWord() const; //!< Only LoRa has a syncword (for the moment)
|
||||||
QByteArray serialize() const;
|
QByteArray serialize() const;
|
||||||
bool deserialize(const QByteArray& data);
|
bool deserialize(const QByteArray& data);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -82,9 +82,12 @@ void ChirpChatDemodSink::initSF(unsigned int sf, unsigned int deBits)
|
|||||||
|
|
||||||
m_nbSymbols = 1 << sf;
|
m_nbSymbols = 1 << sf;
|
||||||
m_nbSymbolsEff = 1 << (sf - deBits);
|
m_nbSymbolsEff = 1 << (sf - deBits);
|
||||||
|
m_deLength = 1 << deBits;
|
||||||
m_fftLength = m_nbSymbols;
|
m_fftLength = m_nbSymbols;
|
||||||
m_fft->configure(m_fftInterpolation*m_fftLength, false);
|
m_interpolatedFFTLength = m_fftInterpolation*m_fftLength;
|
||||||
m_fftSFD->configure(m_fftInterpolation*m_fftLength, false);
|
m_preambleTolerance = (m_deLength*m_fftInterpolation)/2;
|
||||||
|
m_fft->configure(m_interpolatedFFTLength, false);
|
||||||
|
m_fftSFD->configure(m_interpolatedFFTLength, false);
|
||||||
m_state = ChirpChatStateReset;
|
m_state = ChirpChatStateReset;
|
||||||
m_sfdSkip = m_fftLength / 4;
|
m_sfdSkip = m_fftLength / 4;
|
||||||
m_fftWindow.create(FFTWindow::Function::Kaiser, m_fftLength);
|
m_fftWindow.create(FFTWindow::Function::Kaiser, m_fftLength);
|
||||||
@ -146,7 +149,7 @@ void ChirpChatDemodSink::processSample(const Complex& ci)
|
|||||||
if (m_fftCounter == m_fftLength)
|
if (m_fftCounter == m_fftLength)
|
||||||
{
|
{
|
||||||
m_fftWindow.apply(m_fft->in());
|
m_fftWindow.apply(m_fft->in());
|
||||||
std::fill(m_fft->in()+m_fftLength, m_fft->in()+m_fftInterpolation*m_fftLength, Complex{0.0, 0.0});
|
std::fill(m_fft->in()+m_fftLength, m_fft->in()+m_interpolatedFFTLength, Complex{0.0, 0.0});
|
||||||
m_fft->transform();
|
m_fft->transform();
|
||||||
m_fftCounter = 0;
|
m_fftCounter = 0;
|
||||||
double magsq, magsqTotal;
|
double magsq, magsqTotal;
|
||||||
@ -176,11 +179,20 @@ void ChirpChatDemodSink::processSample(const Complex& ci)
|
|||||||
|
|
||||||
for (int i = 1; i < m_requiredPreambleChirps; i++)
|
for (int i = 1; i < m_requiredPreambleChirps; i++)
|
||||||
{
|
{
|
||||||
if (m_argMaxHistory[0] != m_argMaxHistory[i])
|
int delta = m_argMaxHistory[i] - m_argMaxHistory[i-1];
|
||||||
|
// qDebug("ChirpChatDemodSink::processSample: search: delta: %d / %d", delta, m_deLength);
|
||||||
|
|
||||||
|
if ((delta < -m_preambleTolerance) || (delta > m_preambleTolerance))
|
||||||
{
|
{
|
||||||
preambleFound = false;
|
preambleFound = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (m_argMaxHistory[0] != m_argMaxHistory[i])
|
||||||
|
// {
|
||||||
|
// preambleFound = false;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((preambleFound) && (magsq > 1e-9))
|
if ((preambleFound) && (magsq > 1e-9))
|
||||||
@ -227,11 +239,11 @@ void ChirpChatDemodSink::processSample(const Complex& ci)
|
|||||||
if (m_fftCounter == m_fftLength)
|
if (m_fftCounter == m_fftLength)
|
||||||
{
|
{
|
||||||
m_fftWindow.apply(m_fft->in());
|
m_fftWindow.apply(m_fft->in());
|
||||||
std::fill(m_fft->in()+m_fftLength, m_fft->in()+m_fftInterpolation*m_fftLength, Complex{0.0, 0.0});
|
std::fill(m_fft->in()+m_fftLength, m_fft->in()+m_interpolatedFFTLength, Complex{0.0, 0.0});
|
||||||
m_fft->transform();
|
m_fft->transform();
|
||||||
|
|
||||||
m_fftWindow.apply(m_fftSFD->in());
|
m_fftWindow.apply(m_fftSFD->in());
|
||||||
std::fill(m_fftSFD->in()+m_fftLength, m_fftSFD->in()+m_fftInterpolation*m_fftLength, Complex{0.0, 0.0});
|
std::fill(m_fftSFD->in()+m_fftLength, m_fftSFD->in()+m_interpolatedFFTLength, Complex{0.0, 0.0});
|
||||||
m_fftSFD->transform();
|
m_fftSFD->transform();
|
||||||
|
|
||||||
m_fftCounter = 0;
|
m_fftCounter = 0;
|
||||||
@ -265,23 +277,30 @@ void ChirpChatDemodSink::processSample(const Complex& ci)
|
|||||||
{
|
{
|
||||||
m_magsqTotalAvg(magsqSFDTotal);
|
m_magsqTotalAvg(magsqSFDTotal);
|
||||||
|
|
||||||
if (m_chirpCount < 3) // too early
|
if (m_chirpCount < 1 + (m_settings.hasSyncWord() ? 2 : 0)) // too early
|
||||||
{
|
{
|
||||||
m_state = ChirpChatStateReset;
|
m_state = ChirpChatStateReset;
|
||||||
qDebug("ChirpChatDemodSink::processSample: SFD search: signal drop is too early");
|
qDebug("ChirpChatDemodSink::processSample: SFD search: signal drop is too early");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_syncWord = round(m_preambleHistory[m_chirpCount-2] / 8.0);
|
if (m_settings.hasSyncWord())
|
||||||
m_syncWord += 16 * round(m_preambleHistory[m_chirpCount-3] / 8.0);
|
{
|
||||||
qDebug("ChirpChatDemodSink::processSample: SFD found: up: %4u|%11.6f - down: %4u|%11.6f sync: %x", imax, magsq, imaxSFD, magsqSFD, m_syncWord);
|
m_syncWord = round(m_preambleHistory[m_chirpCount-2] / 8.0);
|
||||||
|
m_syncWord += 16 * round(m_preambleHistory[m_chirpCount-3] / 8.0);
|
||||||
|
qDebug("ChirpChatDemodSink::processSample: SFD found: up: %4u|%11.6f - down: %4u|%11.6f sync: %x", imax, magsq, imaxSFD, magsqSFD, m_syncWord);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug("ChirpChatDemodSink::processSample: SFD found: up: %4u|%11.6f - down: %4u|%11.6f", imax, magsq, imaxSFD, magsqSFD);
|
||||||
|
}
|
||||||
|
|
||||||
int sadj = 0;
|
int sadj = 0;
|
||||||
int nadj = 0;
|
int nadj = 0;
|
||||||
int zadj;
|
int zadj;
|
||||||
int sfdSkip = m_sfdSkip;
|
int sfdSkip = m_sfdSkip;
|
||||||
|
|
||||||
for (int i = 0; i < m_chirpCount-3; i++)
|
for (int i = 0; i < m_chirpCount - 1 - (m_settings.hasSyncWord() ? 2 : 0); i++)
|
||||||
{
|
{
|
||||||
sadj += m_preambleHistory[i] > m_nbSymbols/2 ? m_preambleHistory[i] - m_nbSymbols : m_preambleHistory[i];
|
sadj += m_preambleHistory[i] > m_nbSymbols/2 ? m_preambleHistory[i] - m_nbSymbols : m_preambleHistory[i];
|
||||||
nadj++;
|
nadj++;
|
||||||
@ -315,7 +334,7 @@ void ChirpChatDemodSink::processSample(const Complex& ci)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_state == ChirpChatStateSkipSFD) // Just skip SFD
|
else if (m_state == ChirpChatStateSkipSFD) // Just skip the rest of SFD
|
||||||
{
|
{
|
||||||
m_fftCounter++;
|
m_fftCounter++;
|
||||||
|
|
||||||
@ -324,13 +343,12 @@ void ChirpChatDemodSink::processSample(const Complex& ci)
|
|||||||
m_fftCounter = m_fftLength - m_sfdSkip;
|
m_fftCounter = m_fftLength - m_sfdSkip;
|
||||||
m_sfdSkipCounter++;
|
m_sfdSkipCounter++;
|
||||||
|
|
||||||
if (m_sfdSkipCounter == m_sfdFourths) // 1.25 SFD chips left
|
if (m_sfdSkipCounter == m_settings.getNbSFDFourths() - 4U) // SFD chips fourths less one full period
|
||||||
{
|
{
|
||||||
qDebug("ChirpChatDemodSink::processSample: SFD skipped");
|
qDebug("ChirpChatDemodSink::processSample: SFD skipped");
|
||||||
m_chirp = m_chirp0;
|
m_chirp = m_chirp0;
|
||||||
m_fftCounter = 0;
|
m_fftCounter = 0;
|
||||||
m_chirpCount = 0;
|
m_chirpCount = 0;
|
||||||
int correction = 0;
|
|
||||||
m_magsqMax = 0.0;
|
m_magsqMax = 0.0;
|
||||||
m_decodeMsg = ChirpChatDemodMsg::MsgDecodeSymbols::create();
|
m_decodeMsg = ChirpChatDemodMsg::MsgDecodeSymbols::create();
|
||||||
m_decodeMsg->setSyncWord(m_syncWord);
|
m_decodeMsg->setSyncWord(m_syncWord);
|
||||||
@ -346,7 +364,7 @@ void ChirpChatDemodSink::processSample(const Complex& ci)
|
|||||||
if (m_fftCounter == m_fftLength)
|
if (m_fftCounter == m_fftLength)
|
||||||
{
|
{
|
||||||
m_fftWindow.apply(m_fft->in());
|
m_fftWindow.apply(m_fft->in());
|
||||||
std::fill(m_fft->in()+m_fftLength, m_fft->in()+m_fftInterpolation*m_fftLength, Complex{0.0, 0.0});
|
std::fill(m_fft->in()+m_fftLength, m_fft->in()+m_interpolatedFFTLength, Complex{0.0, 0.0});
|
||||||
m_fft->transform();
|
m_fft->transform();
|
||||||
m_fftCounter = 0;
|
m_fftCounter = 0;
|
||||||
double magsq, magsqTotal;
|
double magsq, magsqTotal;
|
||||||
|
|||||||
@ -77,7 +77,6 @@ private:
|
|||||||
|
|
||||||
static const unsigned int m_requiredPreambleChirps = 4; //!< Number of chirps required to estimate preamble
|
static const unsigned int m_requiredPreambleChirps = 4; //!< Number of chirps required to estimate preamble
|
||||||
static const unsigned int m_maxSFDSearchChirps = 8; //!< Maximum number of chirps when looking for SFD after preamble detection
|
static const unsigned int m_maxSFDSearchChirps = 8; //!< Maximum number of chirps when looking for SFD after preamble detection
|
||||||
static const unsigned int m_sfdFourths = 5; //!< Number of SFD chip period fourths to skip until payload
|
|
||||||
static const unsigned int m_fftInterpolation = 2; //!< FFT interpolation factor (usually a power of 2)
|
static const unsigned int m_fftInterpolation = 2; //!< FFT interpolation factor (usually a power of 2)
|
||||||
|
|
||||||
FFTEngine *m_fft;
|
FFTEngine *m_fft;
|
||||||
@ -87,7 +86,7 @@ private:
|
|||||||
Complex *m_upChirps;
|
Complex *m_upChirps;
|
||||||
Complex *m_spectrumLine;
|
Complex *m_spectrumLine;
|
||||||
unsigned int m_fftCounter;
|
unsigned int m_fftCounter;
|
||||||
unsigned int m_argMaxHistory[m_requiredPreambleChirps];
|
int m_argMaxHistory[m_requiredPreambleChirps];
|
||||||
unsigned int m_argMaxHistoryCounter;
|
unsigned int m_argMaxHistoryCounter;
|
||||||
unsigned int m_preambleHistory[m_maxSFDSearchChirps];
|
unsigned int m_preambleHistory[m_maxSFDSearchChirps];
|
||||||
unsigned int m_syncWord;
|
unsigned int m_syncWord;
|
||||||
@ -108,9 +107,12 @@ private:
|
|||||||
BasebandSampleSink* m_spectrumSink;
|
BasebandSampleSink* m_spectrumSink;
|
||||||
Complex *m_spectrumBuffer;
|
Complex *m_spectrumBuffer;
|
||||||
|
|
||||||
unsigned int m_nbSymbols;
|
unsigned int m_nbSymbols; //!< Number of symbols = length of base FFT
|
||||||
unsigned int m_nbSymbolsEff; //!< effective symbols considering DE bits
|
unsigned int m_nbSymbolsEff; //!< effective symbols considering DE bits
|
||||||
unsigned int m_fftLength;
|
unsigned int m_fftLength; //!< Length of base FFT
|
||||||
|
unsigned int m_interpolatedFFTLength; //!< Length of interpolated FFT
|
||||||
|
int m_deLength; //!< Number of FFT bins collated to represent one symbol
|
||||||
|
int m_preambleTolerance; //!< Number of FFT bins to collate when looking for preamble
|
||||||
|
|
||||||
void processSample(const Complex& ci);
|
void processSample(const Complex& ci);
|
||||||
void initSF(unsigned int sf, unsigned int deBits); //!< Init tables, FFTs, depending on spread factor
|
void initSF(unsigned int sf, unsigned int deBits); //!< Init tables, FFTs, depending on spread factor
|
||||||
|
|||||||
@ -109,7 +109,10 @@ bool ChirpChatModGUI::handleMessage(const Message& message)
|
|||||||
{
|
{
|
||||||
const ChirpChatMod::MsgReportPayloadTime& rpt = (ChirpChatMod::MsgReportPayloadTime&) message;
|
const ChirpChatMod::MsgReportPayloadTime& rpt = (ChirpChatMod::MsgReportPayloadTime&) message;
|
||||||
float fourthsMs = ((1<<m_settings.m_spreadFactor) * 250.0) / ChirpChatModSettings::bandwidths[m_settings.m_bandwidthIndex];
|
float fourthsMs = ((1<<m_settings.m_spreadFactor) * 250.0) / ChirpChatModSettings::bandwidths[m_settings.m_bandwidthIndex];
|
||||||
float controlMs = (4*m_settings.m_preambleChirps + 8 + 9) * fourthsMs; // preamble + sync word + SFD
|
int fourthsChirps = 4*m_settings.m_preambleChirps;
|
||||||
|
fourthsChirps += m_settings.hasSyncWord() ? 8 : 0;
|
||||||
|
fourthsChirps += m_settings.getNbSFDFourths();
|
||||||
|
float controlMs = fourthsChirps * fourthsMs; // preamble + sync word + SFD
|
||||||
ui->timePayloadText->setText(tr("%1 ms").arg(QString::number(rpt.getPayloadTimeMs(), 'f', 0)));
|
ui->timePayloadText->setText(tr("%1 ms").arg(QString::number(rpt.getPayloadTimeMs(), 'f', 0)));
|
||||||
ui->timeTotalText->setText(tr("%1 ms").arg(QString::number(rpt.getPayloadTimeMs() + controlMs, 'f', 0)));
|
ui->timeTotalText->setText(tr("%1 ms").arg(QString::number(rpt.getPayloadTimeMs() + controlMs, 'f', 0)));
|
||||||
ui->timeSymbolText->setText(tr("%1 ms").arg(QString::number(4.0*fourthsMs, 'f', 1)));
|
ui->timeSymbolText->setText(tr("%1 ms").arg(QString::number(4.0*fourthsMs, 'f', 1)));
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>392</width>
|
<width>402</width>
|
||||||
<height>373</height>
|
<height>373</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>1</x>
|
<x>1</x>
|
||||||
<y>20</y>
|
<y>20</y>
|
||||||
<width>390</width>
|
<width>400</width>
|
||||||
<height>125</height>
|
<height>125</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -74,7 +74,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>40</x>
|
||||||
<y>50</y>
|
<y>50</y>
|
||||||
<width>251</width>
|
<width>261</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -102,7 +102,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>40</x>
|
||||||
<y>70</y>
|
<y>70</y>
|
||||||
<width>81</width>
|
<width>101</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -131,7 +131,7 @@
|
|||||||
<widget class="QLabel" name="spreadText">
|
<widget class="QLabel" name="spreadText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>130</x>
|
<x>150</x>
|
||||||
<y>70</y>
|
<y>70</y>
|
||||||
<width>30</width>
|
<width>30</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -153,7 +153,7 @@
|
|||||||
<widget class="QLabel" name="bwText">
|
<widget class="QLabel" name="bwText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>300</x>
|
<x>310</x>
|
||||||
<y>50</y>
|
<y>50</y>
|
||||||
<width>80</width>
|
<width>80</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -175,7 +175,7 @@
|
|||||||
<widget class="QLabel" name="deBitsLabel">
|
<widget class="QLabel" name="deBitsLabel">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>180</x>
|
<x>200</x>
|
||||||
<y>70</y>
|
<y>70</y>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -188,7 +188,7 @@
|
|||||||
<widget class="QLabel" name="deBitsText">
|
<widget class="QLabel" name="deBitsText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>280</x>
|
<x>370</x>
|
||||||
<y>70</y>
|
<y>70</y>
|
||||||
<width>10</width>
|
<width>10</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -210,9 +210,9 @@
|
|||||||
<widget class="QSlider" name="deBits">
|
<widget class="QSlider" name="deBits">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>210</x>
|
<x>240</x>
|
||||||
<y>70</y>
|
<y>70</y>
|
||||||
<width>61</width>
|
<width>91</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -243,7 +243,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>371</width>
|
<width>381</width>
|
||||||
<height>26</height>
|
<height>26</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -366,7 +366,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>40</x>
|
||||||
<y>90</y>
|
<y>90</y>
|
||||||
<width>81</width>
|
<width>101</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -408,7 +408,7 @@
|
|||||||
<widget class="QLabel" name="preambleChirpsText">
|
<widget class="QLabel" name="preambleChirpsText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>130</x>
|
<x>150</x>
|
||||||
<y>90</y>
|
<y>90</y>
|
||||||
<width>30</width>
|
<width>30</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -430,7 +430,7 @@
|
|||||||
<widget class="QLabel" name="idleTimeLabel">
|
<widget class="QLabel" name="idleTimeLabel">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>180</x>
|
<x>200</x>
|
||||||
<y>90</y>
|
<y>90</y>
|
||||||
<width>32</width>
|
<width>32</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -443,9 +443,9 @@
|
|||||||
<widget class="QSlider" name="idleTime">
|
<widget class="QSlider" name="idleTime">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>220</x>
|
<x>240</x>
|
||||||
<y>90</y>
|
<y>90</y>
|
||||||
<width>81</width>
|
<width>91</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -474,7 +474,7 @@
|
|||||||
<widget class="QLabel" name="idleTimeText">
|
<widget class="QLabel" name="idleTimeText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>320</x>
|
<x>350</x>
|
||||||
<y>90</y>
|
<y>90</y>
|
||||||
<width>30</width>
|
<width>30</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -493,48 +493,13 @@
|
|||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="syncLabel">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>310</x>
|
|
||||||
<y>70</y>
|
|
||||||
<width>32</width>
|
|
||||||
<height>16</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Sync</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QLineEdit" name="syncWord">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>350</x>
|
|
||||||
<y>68</y>
|
|
||||||
<width>30</width>
|
|
||||||
<height>20</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="focusPolicy">
|
|
||||||
<enum>Qt::ClickFocus</enum>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Sync word (1 byte hex)</string>
|
|
||||||
</property>
|
|
||||||
<property name="inputMask">
|
|
||||||
<string>HH</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>00</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="messageContainer" native="true">
|
<widget class="QWidget" name="messageContainer" native="true">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>1</x>
|
<x>1</x>
|
||||||
<y>150</y>
|
<y>150</y>
|
||||||
<width>390</width>
|
<width>400</width>
|
||||||
<height>221</height>
|
<height>221</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -807,7 +772,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>40</x>
|
||||||
<y>110</y>
|
<y>110</y>
|
||||||
<width>341</width>
|
<width>355</width>
|
||||||
<height>60</height>
|
<height>60</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -830,7 +795,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>40</x>
|
||||||
<y>175</y>
|
<y>175</y>
|
||||||
<width>341</width>
|
<width>355</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -964,7 +929,7 @@
|
|||||||
<widget class="QLabel" name="timeTotalLabel">
|
<widget class="QLabel" name="timeTotalLabel">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>290</x>
|
<x>300</x>
|
||||||
<y>200</y>
|
<y>200</y>
|
||||||
<width>25</width>
|
<width>25</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -980,7 +945,7 @@
|
|||||||
<widget class="QLabel" name="timeTotalText">
|
<widget class="QLabel" name="timeTotalText">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>320</x>
|
<x>330</x>
|
||||||
<y>200</y>
|
<y>200</y>
|
||||||
<width>60</width>
|
<width>60</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -1037,7 +1002,7 @@
|
|||||||
<widget class="QCheckBox" name="header">
|
<widget class="QCheckBox" name="header">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>290</x>
|
<x>285</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>50</width>
|
<width>50</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -1053,7 +1018,7 @@
|
|||||||
<widget class="QCheckBox" name="crc">
|
<widget class="QCheckBox" name="crc">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>230</x>
|
<x>226</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>50</width>
|
<width>50</width>
|
||||||
<height>16</height>
|
<height>16</height>
|
||||||
@ -1168,6 +1133,41 @@
|
|||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="syncWord">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>377</x>
|
||||||
|
<y>8</y>
|
||||||
|
<width>22</width>
|
||||||
|
<height>20</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::ClickFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Sync word (1 byte hex)</string>
|
||||||
|
</property>
|
||||||
|
<property name="inputMask">
|
||||||
|
<string>HH</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>00</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="syncLabel">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>342</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>32</width>
|
||||||
|
<height>16</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Sync</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|||||||
@ -122,6 +122,22 @@ void ChirpChatModSettings::generateMessages()
|
|||||||
.arg(m_urCall).arg(m_myCall).arg(m_textMessage);
|
.arg(m_urCall).arg(m_myCall).arg(m_textMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ChirpChatModSettings::getNbSFDFourths() const
|
||||||
|
{
|
||||||
|
switch (m_codingScheme)
|
||||||
|
{
|
||||||
|
case CodingLoRa:
|
||||||
|
return 9;
|
||||||
|
default:
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChirpChatModSettings::hasSyncWord() const
|
||||||
|
{
|
||||||
|
return m_codingScheme == CodingLoRa;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray ChirpChatModSettings::serialize() const
|
QByteArray ChirpChatModSettings::serialize() const
|
||||||
{
|
{
|
||||||
SimpleSerializer s(1);
|
SimpleSerializer s(1);
|
||||||
|
|||||||
@ -96,6 +96,8 @@ struct ChirpChatModSettings
|
|||||||
void resetToDefaults();
|
void resetToDefaults();
|
||||||
void setDefaultTemplates();
|
void setDefaultTemplates();
|
||||||
void generateMessages();
|
void generateMessages();
|
||||||
|
unsigned int getNbSFDFourths() const; //!< Get the number of SFD period fourths (depends on coding scheme)
|
||||||
|
bool hasSyncWord() const; //!< Only LoRa has a syncword (for the moment)
|
||||||
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
void setChannelMarker(Serializable *channelMarker) { m_channelMarker = channelMarker; }
|
||||||
QByteArray serialize() const;
|
QByteArray serialize() const;
|
||||||
bool deserialize(const QByteArray& data);
|
bool deserialize(const QByteArray& data);
|
||||||
|
|||||||
@ -233,10 +233,20 @@ void ChirpChatModSource::modulateSample()
|
|||||||
if (m_chirpCount == m_settings.m_preambleChirps)
|
if (m_chirpCount == m_settings.m_preambleChirps)
|
||||||
{
|
{
|
||||||
m_chirpCount = 0;
|
m_chirpCount = 0;
|
||||||
m_chirp0 = ((m_settings.m_syncWord >> ((1-m_chirpCount)*4)) & 0xf)*8;
|
|
||||||
m_chirp = (m_chirp0 + m_fftLength)*ChirpChatModSettings::oversampling - 1;
|
if (m_settings.hasSyncWord())
|
||||||
m_fftCounter = 0;
|
{
|
||||||
m_state = ChirpChatStateSyncWord;
|
m_chirp0 = ((m_settings.m_syncWord >> ((1-m_chirpCount)*4)) & 0xf)*8;
|
||||||
|
m_chirp = (m_chirp0 + m_fftLength)*ChirpChatModSettings::oversampling - 1;
|
||||||
|
m_state = ChirpChatStateSyncWord;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sampleCounter = 0;
|
||||||
|
m_chirp0 = 0;
|
||||||
|
m_chirp = m_fftLength*ChirpChatModSettings::oversampling - 1;
|
||||||
|
m_state = ChirpChatStateSFD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,7 +296,7 @@ void ChirpChatModSource::modulateSample()
|
|||||||
m_sampleCounter = 0;
|
m_sampleCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_chirpCount == 9)
|
if (m_chirpCount == m_settings.getNbSFDFourths())
|
||||||
{
|
{
|
||||||
m_fftCounter = 0;
|
m_fftCounter = 0;
|
||||||
m_chirpCount = 0;
|
m_chirpCount = 0;
|
||||||
|
|||||||
@ -82,7 +82,7 @@ In practice it is difficult on the Rx side to make correct decodes if only one F
|
|||||||
|
|
||||||
<h3>7: Sync word</h3>
|
<h3>7: Sync word</h3>
|
||||||
|
|
||||||
This is the sync word (byte) to transmit entered as a 2 nibble hexadecimal number.
|
This is a LoRa specific feature and is the sync word (byte) to transmit entered as a 2 nibble hexadecimal number.
|
||||||
|
|
||||||
<h3>8: Number of preamble chirps</h3>
|
<h3>8: Number of preamble chirps</h3>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user