diff --git a/Config.h b/Config.h index 04056ea..5d7fc5f 100644 --- a/Config.h +++ b/Config.h @@ -69,4 +69,8 @@ // To reduce CPU load, you can remove the DC blocker by commenting out the next line // #define USE_DCBLOCKER +// Constant Service LED once repeater is running +// Do not use if employing an external hardware watchdog +// #define CONSTANT_SRV_LED + #endif diff --git a/DMRDMOTX.cpp b/DMRDMOTX.cpp index 9e10c0a..87f851d 100644 --- a/DMRDMOTX.cpp +++ b/DMRDMOTX.cpp @@ -44,6 +44,13 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02 #define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7]) #define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7]) +// PR FILL pattern +const uint8_t PR_FILL[] = + {0x63U, 0xEAU, 0x00U, 0x76U, 0x6CU, 0x76U, 0xC4U, 0x52U, 0xC8U, 0x78U, + 0x09U, 0x2DU, 0xB8U, 0x79U, 0x27U, 0x57U, 0x9BU, 0x31U, 0xBCU, 0x3EU, + 0xEAU, 0x45U, 0xC3U, 0x30U, 0x49U, 0x17U, 0x93U, 0xAEU, 0x8BU, 0x6DU, + 0xA4U, 0xA5U, 0xADU, 0xA2U, 0xF1U, 0x35U, 0xB5U, 0x3CU, 0x1EU}; + const uint8_t DMR_SYNC = 0x5FU; CDMRDMOTX::CDMRDMOTX() : @@ -72,11 +79,11 @@ void CDMRDMOTX::process() m_poLen = m_txDelay; } else { - for (unsigned int i = 0U; i < 72U; i++) - m_poBuffer[i] = DMR_SYNC; - for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) - m_poBuffer[i + 39U] = m_fifo.get(); + m_poBuffer[i] = m_fifo.get(); + + for (unsigned int i = 0U; i < 39U; i++) + m_poBuffer[i + DMR_FRAME_LENGTH_BYTES] = PR_FILL[i]; m_poLen = 72U; } diff --git a/IO.cpp b/IO.cpp index ba5922e..6301cde 100644 --- a/IO.cpp +++ b/IO.cpp @@ -260,11 +260,15 @@ void CIO::process() m_watchdog = 0U; } - if (m_ledCount >= 48000U) { +#if defined(CONSTANT_SRV_LED) + setLEDInt(true); +#else + if (m_ledCount >= 24000U) { m_ledCount = 0U; m_ledValue = !m_ledValue; setLEDInt(m_ledValue); } +#endif } else { if (m_ledCount >= 480000U) { m_ledCount = 0U; diff --git a/MMDVM_STM32F4xx.coproj b/MMDVM_STM32F4xx.coproj index b5562eb..b502368 100644 --- a/MMDVM_STM32F4xx.coproj +++ b/MMDVM_STM32F4xx.coproj @@ -275,8 +275,8 @@ - + @@ -284,15 +284,15 @@ - + - + @@ -340,8 +340,8 @@ - + diff --git a/SerialPort.cpp b/SerialPort.cpp index d3ccfb6..aa342bb 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -233,7 +233,7 @@ void CSerialPort::getVersion() uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length) { - if (length < 16U) + if (length < 17U) return 4U; bool rxInvert = (data[0U] & 0x01U) == 0x01U; @@ -288,6 +288,8 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length) uint8_t nxdnTXLevel = data[15U]; + uint8_t ysfTXHang = data[16U]; + m_modemState = modemState; m_dstarEnable = dstarEnable; @@ -309,7 +311,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length) dmrDMORX.setColorCode(colorCode); dmrIdleRX.setColorCode(colorCode); - ysfTX.setLoDev(ysfLoDev); + ysfTX.setParams(ysfLoDev, ysfTXHang); io.setParameters(rxInvert, txInvert, pttInvert, rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, txDCOffset, rxDCOffset); diff --git a/SerialRB.h b/SerialRB.h index 4378cc9..7b6b7b9 100644 --- a/SerialRB.h +++ b/SerialRB.h @@ -32,7 +32,7 @@ Boston, MA 02110-1301, USA. #include #endif -const uint16_t SERIAL_RINGBUFFER_SIZE = 2000U; +const uint16_t SERIAL_RINGBUFFER_SIZE = 370U; class CSerialRB { public: diff --git a/YSFTX.cpp b/YSFTX.cpp index 2cb3a5e..bfd5462 100644 --- a/YSFTX.cpp +++ b/YSFTX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2017 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2018 by Jonathan Naylor G4KLX * Copyright (C) 2017 by Andy Uribe CA6JAU * * This program is free software; you can redistribute it and/or modify @@ -47,6 +47,7 @@ const q15_t YSF_LEVELD_LO = -948; const uint8_t YSF_START_SYNC = 0x77U; const uint8_t YSF_END_SYNC = 0xFFU; +const uint8_t YSF_HANG = 0x00U; CYSFTX::CYSFTX() : m_buffer(4000U), @@ -56,7 +57,9 @@ m_poBuffer(), m_poLen(0U), m_poPtr(0U), m_txDelay(240U), // 200ms -m_loDev(false) +m_loDev(false), +m_txHang(4800U), // 4s +m_txCount(0U) { ::memset(m_modState, 0x00U, 16U * sizeof(q15_t)); @@ -66,12 +69,14 @@ m_loDev(false) m_modFilter.pState = m_modState; } + void CYSFTX::process() { - if (m_buffer.getData() == 0U && m_poLen == 0U) + if (m_buffer.getData() == 0U && m_poLen == 0U && m_txCount == 0U) return; - if (m_poLen == 0U) { + // If we have YSF data to transmit, do so. + if (m_poLen == 0U && m_buffer.getData() > 0U) { if (!m_tx) { for (uint16_t i = 0U; i < m_txDelay; i++) m_poBuffer[m_poLen++] = YSF_START_SYNC; @@ -86,20 +91,37 @@ void CYSFTX::process() } if (m_poLen > 0U) { + // Transmit YSF data. uint16_t space = io.getSpace(); - + while (space > (4U * YSF_RADIO_SYMBOL_LENGTH)) { uint8_t c = m_poBuffer[m_poPtr++]; writeByte(c); + // Reduce space and reset the hang timer. space -= 4U * YSF_RADIO_SYMBOL_LENGTH; - + if (m_duplex) + m_txCount = m_txHang; + if (m_poPtr >= m_poLen) { m_poPtr = 0U; m_poLen = 0U; return; } } + } else if (m_txCount > 0U) { + // Transmit silence until the hang timer has expired. + uint16_t space = io.getSpace(); + + while (space > (4U * YSF_RADIO_SYMBOL_LENGTH)) { + writeSilence(); + + space -= 4U * YSF_RADIO_SYMBOL_LENGTH; + m_txCount--; + + if (m_txCount == 0U) + return; + } } } @@ -147,6 +169,16 @@ void CYSFTX::writeByte(uint8_t c) io.write(STATE_YSF, outBuffer, YSF_RADIO_SYMBOL_LENGTH * 4U); } +void CYSFTX::writeSilence() +{ + q15_t inBuffer[4U] = {0x00U, 0x00U, 0x00U, 0x00U}; + q15_t outBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U]; + + ::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 4U); + + io.write(STATE_YSF, outBuffer, YSF_RADIO_SYMBOL_LENGTH * 4U); +} + void CYSFTX::setTXDelay(uint8_t delay) { m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay @@ -160,8 +192,9 @@ uint8_t CYSFTX::getSpace() const return m_buffer.getSpace() / YSF_FRAME_LENGTH_BYTES; } -void CYSFTX::setLoDev(bool on) +void CYSFTX::setParams(bool on, uint8_t txHang) { - m_loDev = on; + m_loDev = on; + m_txHang = txHang * 1200U; } diff --git a/YSFTX.h b/YSFTX.h index 01211a5..647767c 100644 --- a/YSFTX.h +++ b/YSFTX.h @@ -35,7 +35,7 @@ public: uint8_t getSpace() const; - void setLoDev(bool on); + void setParams(bool on, uint8_t txHang); private: CSerialRB m_buffer; @@ -46,8 +46,11 @@ private: uint16_t m_poPtr; uint16_t m_txDelay; bool m_loDev; + uint32_t m_txHang; + uint32_t m_txCount; void writeByte(uint8_t c); + void writeSilence(); }; #endif