mirror of https://github.com/markqvist/MMDVM.git
Add DMR calibration.
parent
8bfff17ace
commit
51f26b1330
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
|
@ -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);
|
||||
|
|
@ -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;
|
|
@ -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);
|
||||
|
25
DMRTX.cpp
25
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)
|
||||
|
|
6
DMRTX.h
6
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);
|
||||
};
|
||||
|
||||
|
|
15
Globals.h
15
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
|
||||
|
||||
|
|
4
IO.cpp
4
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
MMDVM.cpp
13
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()
|
||||
|
|
13
MMDVM.ino
13
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue