Remove the OscOffset parameter.

c4fmdemod
Jonathan Naylor 2017-03-07 20:41:54 +00:00
parent a9b761d1dc
commit df1210eaea
16 changed files with 61 additions and 227 deletions

View File

@ -49,8 +49,7 @@ m_modState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(240U), // 200ms
m_count(0U)
m_txDelay(240U) // 200ms
{
::memset(m_modState, 0x00U, 70U * sizeof(q15_t));
@ -112,8 +111,8 @@ uint8_t CDMRDMOTX::writeData(const uint8_t* data, uint8_t length)
void CDMRDMOTX::writeByte(uint8_t c)
{
q15_t inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
const uint8_t MASK = 0xC0U;
@ -135,27 +134,9 @@ void CDMRDMOTX::writeByte(uint8_t c)
}
}
uint16_t blockSize = DMR_RADIO_SYMBOL_LENGTH * 4U;
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, DMR_RADIO_SYMBOL_LENGTH * 4U);
// Handle the case of the oscillator not being accurate enough
if (m_sampleCount > 0U) {
m_count += DMR_RADIO_SYMBOL_LENGTH * 4U;
if (m_count >= m_sampleCount) {
if (m_sampleInsert) {
inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U] = inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U - 1U];
blockSize++;
} else {
blockSize--;
}
m_count -= m_sampleCount;
}
}
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, blockSize);
io.write(STATE_DMR, outBuffer, blockSize);
io.write(STATE_DMR, outBuffer, DMR_RADIO_SYMBOL_LENGTH * 4U);
}
uint8_t CDMRDMOTX::getSpace() const

View File

@ -45,7 +45,6 @@ private:
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
uint32_t m_count;
void writeByte(uint8_t c);
};

View File

@ -76,7 +76,6 @@ m_markBuffer(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_count(0U),
m_frameCount(0U),
m_abort()
{
@ -234,8 +233,6 @@ void CDMRTX::setStart(bool start)
{
m_state = start ? DMRTXSTATE_SLOT1 : DMRTXSTATE_IDLE;
m_count = 0U;
m_frameCount = 0U;
m_abort[0U] = false;
@ -245,14 +242,12 @@ void CDMRTX::setStart(bool start)
void CDMRTX::setCal(bool start)
{
m_state = start ? DMRTXSTATE_CAL : DMRTXSTATE_IDLE;
m_count = 0U;
}
void CDMRTX::writeByte(uint8_t c, uint8_t control)
{
q15_t inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
q15_t outBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
const uint8_t MASK = 0xC0U;
@ -274,36 +269,13 @@ void CDMRTX::writeByte(uint8_t c, uint8_t control)
}
}
uint16_t blockSize = DMR_RADIO_SYMBOL_LENGTH * 4U;
uint8_t controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U + 1U];
uint8_t controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U];
::memset(controlBuffer, MARK_NONE, DMR_RADIO_SYMBOL_LENGTH * 4U * sizeof(uint8_t));
controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 2U] = control;
// Handle the case of the oscillator not being accurate enough
if (m_sampleCount > 0U) {
m_count += DMR_RADIO_SYMBOL_LENGTH * 4U;
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, DMR_RADIO_SYMBOL_LENGTH * 4U);
if (m_count >= m_sampleCount) {
if (m_sampleInsert) {
inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U] = inBuffer[DMR_RADIO_SYMBOL_LENGTH * 4U - 1U];
for (int8_t i = DMR_RADIO_SYMBOL_LENGTH * 4U - 1; i >= 0; i--)
controlBuffer[i + 1] = controlBuffer[i];
blockSize++;
} else {
controlBuffer[DMR_RADIO_SYMBOL_LENGTH * 2U - 1U] = control;
for (uint8_t i = 0U; i < (DMR_RADIO_SYMBOL_LENGTH * 4U - 1U); i++)
controlBuffer[i] = controlBuffer[i + 1U];
blockSize--;
}
m_count -= m_sampleCount;
}
}
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, blockSize);
io.write(STATE_DMR, outBuffer, blockSize, controlBuffer);
io.write(STATE_DMR, outBuffer, DMR_RADIO_SYMBOL_LENGTH * 4U, controlBuffer);
}
uint8_t CDMRTX::getSpace1() const

View File

@ -67,7 +67,6 @@ private:
uint8_t m_poBuffer[40U];
uint16_t m_poLen;
uint16_t m_poPtr;
uint32_t m_count;
uint32_t m_frameCount;
bool m_abort[2U];

View File

@ -195,8 +195,7 @@ m_modState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(60U), // 100ms
m_count(0U)
m_txDelay(60U) // 100ms
{
::memset(m_modState, 0x00U, 60U * sizeof(q15_t));
@ -214,8 +213,6 @@ void CDStarTX::process()
if (type == DSTAR_HEADER && m_poLen == 0U) {
if (!m_tx) {
m_count = 0U;
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = BIT_SYNC;
} else {
@ -241,9 +238,6 @@ void CDStarTX::process()
}
if (type == DSTAR_DATA && m_poLen == 0U) {
if (!m_tx)
m_count = 0U;
// Pop the type byte off
m_buffer.get();
@ -417,8 +411,8 @@ void CDStarTX::txHeader(const uint8_t* in, uint8_t* out) const
void CDStarTX::writeByte(uint8_t c)
{
q15_t inBuffer[DSTAR_RADIO_BIT_LENGTH * 8U + 1U];
q15_t outBuffer[DSTAR_RADIO_BIT_LENGTH * 8U + 1U];
q15_t inBuffer[DSTAR_RADIO_BIT_LENGTH * 8U];
q15_t outBuffer[DSTAR_RADIO_BIT_LENGTH * 8U];
uint8_t mask = 0x01U;
@ -432,27 +426,9 @@ void CDStarTX::writeByte(uint8_t c)
mask <<= 1;
}
uint16_t blockSize = DSTAR_RADIO_BIT_LENGTH * 8U;
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, DSTAR_RADIO_BIT_LENGTH * 8U);
// Handle the case of the oscillator not being accurate enough
if (m_sampleCount > 0U) {
m_count += DSTAR_RADIO_BIT_LENGTH * 8U;
if (m_count >= m_sampleCount) {
if (m_sampleInsert) {
inBuffer[DSTAR_RADIO_BIT_LENGTH * 8U] = inBuffer[DSTAR_RADIO_BIT_LENGTH * 8U - 1U];
blockSize++;
} else {
blockSize--;
}
m_count -= m_sampleCount;
}
}
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, blockSize);
io.write(STATE_DSTAR, outBuffer, blockSize);
io.write(STATE_DSTAR, outBuffer, DSTAR_RADIO_BIT_LENGTH * 8U);
}
void CDStarTX::setTXDelay(uint8_t delay)

View File

@ -45,7 +45,6 @@ private:
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay; // In bytes
uint32_t m_count;
void txHeader(const uint8_t* in, uint8_t* out) const;
void writeByte(uint8_t c);

View File

@ -90,9 +90,6 @@ extern bool m_duplex;
extern bool m_tx;
extern bool m_dcd;
extern uint32_t m_sampleCount;
extern bool m_sampleInsert;
extern CSerialPort serial;
extern CIO io;

89
IO.cpp
View File

