diff --git a/CalDMR.cpp b/CalDMR.cpp new file mode 100644 index 0000000..5622c1d --- /dev/null +++ b/CalDMR.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2016 by Colin Durbridge G4EML + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "Config.h" +#include "Globals.h" +#include "CalDMR.h" + + +CCalDMR::CCalDMR() : +m_transmit(false) +{ +} + +void CCalDMR::process() +{ + if (m_transmit) { + dmrTX.setCal(true); + dmrTX.process(); + } else { + dmrTX.setCal(false); + } +} + +uint8_t CCalDMR::write(const uint8_t* data, uint8_t length) +{ + if (length != 1U) + return 4U; + + m_transmit = data[0U] == 1U; + + return 0U; +} + diff --git a/CalDMR.h b/CalDMR.h new file mode 100644 index 0000000..c3231c5 --- /dev/null +++ b/CalDMR.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2009-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2016 by Colin Durbridge G4EML + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if !defined(CALDMR_H) +#define CALDMR_H + +#include "Config.h" +#include "DMRDefines.h" + +class CCalDMR { +public: + CCalDMR(); + + void process(); + + uint8_t write(const uint8_t* data, uint8_t length); + +private: + bool m_transmit; +}; + +#endif + diff --git a/CalRX.cpp b/CalDStarRX.cpp similarity index 93% rename from CalRX.cpp rename to CalDStarRX.cpp index c37f191..32b6345 100644 --- a/CalRX.cpp +++ b/CalDStarRX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,7 @@ #include "Config.h" #include "Globals.h" -#include "CalRX.h" +#include "CalDStarRX.h" #include "Utils.h" const unsigned int BUFFER_LENGTH = 200U; @@ -33,7 +33,7 @@ const uint32_t DATA_SYNC_DATA2 = 0x00554B97U; const uint32_t DATA_SYNC_MASK = 0x00FFFFFFU; const uint8_t DATA_SYNC_ERRS = 2U; -CCalRX::CCalRX() : +CCalDStarRX::CCalDStarRX() : m_pll(0U), m_prev(false), m_patternBuffer(0x00U), @@ -42,7 +42,7 @@ m_ptr(0U) { } -void CCalRX::samples(const q15_t* samples, uint8_t length) +void CCalDStarRX::samples(const q15_t* samples, uint8_t length) { for (uint16_t i = 0U; i < length; i++) { bool bit = samples[i] < 0; @@ -65,7 +65,7 @@ void CCalRX::samples(const q15_t* samples, uint8_t length) } } -void CCalRX::process(q15_t value) +void CCalDStarRX::process(q15_t value) { m_patternBuffer <<= 1; if (value < 0) diff --git a/CalRX.h b/CalDStarRX.h similarity index 87% rename from CalRX.h rename to CalDStarRX.h index cc1ba67..9b2c067 100644 --- a/CalRX.h +++ b/CalDStarRX.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,15 +16,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined(CALRX_H) -#define CALRX_H +#if !defined(CALDSTARRX_H) +#define CALDSTARRX_H #include "Config.h" #include "DStarDefines.h" -class CCalRX { +class CCalDStarRX { public: - CCalRX(); + CCalDStarRX(); void samples(const q15_t* samples, uint8_t length); diff --git a/CalTX.cpp b/CalDStarTX.cpp similarity index 97% rename from CalTX.cpp rename to CalDStarTX.cpp index 4534d1e..1c1a3a4 100644 --- a/CalTX.cpp +++ b/CalDStarTX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2015 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,7 @@ #include "Config.h" #include "Globals.h" -#include "CalTX.h" +#include "CalDStarTX.h" const uint8_t HEADER[] = {0x00U, 0x00U, 0x00U, 'D', 'I', 'R', 'E', 'C', 'T', ' ', ' ', 'D', 'I', 'R', 'E', 'C', 'T', ' ', ' ', @@ -28,13 +28,13 @@ const uint8_t HEADER[] = {0x00U, 0x00U, 0x00U, 'D', 'I', 'R', 'E', 'C', 'T', ' ' const uint8_t SLOW_DATA_TEXT[] = {'M', 'M', 'D', 'V', 'M', ' ', 'M', 'o', 'd', 'e', 'm', ' ', 'T', 'e', 's', 't', ' ', ' ', ' ', ' '}; -CCalTX::CCalTX() : +CCalDStarTX::CCalDStarTX() : m_transmit(false), m_count(0U) { } -void CCalTX::process() +void CCalDStarTX::process() { dstarTX.process(); @@ -162,7 +162,7 @@ void CCalTX::process() m_count = (m_count + 1U) % (30U * 21U); } -uint8_t CCalTX::write(const uint8_t* data, uint8_t length) +uint8_t CCalDStarTX::write(const uint8_t* data, uint8_t length) { if (length != 1U) return 4U; diff --git a/CalTX.h b/CalDStarTX.h similarity index 86% rename from CalTX.h rename to CalDStarTX.h index cd6a374..c411317 100644 --- a/CalTX.h +++ b/CalDStarTX.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,15 +16,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if !defined(CALTX_H) -#define CALTX_H +#if !defined(CALDSTARTX_H) +#define CALDSTARTX_H #include "Config.h" #include "DStarDefines.h" -class CCalTX { +class CCalDStarTX { public: - CCalTX(); + CCalDStarTX(); uint8_t write(const uint8_t* data, uint8_t length); diff --git a/DMRTX.cpp b/DMRTX.cpp index 380d390..031d15e 100644 --- a/DMRTX.cpp +++ b/DMRTX.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2009-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2016 by Colin Durbridge G4EML * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -97,7 +98,11 @@ void CDMRTX::process() createData(1U); m_state = DMRTXSTATE_CACH1; break; - + + case DMRTXSTATE_CAL: + createCal(); + break; + default: createCACH(0U, 1U); m_state = DMRTXSTATE_SLOT1; @@ -193,6 +198,13 @@ void CDMRTX::setStart(bool start) m_count = 0U; } +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]; @@ -279,6 +291,17 @@ void CDMRTX::createData(uint8_t slotIndex) m_poPtr = 0U; } +void CDMRTX::createCal() +{ + for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) { + m_poBuffer[i] = 0x5FU; // +3, +3, -3, -3 pattern for deviation cal. + m_markBuffer[i] = MARK_NONE; + } + + m_poLen = DMR_FRAME_LENGTH_BYTES; + m_poPtr = 0U; +} + void CDMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex) { if (m_cachPtr >= 12U) diff --git a/DMRTX.h b/DMRTX.h index 7fc499d..2db5f3f 100644 --- a/DMRTX.h +++ b/DMRTX.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2016 by Colin Durbridge G4EML * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +30,8 @@ enum DMRTXSTATE { DMRTXSTATE_SLOT1, DMRTXSTATE_CACH1, DMRTXSTATE_SLOT2, - DMRTXSTATE_CACH2 + DMRTXSTATE_CACH2, + DMRTXSTATE_CAL }; class CDMRTX { @@ -41,6 +43,7 @@ public: uint8_t writeShortLC(const uint8_t* data, uint8_t length); void setStart(bool start); + void setCal(bool start); void process(); @@ -66,6 +69,7 @@ private: void createData(uint8_t slotIndex); void createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex); + void createCal(); void writeByte(uint8_t c, uint8_t control); }; diff --git a/Globals.h b/Globals.h index d64a64f..0e7116f 100644 --- a/Globals.h +++ b/Globals.h @@ -39,7 +39,8 @@ enum MMDVM_STATE { STATE_DSTAR = 1, STATE_DMR = 2, STATE_YSF = 3, - STATE_CALIBRATE = 99 + STATE_DMRCAL = 98, + STATE_DSTARCAL = 99 }; #include "SerialPort.h" @@ -50,8 +51,9 @@ enum MMDVM_STATE { #include "DMRTX.h" #include "YSFRX.h" #include "YSFTX.h" -#include "CalRX.h" -#include "CalTX.h" +#include "CalDStarRX.h" +#include "CalDStarTX.h" +#include "CalDMR.h" #include "Debug.h" #include "IO.h" @@ -70,7 +72,7 @@ extern bool m_ysfEnable; extern bool m_tx; extern uint32_t m_sampleCount; -extern bool m_sampleInsert; +extern bool m_sampleInsert; extern CSerialPort serial; extern CIO io; @@ -85,8 +87,9 @@ extern CDMRTX dmrTX; extern CYSFRX ysfRX; extern CYSFTX ysfTX; -extern CCalRX calRX; -extern CCalTX calTX; +extern CCalDStarRX calDStarRX; +extern CCalDStarTX calDStarTX; +extern CCalDMR calDMR; #endif diff --git a/IO.cpp b/IO.cpp index 1f60ad5..1c9bac7 100644 --- a/IO.cpp +++ b/IO.cpp @@ -361,11 +361,11 @@ void CIO::process() ysfRX.samples(C4FSKVals, blockSize); } - } else if (m_modemState == STATE_CALIBRATE) { + } else if (m_modemState == STATE_DSTARCAL) { q15_t GMSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize); - calRX.samples(GMSKVals, blockSize); + calDStarRX.samples(GMSKVals, blockSize); } } } diff --git a/MMDVM.cpp b/MMDVM.cpp index 734b20e..1f14e88 100644 --- a/MMDVM.cpp +++ b/MMDVM.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX * Copyright (C) 2016 by Mathis Schmieder DB9MAT + * Copyright (C) 2016 by Colin Durbridge G4EML * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,8 +45,9 @@ CDMRTX dmrTX; CYSFRX ysfRX; CYSFTX ysfTX; -CCalRX calRX; -CCalTX calTX; +CCalDStarRX calDStarRX; +CCalDStarTX calDStarTX; +CCalDMR calDMR; CSerialPort serial; CIO io; @@ -71,8 +73,11 @@ void loop() if (m_ysfEnable && m_modemState == STATE_YSF) ysfTX.process(); - if (m_modemState == STATE_CALIBRATE) - calTX.process(); + if (m_modemState == STATE_DSTARCAL) + calDStarTX.process(); + + if (m_modemState == STATE_DMRCAL) + calDMR.process(); } int main() diff --git a/MMDVM.ino b/MMDVM.ino index d9c2041..f84c25f 100644 --- a/MMDVM.ino +++ b/MMDVM.ino @@ -1,5 +1,6 @@ /* * Copyright (C) 2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2016 by Colin Durbridge G4EML * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,8 +42,9 @@ CDMRTX dmrTX; CYSFRX ysfRX; CYSFTX ysfTX; -CCalRX calRX; -CCalTX calTX; +CCalDStarRX calDStarRX; +CCalDStarTX calDStarTX; +CCalDMR calDMR; CSerialPort serial; CIO io; @@ -68,7 +70,10 @@ void loop() if (m_ysfEnable && m_modemState == STATE_YSF) ysfTX.process(); - if (m_modemState == STATE_CALIBRATE) - calTX.process(); + if (m_modemState == STATE_DSTARCAL) + calDStarTX.process(); + + if (m_modemState == STATE_DMRCAL) + calDMR.process(); } diff --git a/SerialPort.cpp b/SerialPort.cpp index c4adc3f..e8bc328 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2013,2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2016 by Colin Durbridge G4EML * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,7 +58,7 @@ const uint8_t MMDVM_DEBUG3 = 0xF3U; const uint8_t MMDVM_DEBUG4 = 0xF4U; const uint8_t MMDVM_DEBUG5 = 0xF5U; -const uint8_t HARDWARE[] = "MMDVM 20160412 24kHz (D-Star/DMR/System Fusion)"; +const uint8_t HARDWARE[] = "MMDVM 20160413 24kHz (D-Star/DMR/System Fusion)"; const uint8_t PROTOCOL_VERSION = 1U; @@ -191,7 +192,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length) MMDVM_STATE modemState = MMDVM_STATE(data[3U]); - if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_CALIBRATE) + if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL) return 4U; if (modemState == STATE_DSTAR && !dstarEnable) return 4U; @@ -252,7 +253,7 @@ uint8_t CSerialPort::setMode(const uint8_t* data, uint8_t length) if (modemState == m_modemState) return 0U; - if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_CALIBRATE) + if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL) return 4U; if (modemState == STATE_DSTAR && !m_dstarEnable) return 4U; @@ -286,8 +287,15 @@ void CSerialPort::setMode(MMDVM_STATE modemState) dmrRX.reset(); dstarRX.reset(); break; - case STATE_CALIBRATE: - DEBUG1("Mode set to Calibrate"); + case STATE_DSTARCAL: + DEBUG1("Mode set to D-Star Calibrate"); + dmrIdleRX.reset(); + dmrRX.reset(); + dstarRX.reset(); + ysfRX.reset(); + break; + case STATE_DMRCAL: + DEBUG1("Mode set to DMR Calibrate"); dmrIdleRX.reset(); dmrRX.reset(); dstarRX.reset(); @@ -375,8 +383,10 @@ void CSerialPort::process() break; case MMDVM_CAL_DATA: - if (m_modemState == STATE_CALIBRATE) - err = calTX.write(m_buffer + 3U, m_len - 3U); + if (m_modemState == STATE_DSTARCAL) + err = calDStarTX.write(m_buffer + 3U, m_len - 3U); + if (m_modemState == STATE_DMRCAL) + err = calDMR.write(m_buffer + 3U, m_len - 3U); if (err == 0U) { sendACK(); } else { @@ -673,7 +683,7 @@ void CSerialPort::writeYSFLost() void CSerialPort::writeCalData(const uint8_t* data, uint8_t length) { - if (m_modemState != STATE_CALIBRATE) + if (m_modemState != STATE_DSTARCAL) return; uint8_t reply[130U];