@ -70,7 +70,6 @@ m_ledValue(true),
m_detect(false),
m_adcOverflow(0U),
m_dacOverflow(0U),
m_count(0U),
m_watchdog(0U),
m_lockout(false)
{
@ -100,7 +99,6 @@ void CIO::start()
startInt();
m_count = 0U;
m_started = true;
setMode();
@ -147,11 +145,9 @@ void CIO::process()
}
if (m_rxBuffer.getData() >= RX_BLOCK_SIZE) {
q15_t samples[RX_BLOCK_SIZE + 1U];
uint8_t control[RX_BLOCK_SIZE + 1U];
uint16_t rssi[RX_BLOCK_SIZE + 1U];
uint8_t blockSize = RX_BLOCK_SIZE;
q15_t samples[RX_BLOCK_SIZE];
uint8_t control[RX_BLOCK_SIZE];
uint16_t rssi[RX_BLOCK_SIZE];
for (uint16_t i = 0U; i < RX_BLOCK_SIZE; i++) {
uint16_t sample;
@ -167,102 +163,81 @@ void CIO::process()
samples[i] = q15_t(__SSAT((res2 >> 15), 16));
}
// Handle the case of the oscillator not being accurate enough
if (m_sampleCount > 0U) {
m_count += RX_BLOCK_SIZE;
if (m_count >= m_sampleCount) {
if (m_sampleInsert) {
blockSize++;
samples[RX_BLOCK_SIZE] = 0;
for (int8_t i = RX_BLOCK_SIZE - 1; i >= 0; i--)
control[i + 1] = control[i];
} else {
blockSize--;
for (uint8_t i = 0U; i < (RX_BLOCK_SIZE - 1U); i++)
control[i] = control[i + 1U];
}
m_count -= m_sampleCount;
}
}
if (m_lockout)
return;
if (m_modemState == STATE_IDLE) {
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
q15_t GMSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE);
dstarRX.samples(GMSKVals, rssi, blockSize);
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
if (m_p25Enable) {
q15_t P25Vals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, blockSize);
q15_t P25Vals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE);
p25RX.samples(P25Vals, rssi, blockSize);
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
if (m_dmrEnable || m_ysfEnable) {
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
q15_t C4FSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
if (m_dmrEnable) {
if (m_duplex)
dmrIdleRX.samples(C4FSKVals, blockSize);
dmrIdleRX.samples(C4FSKVals, RX_BLOCK_SIZE);
else
dmrDMORX.samples(C4FSKVals, rssi, blockSize);
dmrDMORX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
}
if (m_ysfEnable)
ysfRX.samples(C4FSKVals, rssi, blockSize);
ysfRX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DSTAR) {
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
q15_t GMSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE);
dstarRX.samples(GMSKVals, rssi, blockSize);
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DMR) {
if (m_dmrEnable) {
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
q15_t C4FSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
if (m_duplex) {
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
if (m_tx)
dmrRX.samples(C4FSKVals, rssi, control, blockSize);
dmrRX.samples(C4FSKVals, rssi, control, RX_BLOCK_SIZE);
else
dmrIdleRX.samples(C4FSKVals, blockSize);
dmrIdleRX.samples(C4FSKVals, RX_BLOCK_SIZE);
} else {
dmrDMORX.samples(C4FSKVals, rssi, blockSize);
dmrDMORX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
}
}
} else if (m_modemState == STATE_YSF) {
if (m_ysfEnable) {
q15_t C4FSKVals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize);
q15_t C4FSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
ysfRX.samples(C4FSKVals, rssi, blockSize);
ysfRX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_P25) {
if (m_p25Enable) {
q15_t P25Vals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, blockSize);
q15_t P25Vals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE);
p25RX.samples(P25Vals, rssi, blockSize);
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DSTARCAL) {
q15_t GMSKVals[RX_BLOCK_SIZE + 1U];
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize);
q15_t GMSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE);
calDStarRX.samples(GMSKVals, blockSize);
calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE);
} else if (m_modemState == STATE_RSSICAL) {
calRSSI.samples(rssi, blockSize);
calRSSI.samples(rssi, RX_BLOCK_SIZE);
}
}
}

2
IO.h
View File

@ -83,8 +83,6 @@ private:
uint16_t m_adcOverflow;
uint16_t m_dacOverflow;
uint32_t m_count;
volatile uint32_t m_watchdog;
bool m_lockout;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Mathis Schmieder DB9MAT
* Copyright (C) 2016 by Colin Durbridge G4EML
*
@ -36,9 +36,6 @@ bool m_duplex = true;
bool m_tx = false;
bool m_dcd = false;
uint32_t m_sampleCount = 0U;
bool m_sampleInsert = false;
CDStarRX dstarRX;
CDStarTX dstarTX;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
@ -33,9 +33,6 @@ bool m_duplex = true;
bool m_tx = false;
bool m_dcd = false;
uint32_t m_sampleCount = 0U;
bool m_sampleInsert = false;
CDStarRX dstarRX;
CDStarTX dstarTX;

View File

@ -60,8 +60,7 @@ m_lpState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(240U), // 200ms
m_count(0U)
m_txDelay(240U) // 200ms
{
::memset(m_modState, 0x00U, 70U * sizeof(q15_t));
::memset(m_lpState, 0x00U, 70U * sizeof(q15_t));
@ -82,8 +81,6 @@ void CP25TX::process()
if (m_poLen == 0U) {
if (!m_tx) {
m_count = 0U;
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = P25_START_SYNC;
} else {
@ -133,9 +130,9 @@ uint8_t CP25TX::writeData(const uint8_t* data, uint8_t length)
void CP25TX::writeByte(uint8_t c)
{
q15_t inBuffer[P25_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t intBuffer[P25_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t outBuffer[P25_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t inBuffer[P25_RADIO_SYMBOL_LENGTH * 4U];
q15_t intBuffer[P25_RADIO_SYMBOL_LENGTH * 4U];
q15_t outBuffer[P25_RADIO_SYMBOL_LENGTH * 4U];
const uint8_t MASK = 0xC0U;
@ -157,29 +154,11 @@ void CP25TX::writeByte(uint8_t c)
}
}
uint16_t blockSize = P25_RADIO_SYMBOL_LENGTH * 4U;
::arm_fir_fast_q15(&m_modFilter, inBuffer, intBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
// Handle the case of the oscillator not being accurate enough
if (m_sampleCount > 0U) {
m_count += P25_RADIO_SYMBOL_LENGTH * 4U;
::arm_fir_fast_q15(&m_lpFilter, intBuffer, outBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
if (m_count >= m_sampleCount) {
if (m_sampleInsert) {
inBuffer[P25_RADIO_SYMBOL_LENGTH * 4U] = inBuffer[P25_RADIO_SYMBOL_LENGTH * 4U - 1U];
blockSize++;
} else {
blockSize--;
}
m_count -= m_sampleCount;
}
}
::arm_fir_fast_q15(&m_modFilter, inBuffer, intBuffer, blockSize);
::arm_fir_fast_q15(&m_lpFilter, intBuffer, outBuffer, blockSize);
io.write(STATE_P25, outBuffer, blockSize);
io.write(STATE_P25, outBuffer, P25_RADIO_SYMBOL_LENGTH * 4U);
}
void CP25TX::setTXDelay(uint8_t delay)

View File

@ -45,7 +45,6 @@ private:
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
uint32_t m_count;
void writeByte(uint8_t c);
};

View File

@ -248,18 +248,6 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
uint8_t dmrDelay = data[7U];
int8_t oscOffset = int8_t(data[8U]) - 128;
if (oscOffset < 0) {
m_sampleCount = 1000000U / uint32_t(-oscOffset);
m_sampleInsert = false;
} else if (oscOffset > 0) {
m_sampleCount = 1000000U / uint32_t(oscOffset);
m_sampleInsert = true;
} else {
m_sampleCount = 0U;
m_sampleInsert = false;
}
uint8_t cwIdTXLevel = data[5U];
uint8_t dstarTXLevel = data[9U];
uint8_t dmrTXLevel = data[10U];

View File

@ -52,8 +52,7 @@ m_modState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(240U), // 200ms
m_count(0U)
m_txDelay(240U) // 200ms
{
::memset(m_modState, 0x00U, 70U * sizeof(q15_t));
@ -69,8 +68,6 @@ void CYSFTX::process()
if (m_poLen == 0U) {
if (!m_tx) {
m_count = 0U;
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = YSF_START_SYNC;
} else {
@ -118,8 +115,8 @@ uint8_t CYSFTX::writeData(const uint8_t* data, uint8_t length)
void CYSFTX::writeByte(uint8_t c)
{
q15_t inBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t outBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U + 1U];
q15_t inBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U];
q15_t outBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U];
const uint8_t MASK = 0xC0U;
@ -141,27 +138,9 @@ void CYSFTX::writeByte(uint8_t c)
}
}
uint16_t blockSize = YSF_RADIO_SYMBOL_LENGTH * 4U;
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, YSF_RADIO_SYMBOL_LENGTH * 4U);
// Handle the case of the oscillator not being accurate enough
if (m_sampleCount > 0U) {
m_count += YSF_RADIO_SYMBOL_LENGTH * 4U;
if (m_count >= m_sampleCount) {
if (m_sampleInsert) {
inBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U] = inBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U - 1U];
blockSize++;
} else {
blockSize--;
}
m_count -= m_sampleCount;
}
}
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, blockSize);
io.write(STATE_YSF, outBuffer, blockSize);
io.write(STATE_YSF, outBuffer, YSF_RADIO_SYMBOL_LENGTH * 4U);
}
void CYSFTX::setTXDelay(uint8_t delay)

View File

@ -43,7 +43,6 @@ private:
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
uint32_t m_count;
void writeByte(uint8_t c);
};