convert documentation format to Doxygen;

pull/5/head 2024-07-03
Bryan Biedenkapp 2 years ago
parent 7840a3daf9
commit 994c348129

@ -1,20 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2020,2021 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Jim McLaughlin, KI6ZUM
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU
* * Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2020,2021 Jonathan Naylor, G4KLX * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* Copyright (C) 2016 Jim McLaughlin, KI6ZUM *
* Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU */
* Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include <math.h> #include <math.h>
#include "Globals.h" #include "Globals.h"
@ -74,9 +70,8 @@ uint8_t m_afcRange;
// Global Functions // Global Functions
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* */
///
/// </summary>
static void AD7021_IOCTL_Shift() static void AD7021_IOCTL_Shift()
{ {
for (int i = 31; i >= 0; i--) { for (int i = 31; i >= 0; i--) {
@ -95,9 +90,8 @@ static void AD7021_IOCTL_Shift()
io.SDATA(LOW); io.SDATA(LOW);
} }
/// <summary> /* */
///
/// </summary>
static void AD7021_IOCTL_SLEPulse() static void AD7021_IOCTL_SLEPulse()
{ {
io.SLE1(HIGH); io.SLE1(HIGH);
@ -105,10 +99,8 @@ static void AD7021_IOCTL_SLEPulse()
io.SLE1(LOW); io.SLE1(LOW);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="doSle"></param>
static void AD7021_1_IOCTL(bool doSle = true) static void AD7021_1_IOCTL(bool doSle = true)
{ {
AD7021_IOCTL_Shift(); AD7021_IOCTL_Shift();
@ -118,9 +110,8 @@ static void AD7021_1_IOCTL(bool doSle = true)
} }
#if defined(DUPLEX) #if defined(DUPLEX)
/// <summary> /* */
///
/// </summary>
static void AD7021_2_IOCTL_SLEPulse() static void AD7021_2_IOCTL_SLEPulse()
{ {
io.SLE2(HIGH); io.SLE2(HIGH);
@ -128,10 +119,8 @@ static void AD7021_2_IOCTL_SLEPulse()
io.SLE2(LOW); io.SLE2(LOW);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="doSle"></param>
static void AD7021_2_IOCTL(bool doSle = true) static void AD7021_2_IOCTL(bool doSle = true)
{ {
AD7021_IOCTL_Shift(); AD7021_IOCTL_Shift();
@ -145,9 +134,8 @@ static void AD7021_2_IOCTL(bool doSle = true)
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Hardware interrupt handler. */
/// Hardware interrupt handler.
/// </summary>
void IO::interrupt1() void IO::interrupt1()
{ {
uint8_t bit = 0U; uint8_t bit = 0U;
@ -256,9 +244,8 @@ void IO::interrupt1()
} }
#if defined(DUPLEX) #if defined(DUPLEX)
/// <summary> /* Hardware interrupt handler. */
/// Hardware interrupt handler.
/// </summary>
void IO::interrupt2() void IO::interrupt2()
{ {
uint8_t bit = 0U; uint8_t bit = 0U;
@ -276,11 +263,8 @@ void IO::interrupt2()
} }
#endif #endif
/// <summary> /* Sets the ADF7021 RF configuration. */
/// Sets the ADF7021 RF configuration.
/// </summary>
/// <param name="modemState"></param>
/// <param name="reset"></param>
void IO::rf1Conf(DVM_STATE modemState, bool reset) void IO::rf1Conf(DVM_STATE modemState, bool reset)
{ {
uint32_t txFrequencyTmp, rxFrequencyTmp; uint32_t txFrequencyTmp, rxFrequencyTmp;
@ -482,11 +466,8 @@ void IO::rf1Conf(DVM_STATE modemState, bool reset)
} }
#if defined(DUPLEX) #if defined(DUPLEX)
/// <summary> /* Sets the ADF7021 RF configuration. */
/// Sets the ADF7021 RF configuration.
/// </summary>
/// <param name="modemState"></param>
/// <param name="reset"></param>
void IO::rf2Conf(DVM_STATE modemState) void IO::rf2Conf(DVM_STATE modemState)
{ {
DEBUG3("IO::rf2Conf() ADF2 (Rx); modemState/rxGain", modemState, m_gainMode); DEBUG3("IO::rf2Conf() ADF2 (Rx); modemState/rxGain", modemState, m_gainMode);
@ -609,12 +590,8 @@ void IO::rf2Conf(DVM_STATE modemState)
} }
#endif // DUPLEX #endif // DUPLEX
/// <summary> /* Sets the deviation levels. */
///
/// </summary>
/// <param name="dmrTXLevel"></param>
/// <param name="p25TXLevel"></param>
/// <param name="nxdnTXLevel"></param>
void IO::setDeviations(uint8_t dmrTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel) void IO::setDeviations(uint8_t dmrTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel)
{ {
dmrDev = uint16_t((ADF7021_DEV_DMR * uint16_t(dmrTXLevel)) / 128U); dmrDev = uint16_t((ADF7021_DEV_DMR * uint16_t(dmrTXLevel)) / 128U);
@ -622,17 +599,8 @@ void IO::setDeviations(uint8_t dmrTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLev
nxdnDev = uint16_t((ADF7021_DEV_NXDN * uint16_t(nxdnTXLevel)) / 128U); nxdnDev = uint16_t((ADF7021_DEV_NXDN * uint16_t(nxdnTXLevel)) / 128U);
} }
/// <summary> /* Sets the RF adjustment parameters. */
/// Sets the RF adjustment parameters.
/// </summary>
/// <param name="dmrDevAdj"></param>
/// <param name="p25DevAdj"></param>
/// <param name="dmrDiscBWAdj"></param>
/// <param name="p25DiscBWAdj"></param>
/// <param name="nxdnDiscBWAdj"></param>
/// <param name="dmrPostBWAdj"></param>
/// <param name="p25PostBWAdj"></param>
/// <param name="nxdnPostBWAdj"></param>
void IO::setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t nxdnDiscBWAdj, int8_t dmrPostBWAdj, int8_t p25PostBWAdj, int8_t nxdnPostBWADJ) void IO::setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t nxdnDiscBWAdj, int8_t dmrPostBWAdj, int8_t p25PostBWAdj, int8_t nxdnPostBWADJ)
{ {
m_dmrDiscBWAdj = dmrDiscBWAdj; m_dmrDiscBWAdj = dmrDiscBWAdj;
@ -646,13 +614,8 @@ void IO::setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t nxdnDiscBW
DEBUG4("IO::setRFAdjust() RF adjustment, postBW", dmrPostBWAdj, p25PostBWAdj, nxdnPostBWADJ); DEBUG4("IO::setRFAdjust() RF adjustment, postBW", dmrPostBWAdj, p25PostBWAdj, nxdnPostBWADJ);
} }
/// <summary> /* Sets the RF AFC parameters. */
/// Sets the RF AFC parameters.
/// </summary>
/// <param name="afcEnable"></param>
/// <param name="afcKI"></param>
/// <param name="afcKP"></param>
/// <param name="afcRange"></param>
void IO::setAFCParams(bool afcEnable, uint8_t afcKI, uint8_t afcKP, uint8_t afcRange) void IO::setAFCParams(bool afcEnable, uint8_t afcKI, uint8_t afcKP, uint8_t afcRange)
{ {
m_afcEnable = afcEnable; m_afcEnable = afcEnable;
@ -663,9 +626,8 @@ void IO::setAFCParams(bool afcEnable, uint8_t afcKI, uint8_t afcKP, uint8_t afcR
DEBUG5("IO::setAFCParams() AFC params", afcEnable, afcKI, afcKP, afcRange); DEBUG5("IO::setAFCParams() AFC params", afcEnable, afcKI, afcKP, afcRange);
} }
/// <summary> /* */
///
/// </summary>
void IO::updateCal(DVM_STATE modemState) void IO::updateCal(DVM_STATE modemState)
{ {
uint32_t ADF7021_REG2; uint32_t ADF7021_REG2;
@ -726,10 +688,8 @@ void IO::updateCal(DVM_STATE modemState)
setRX(); setRX();
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
uint16_t IO::readRSSI() uint16_t IO::readRSSI()
{ {
uint32_t AD7021_RB; uint32_t AD7021_RB;
@ -818,9 +778,8 @@ uint16_t IO::readRSSI()
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* */
///
/// </summary>
void IO::configureBand() void IO::configureBand()
{ {
/* /*
@ -890,10 +849,8 @@ void IO::configureBand()
DEBUG3("IO::configureBand() ADF freq band; reg1/f_div", ADF7021_REG1, f_div); DEBUG3("IO::configureBand() ADF freq band; reg1/f_div", ADF7021_REG1, f_div);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="modemState"></param>
void IO::configureTxRx(DVM_STATE modemState) void IO::configureTxRx(DVM_STATE modemState)
{ {
uint16_t dmrDiscBW = ADF7021_DISC_BW_DMR, dmrPostBW = ADF7021_POST_BW_DMR; uint16_t dmrDiscBW = ADF7021_DISC_BW_DMR, dmrPostBW = ADF7021_POST_BW_DMR;
@ -1375,9 +1332,8 @@ void IO::configureTxRx(DVM_STATE modemState)
(uint16_t)((ADF7021_PFD * p25Dev) / (f_div * 65536)), (uint16_t)((ADF7021_PFD * nxdnDev) / (f_div * 65536)), m_rfPower); (uint16_t)((ADF7021_PFD * p25Dev) / (f_div * 65536)), (uint16_t)((ADF7021_PFD * nxdnDev) / (f_div * 65536)), m_rfPower);
} }
/// <summary> /* */
///
/// </summary>
void IO::setTX() void IO::setTX()
{ {
// PTT pin on (doing it earlier helps to measure timing impact) // PTT pin on (doing it earlier helps to measure timing impact)
@ -1396,10 +1352,8 @@ void IO::setTX()
while(CLK()); while(CLK());
} }
/// <summary> /* */
///
/// </summary>
/// <param name="doSle"></param>
void IO::setRX(bool doSle) void IO::setRX(bool doSle)
{ {
// PTT pin off (doing it earlier helps to measure timing impact) // PTT pin off (doing it earlier helps to measure timing impact)

@ -1,20 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2020 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Jim McLaughlin, KI6ZUM
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file ADF7021.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. */
*
* @package DVM / Hotspot Firmware
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2020 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Jim McLaughlin, KI6ZUM
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__ADF7021_H__) #if !defined(__ADF7021_H__)
#define __ADF7021_H__ #define __ADF7021_H__
@ -24,6 +24,11 @@
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @addtogroup hotspot_fw
* @{
*/
#define LOW 0 #define LOW 0
#define HIGH 1 #define HIGH 1
@ -312,4 +317,5 @@
#endif // ADF7021_N_VER #endif // ADF7021_N_VER
#endif // ENABLE_ADF7021 #endif // ENABLE_ADF7021
/** @} */
#endif // __ADF7021_H__ #endif // __ADF7021_H__

@ -1,26 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) *
* */
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
*
*/
#include "BitBuffer.h" #include "BitBuffer.h"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the BitBuffer class. */
/// Initializes a new instance of the BitBuffer class.
/// </summary>
BitBuffer::BitBuffer(uint16_t length) : BitBuffer::BitBuffer(uint16_t length) :
m_length(length), m_length(length),
m_bits(NULL), m_bits(NULL),
@ -34,10 +29,8 @@ BitBuffer::BitBuffer(uint16_t length) :
m_control = new uint8_t[length / 8U]; m_control = new uint8_t[length / 8U];
} }
/// <summary> /* Helper to get how much space the ring buffer has for samples. */
/// Helper to get how much space the ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint16_t BitBuffer::getSpace() const uint16_t BitBuffer::getSpace() const
{ {
uint16_t n = 0U; uint16_t n = 0U;
@ -55,10 +48,8 @@ uint16_t BitBuffer::getSpace() const
return n; return n;
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
uint16_t BitBuffer::getData() const uint16_t BitBuffer::getData() const
{ {
if (m_tail == m_head) if (m_tail == m_head)
@ -69,11 +60,8 @@ uint16_t BitBuffer::getData() const
return m_length - m_tail + m_head; return m_length - m_tail + m_head;
} }
/// <summary> /* */
///
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
bool BitBuffer::put(uint8_t bit, uint8_t control) bool BitBuffer::put(uint8_t bit, uint8_t control)
{ {
if (m_full) { if (m_full) {
@ -94,10 +82,8 @@ bool BitBuffer::put(uint8_t bit, uint8_t control)
return true; return true;
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool BitBuffer::get(uint8_t& bit, uint8_t& control) bool BitBuffer::get(uint8_t& bit, uint8_t& control)
{ {
if (m_head == m_tail && !m_full) if (m_head == m_tail && !m_full)
@ -115,10 +101,8 @@ bool BitBuffer::get(uint8_t& bit, uint8_t& control)
return true; return true;
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool BitBuffer::hasOverflowed() bool BitBuffer::hasOverflowed()
{ {
bool overflow = m_overflow; bool overflow = m_overflow;

@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file BitBuffer.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file BitBuffer.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
*
*/
#if !defined(__BIT_RB_H__) #if !defined(__BIT_RB_H__)
#define __BIT_RB_H__ #define __BIT_RB_H__
@ -26,27 +28,52 @@
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements a circular buffer for bit data.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements a circular ring buffer for bit data.
* @ingroup hotspot_fw
*/
class DSP_FW_API BitBuffer { class DSP_FW_API BitBuffer {
public: public:
/// <summary>Initializes a new instance of the BitBuffer class.</summary> /**
* @brief Initializes a new instance of the BitBuffer class.
* @param length Length of buffer.
*/
BitBuffer(uint16_t length); BitBuffer(uint16_t length);
/// <summary>Helper to get how much space the ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the ring buffer has for samples.
* @returns uint16_t Amount of space remaining for data.
*/
uint16_t getSpace() const; uint16_t getSpace() const;
/// <summary></summary> /**
* @brief
* @returns uint16_t
*/
uint16_t getData() const; uint16_t getData() const;
/// <summary></summary> /**
* @brief
* @param bit
* @param control
* @returns bool
*/
bool put(uint8_t bit, uint8_t control); bool put(uint8_t bit, uint8_t control);
/// <summary></summary> /**
* @brief
* @param[out] bit
* @param[out] control
* @returns bool
*/
bool get(uint8_t& bit, uint8_t& control); bool get(uint8_t& bit, uint8_t& control);
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool hasOverflowed(); bool hasOverflowed();
private: private:

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2017 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Colin Durbridge, G4EML
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2017 Andy Uribe, CA6JAU
* *
* Copyright (C) 2009-2017 Jonathan Naylor, G4KLX */
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2017 Andy Uribe, CA6JAU
*
*/
#include "Globals.h" #include "Globals.h"
#include "CWIdTX.h" #include "CWIdTX.h"
@ -85,9 +81,8 @@ const struct {
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the CWIdTX class. */
/// Initializes a new instance of the CWIdTX class.
/// </summary>
CWIdTX::CWIdTX() : CWIdTX::CWIdTX() :
m_poBuffer(), m_poBuffer(),
m_poLen(0U), m_poLen(0U),
@ -97,9 +92,8 @@ CWIdTX::CWIdTX() :
/* stub */ /* stub */
} }
/// <summary> /* Process local buffer and transmit on the air interface. */
/// Process local buffer and transmit on the air interface.
/// </summary>
void CWIdTX::process() void CWIdTX::process()
{ {
if (m_poLen == 0U) if (m_poLen == 0U)
@ -130,12 +124,8 @@ void CWIdTX::process()
} }
} }
/// <summary> /* Write CW ID data to the local buffer. */
/// Write CW ID data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t CWIdTX::write(const uint8_t* data, uint8_t length) uint8_t CWIdTX::write(const uint8_t* data, uint8_t length)
{ {
::memset(m_poBuffer, 0x00U, 300U * sizeof(uint8_t)); ::memset(m_poBuffer, 0x00U, 300U * sizeof(uint8_t));
@ -176,9 +166,8 @@ uint8_t CWIdTX::write(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void CWIdTX::reset() void CWIdTX::reset()
{ {
m_poLen = 0U; m_poLen = 0U;

@ -1,18 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2009-2015 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2017 Andy Uribe, CA6JAU
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file CWIdTX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file CWIdTX.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2009-2015 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2017 Andy Uribe, CA6JAU
*
*/
#if !defined(__CWID_TX_H__) #if !defined(__CWID_TX_H__)
#define __CWID_TX_H__ #define __CWID_TX_H__
@ -20,21 +22,35 @@
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements logic to transmit a CW ID.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements logic to transmit a CW ID.
* @ingroup hotspot_fw
*/
class DSP_FW_API CWIdTX { class DSP_FW_API CWIdTX {
public: public:
/// <summary>Initializes a new instance of the CWIdTX class.</summary> /**
* @brief Initializes a new instance of the CWIdTX class.
*/
CWIdTX(); CWIdTX();
/// <summary>Process local buffer and transmit on the air interface.</summary> /**
* @brief Process local buffer and transmit on the air interface.
*/
void process(); void process();
/// <summary>Write CW ID data to the local buffer.</summary> /**
* @brief Write CW ID data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t write(const uint8_t* data, uint8_t length); uint8_t write(const uint8_t* data, uint8_t length);
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
private: private:

@ -1,17 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2016 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2018 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) *
* */
* Copyright (C) 2016 Jonathan Naylor, G4KLX
* Copyright (C) 2018 Andy Uribe, CA6JAU
*
*/
#include "Globals.h" #include "Globals.h"
#include "CalRSSI.h" #include "CalRSSI.h"
#include "Utils.h" #include "Utils.h"
@ -20,9 +16,8 @@
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the CalRSSI class. */
/// Initializes a new instance of the CalRSSI class.
/// </summary>
CalRSSI::CalRSSI() : CalRSSI::CalRSSI() :
m_count(0U), m_count(0U),
m_navg(0U), m_navg(0U),
@ -33,9 +28,8 @@ CalRSSI::CalRSSI() :
/* stub */ /* stub */
} }
/// <summary> /* Sample RSSI values from the air interface. */
/// Sample RSSI values from the air interface.
/// </summary>
void CalRSSI::process() void CalRSSI::process()
{ {
m_count++; m_count++;

@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2016 Jonathan Naylor, G4KLX
* Copyright (C) 2018 Andy Uribe, CA6JAU
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file CalRSSI.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file CalRSSI.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2016 Jonathan Naylor, G4KLX
* Copyright (C) 2018 Andy Uribe, CA6JAU
*
*/
#if !defined(__CAL_RSSI_H__) #if !defined(__CAL_RSSI_H__)
#define __CAL_RSSI_H__ #define __CAL_RSSI_H__
@ -24,10 +26,14 @@
class DSP_FW_API CalRSSI { class DSP_FW_API CalRSSI {
public: public:
/// <summary>Initializes a new instance of the CalRSSI class.</summary> /**
* @brief Initializes a new instance of the CalRSSI class.
*/
CalRSSI(); CalRSSI();
/// <summary>Sample RSSI values from the air interface.</summary> /**
* @brief Sample RSSI values from the air interface.
*/
void process(); void process();
private: private:

@ -1,18 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2018,2019,2020 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file Defines.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. */
*
* @package DVM / Hotspot Firmware
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2018,2019,2020 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__DEFINES_H__) #if !defined(__DEFINES_H__)
#define __DEFINES_H__ #define __DEFINES_H__

@ -1,21 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Mathis Schmieder, DB9MAT
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2016 Colin Durbridge, G4EML
* * Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX * Copyright (C) 2019 Florian Wolters, DF2ET
* Copyright (C) 2016 Mathis Schmieder, DB9MAT * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* Copyright (C) 2016 Colin Durbridge, G4EML *
* Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU */
* Copyright (C) 2019 Florian Wolters, DF2ET
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -39,35 +35,35 @@ bool m_dcd = false;
uint8_t m_control; uint8_t m_control;
/** DMR BS */ /* DMR BS */
#if defined(DUPLEX) #if defined(DUPLEX)
dmr::DMRIdleRX dmrIdleRX; dmr::DMRIdleRX dmrIdleRX;
dmr::DMRRX dmrRX; dmr::DMRRX dmrRX;
#endif #endif
dmr::DMRTX dmrTX; dmr::DMRTX dmrTX;
/** DMR MS-DMO */ /* DMR MS-DMO */
dmr::DMRDMORX dmrDMORX; dmr::DMRDMORX dmrDMORX;
dmr::DMRDMOTX dmrDMOTX; dmr::DMRDMOTX dmrDMOTX;
/** P25 */ /* P25 */
p25::P25RX p25RX; p25::P25RX p25RX;
p25::P25TX p25TX; p25::P25TX p25TX;
/** NXDN */ /* NXDN */
nxdn::NXDNRX nxdnRX; nxdn::NXDNRX nxdnRX;
nxdn::NXDNTX nxdnTX; nxdn::NXDNTX nxdnTX;
/** Calibration */ /* Calibration */
dmr::CalDMR calDMR; dmr::CalDMR calDMR;
p25::CalP25 calP25; p25::CalP25 calP25;
nxdn::CalNXDN calNXDN; nxdn::CalNXDN calNXDN;
CalRSSI calRSSI; CalRSSI calRSSI;
/** CW */ /* CW */
CWIdTX cwIdTX; CWIdTX cwIdTX;
/** RS232 and Air Interface I/O */ /* RS232 and Air Interface I/O */
SerialPort serial; SerialPort serial;
IO io; IO io;

@ -1,19 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU
* Copyright (C) 2019 Florian Wolters, DF2ET
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @defgroup hotspot_fw Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * @brief Digital Voice Modem - Hotspot Firmware
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @details Firmware that is used for all-in-one hotspots.
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware *
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * @file Globals.h
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @ingroup hotspot_fw
* */
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU
* Copyright (C) 2019 Florian Wolters, DF2ET
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__GLOBALS_H__) #if !defined(__GLOBALS_H__)
#define __GLOBALS_H__ #define __GLOBALS_H__
@ -94,32 +99,32 @@ extern uint8_t m_control;
extern SerialPort serial; extern SerialPort serial;
extern IO io; extern IO io;
/** DMR BS */ /* DMR BS */
#if defined(DUPLEX) #if defined(DUPLEX)
extern dmr::DMRIdleRX dmrIdleRX; extern dmr::DMRIdleRX dmrIdleRX;
extern dmr::DMRRX dmrRX; extern dmr::DMRRX dmrRX;
#endif #endif
extern dmr::DMRTX dmrTX; extern dmr::DMRTX dmrTX;
/** DMR MS-DMO */ /* DMR MS-DMO */
extern dmr::DMRDMORX dmrDMORX; extern dmr::DMRDMORX dmrDMORX;
extern dmr::DMRDMOTX dmrDMOTX; extern dmr::DMRDMOTX dmrDMOTX;
/** P25 BS */ /* P25 BS */
extern p25::P25RX p25RX; extern p25::P25RX p25RX;
extern p25::P25TX p25TX; extern p25::P25TX p25TX;
/** NXDN BS */ /* NXDN BS */
extern nxdn::NXDNRX nxdnRX; extern nxdn::NXDNRX nxdnRX;
extern nxdn::NXDNTX nxdnTX; extern nxdn::NXDNTX nxdnTX;
/** Calibration */ /* Calibration */
extern dmr::CalDMR calDMR; extern dmr::CalDMR calDMR;
extern p25::CalP25 calP25; extern p25::CalP25 calP25;
extern nxdn::CalNXDN calNXDN; extern nxdn::CalNXDN calNXDN;
extern CalRSSI calRSSI; extern CalRSSI calRSSI;
/** CW */ /* CW */
extern CWIdTX cwIdTX; extern CWIdTX cwIdTX;
#endif // __GLOBALS_H__ #endif // __GLOBALS_H__

151
IO.cpp

@ -1,19 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2017 Danilo, DB4PLE
* * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX *
* Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU */
* Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "ADF7021.h" #include "ADF7021.h"
#include "IO.h" #include "IO.h"
@ -22,9 +18,8 @@
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the IO class. */
/// Initializes a new instance of the IO class.
/// </summary>
IO::IO(): IO::IO():
m_started(false), m_started(false),
m_rxBuffer(1024U), m_rxBuffer(1024U),
@ -64,9 +59,8 @@ IO::IO():
selfTest(); selfTest();
} }
/// <summary> /* Starts air interface sampler. */
/// Starts air interface sampler.
/// </summary>
void IO::start() void IO::start()
{ {
if (m_started) if (m_started)
@ -77,9 +71,8 @@ void IO::start()
m_started = true; m_started = true;
} }
/// <summary> /* Process samples from air interface. */
/// Process samples from air interface.
/// </summary>
void IO::process() void IO::process()
{ {
uint8_t bit; uint8_t bit;
@ -155,13 +148,8 @@ void IO::process()
} }
} }
/// <summary> /* Write bits to air interface. */
/// Write bits to air interface.
/// </summary>
/// <param name="mode"></param>
/// <param name="samples"></param>
/// <param name="length"></param>
/// <param name="control"></param>
void IO::write(uint8_t* data, uint16_t length, const uint8_t* control) void IO::write(uint8_t* data, uint16_t length, const uint8_t* control)
{ {
if (!m_started) if (!m_started)
@ -181,19 +169,15 @@ void IO::write(uint8_t* data, uint16_t length, const uint8_t* control)
} }
} }
/// <summary> /* Helper to get how much space the transmit ring buffer has for samples. */
/// Helper to get how much space the transmit ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint16_t IO::getSpace() const uint16_t IO::getSpace() const
{ {
return m_txBuffer.getSpace(); return m_txBuffer.getSpace();
} }
/// <summary> /* */
///
/// </summary>
/// <param name="dcd"></param>
void IO::setDecode(bool dcd) void IO::setDecode(bool dcd)
{ {
if (dcd != m_dcd) if (dcd != m_dcd)
@ -202,10 +186,8 @@ void IO::setDecode(bool dcd)
m_dcd = dcd; m_dcd = dcd;
} }
/// <summary> /* Helper to set the modem air interface state. */
/// Helper to set the modem air interface state.
/// </summary>
/// <param name="modemState"></param>
void IO::setMode(DVM_STATE modemState) void IO::setMode(DVM_STATE modemState)
{ {
DVM_STATE relativeState = modemState; DVM_STATE relativeState = modemState;
@ -223,13 +205,8 @@ void IO::setMode(DVM_STATE modemState)
setNXDNInt(relativeState == STATE_NXDN); setNXDNInt(relativeState == STATE_NXDN);
} }
/// <summary> /* Sets the RF parameters. */
/// Sets the RF parameters.
/// </summary>
/// <param name="rxFreq"></param>
/// <param name="txFreq"></param>
/// <param name="rfPower"></param>
/// <param name="gainMode"></param>
uint8_t IO::setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower, ADF_GAIN_MODE gainMode) uint8_t IO::setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower, ADF_GAIN_MODE gainMode)
{ {
m_rfPower = rfPower >> 2; m_rfPower = rfPower >> 2;
@ -237,22 +214,22 @@ uint8_t IO::setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower, ADF_G
// check frequency ranges // check frequency ranges
if (!( if (!(
/** 136 - 174 mhz */ /* 136 - 174 mhz */
((rxFreq >= VHF_MIN) && (rxFreq < VHF_MAX)) || ((txFreq >= VHF_MIN) && (txFreq < VHF_MAX)) || ((rxFreq >= VHF_MIN) && (rxFreq < VHF_MAX)) || ((txFreq >= VHF_MIN) && (txFreq < VHF_MAX)) ||
/** 216 - 225 mhz */ /* 216 - 225 mhz */
((rxFreq >= VHF_220_MIN) && (rxFreq < VHF_220_MAX)) || ((txFreq >= VHF_220_MIN) && (txFreq < VHF_220_MAX)) || ((rxFreq >= VHF_220_MIN) && (rxFreq < VHF_220_MAX)) || ((txFreq >= VHF_220_MIN) && (txFreq < VHF_220_MAX)) ||
/** 380 - 431 mhz */ /* 380 - 431 mhz */
((rxFreq >= UHF_380_MIN) && (rxFreq < UHF_380_MAX)) || ((txFreq >= UHF_380_MIN) && (txFreq < UHF_380_MAX)) || ((rxFreq >= UHF_380_MIN) && (rxFreq < UHF_380_MAX)) || ((txFreq >= UHF_380_MIN) && (txFreq < UHF_380_MAX)) ||
/** 431 - 450 mhz */ /* 431 - 450 mhz */
((rxFreq >= UHF_1_MIN) && (rxFreq < UHF_1_MAX)) || ((txFreq >= UHF_1_MIN) && (txFreq < UHF_1_MAX)) || ((rxFreq >= UHF_1_MIN) && (rxFreq < UHF_1_MAX)) || ((txFreq >= UHF_1_MIN) && (txFreq < UHF_1_MAX)) ||
/** 450 - 470 mhz */ /* 450 - 470 mhz */
((rxFreq >= UHF_2_MIN) && (rxFreq < UHF_2_MAX)) || ((txFreq >= UHF_2_MIN) && (txFreq < UHF_2_MAX)) || ((rxFreq >= UHF_2_MIN) && (rxFreq < UHF_2_MAX)) || ((txFreq >= UHF_2_MIN) && (txFreq < UHF_2_MAX)) ||
/** 470 - 520 mhz */ /* 470 - 520 mhz */
((rxFreq >= UHF_T_MIN) && (rxFreq < UHF_T_MAX)) || ((txFreq >= UHF_T_MIN) && (txFreq < UHF_T_MAX)) || ((rxFreq >= UHF_T_MIN) && (rxFreq < UHF_T_MAX)) || ((txFreq >= UHF_T_MIN) && (txFreq < UHF_T_MAX)) ||
/** 842 - 900 mhz */ /* 842 - 900 mhz */
((rxFreq >= UHF_800_MIN) && (rxFreq < UHF_800_MAX)) || ((txFreq >= UHF_800_MIN) && (txFreq < UHF_800_MAX)) || ((rxFreq >= UHF_800_MIN) && (rxFreq < UHF_800_MAX)) || ((txFreq >= UHF_800_MIN) && (txFreq < UHF_800_MAX)) ||
/** 900 - 950 mhz */ /* 900 - 950 mhz */
((rxFreq >= UHF_900_MIN) && (rxFreq < UHF_900_MAX)) || ((txFreq >= UHF_900_MIN) && (txFreq < UHF_900_MAX)) ((rxFreq >= UHF_900_MIN) && (rxFreq < UHF_900_MAX)) || ((txFreq >= UHF_900_MIN) && (txFreq < UHF_900_MAX))
)) ))
return RSN_INVALID_REQUEST; return RSN_INVALID_REQUEST;
@ -289,44 +266,36 @@ uint8_t IO::setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower, ADF_G
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Flag indicating the TX ring buffer has overflowed. */
/// Flag indicating the TX ring buffer has overflowed.
/// </summary>
/// <returns></returns>
bool IO::hasTXOverflow() bool IO::hasTXOverflow()
{ {
return m_txBuffer.hasOverflowed(); return m_txBuffer.hasOverflowed();
} }
/// <summary> /* Flag indicating the RX ring buffer has overflowed. */
/// Flag indicating the RX ring buffer has overflowed.
/// </summary>
/// <returns></returns>
bool IO::hasRXOverflow() bool IO::hasRXOverflow()
{ {
return m_rxBuffer.hasOverflowed(); return m_rxBuffer.hasOverflowed();
} }
/// <summary> /* */
///
/// </summary>
void IO::resetWatchdog() void IO::resetWatchdog()
{ {
m_watchdog = 0U; m_watchdog = 0U;
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
uint32_t IO::getWatchdog() uint32_t IO::getWatchdog()
{ {
return m_watchdog; return m_watchdog;
} }
/// <summary> /* */
///
/// </summary>
void IO::selfTest() void IO::selfTest()
{ {
bool ledValue = false; bool ledValue = false;
@ -420,11 +389,8 @@ void IO::selfTest()
delayUS(125000U); delayUS(125000U);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="int1"></param>
/// <param name="int2"></param>
void IO::getIntCounter(uint16_t& int1, uint16_t& int2) void IO::getIntCounter(uint16_t& int1, uint16_t& int2)
{ {
int1 = m_int1Counter; int1 = m_int1Counter;
@ -438,11 +404,8 @@ void IO::getIntCounter(uint16_t& int1, uint16_t& int2)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#if defined(ZUMSPOT_ADF7021) || defined(LONESTAR_USB) || defined(SKYBRIDGE_HS) #if defined(ZUMSPOT_ADF7021) || defined(LONESTAR_USB) || defined(SKYBRIDGE_HS)
/// <summary> /* */
///
/// </summary>
/// <param name="rxFreq"></param>
/// <param name="txFreq"></param>
void IO::checkBand(uint32_t rxFreq, uint32_t txFreq) void IO::checkBand(uint32_t rxFreq, uint32_t txFreq)
{ {
// check hotspot configuration for single or dual ADF7021 // check hotspot configuration for single or dual ADF7021

344
IO.h

@ -1,19 +1,25 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU
* Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2017-2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file IO.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file IO.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware * @file IOSTM.cpp
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * @ingroup hotspot_fw
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @file ADF7021.cpp
* * @ingroup hotspot_fw
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX */
* Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU
* Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2017-2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__IO_H__) #if !defined(__IO_H__)
#define __IO_H__ #define __IO_H__
@ -31,123 +37,243 @@
#define CAL_DLY_LOOP 104600U #define CAL_DLY_LOOP 104600U
#endif #endif
/**
* @brief ADF7021 Gain Modes
*/
enum ADF_GAIN_MODE { enum ADF_GAIN_MODE {
// AGC automatic, default settings ADF_GAIN_AUTO = 0U, //! AGC automatic, default settings
ADF_GAIN_AUTO = 0U, ADF_GAIN_AUTO_LIN = 1U, //! AGC automatic with high LNA linearity
// AGC automatic with high LNA linearity ADF_GAIN_LOW = 2U, //! AGC OFF, lowest gain
ADF_GAIN_AUTO_LIN = 1U, ADF_GAIN_HIGH = 3U //! AGC OFF, highest gain
// AGC OFF, lowest gain
ADF_GAIN_LOW = 2U,
// AGC OFF, highest gain
ADF_GAIN_HIGH = 3U
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements the input/output data path with the radio air interface.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements the input/output data path with the radio air interface.
* @ingroup hotspot_fw
*/
class DSP_FW_API IO { class DSP_FW_API IO {
public: public:
/// <summary>Initializes a new instance of the IO class.</summary> /**
* @brief Initializes a new instance of the IO class.
*/
IO(); IO();
/// <summary>Starts air interface sampler.</summary> /**
* @brief Starts air interface sampler.
*/
void start(); void start();
/// <summary>Process bits from air interface.</summary> /**
* @brief Process bits from air interface.
*/
void process(); void process();
/// <summary>Write bits to air interface.</summary> /**
* @brief Write bits to air interface.
* @param data Data to write.
* @param length Length of data buffer.
* @param control
*/
void write(uint8_t* data, uint16_t length, const uint8_t* control = NULL); void write(uint8_t* data, uint16_t length, const uint8_t* control = NULL);
/// <summary>Helper to get how much space the transmit ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the transmit ring buffer has for samples.
* @returns uint16_t Amount of space in the transmit ring buffer for samples.
*/
uint16_t getSpace(void) const; uint16_t getSpace(void) const;
/// <summary></summary> /**
* @brief
* @param dcd
*/
void setDecode(bool dcd); void setDecode(bool dcd);
/// <summary>Set modem mode.</summary> /**
* @brief Set modem mode.
* @param modemState
*/
void setMode(DVM_STATE modemState); void setMode(DVM_STATE modemState);
/// <summary>Hardware interrupt handler.</summary> /**
* @brief Hardware interrupt handler.
*/
void interrupt1(); void interrupt1();
#if defined(DUPLEX) #if defined(DUPLEX)
/// <summary>Hardware interrupt handler.</summary> /**
* @brief Hardware interrupt handler.
*/
void interrupt2(); void interrupt2();
#endif #endif
/// <summary>Sets the ADF7021 RF configuration.</summary> /**
* @brief Sets the ADF7021 RF configuration.
* @param modemState
* @param reset
*/
void rf1Conf(DVM_STATE modemState, bool reset); void rf1Conf(DVM_STATE modemState, bool reset);
#if defined(DUPLEX) #if defined(DUPLEX)
/// <summary>Sets the ADF7021 RF configuration.</summary> /**
* @brief Sets the ADF7021 RF configuration.
* @param modemState
*/
void rf2Conf(DVM_STATE modemState); void rf2Conf(DVM_STATE modemState);
#endif #endif
/// <summary></summary> /**
* @brief Sets the deviation levels.
* @param dmrTXLevel DMR Transmit Level.
* @param p25TXLevel P25 Transmit Level.
* @param nxdnTXLevel NXDN Transmit Level.
*/
void setDeviations(uint8_t dmrTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel); void setDeviations(uint8_t dmrTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel);
/// <summary>Sets the RF parameters.</summary> /**
* @brief Sets the RF parameters.
* @param rxFreq Receive Frequency (hz).
* @param txFreq Transmit Frequency (hz).
* @param rfPower RF Power Level.
* @param gainMode Gain Mode.
* @returns uint8_t Reason code.
*/
uint8_t setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower, ADF_GAIN_MODE gainMode); uint8_t setRFParams(uint32_t rxFreq, uint32_t txFreq, uint8_t rfPower, ADF_GAIN_MODE gainMode);
/// <summary>Sets the RF adjustment parameters.</summary> /**
* @brief Sets the RF adjustment parameters.
* @param dmrDiscBWAdj DMR Discriminator Bandwidth Adjust.
* @param p25DiscBWAdj P25 Discriminator Bandwidth Adjust.
* @param nxdnDiscBWAdj NXDN Discriminator Bandwidth Adjust.
* @param dmrPostBWAdj DMR Post Bandwidth Adjust.
* @param p25PostBWAdj P25 Post Bandwidth Adjust.
* @param nxdnPostBWAdj NXDN Post Bandwidth Adjust.
*/
void setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t nxdnDiscBWAdj, int8_t dmrPostBWAdj, int8_t p25PostBWAdj, int8_t nxdnPostBWAdj); void setRFAdjust(int8_t dmrDiscBWAdj, int8_t p25DiscBWAdj, int8_t nxdnDiscBWAdj, int8_t dmrPostBWAdj, int8_t p25PostBWAdj, int8_t nxdnPostBWAdj);
/// <summary>Sets the RF AFC adjustment parameters.</summary> /**
* @brief Sets the RF AFC adjustment parameters.
* @param afcEnable Flag indicating the Automatic Frequency Correction is enabled.
* @param afcKI
* @param afcKP
* @param afcRange
*/
void setAFCParams(bool afcEnable, uint8_t afcKI, uint8_t afcKP, uint8_t afcRange); void setAFCParams(bool afcEnable, uint8_t afcKI, uint8_t afcKP, uint8_t afcRange);
/// <summary>Flag indicating the TX ring buffer has overflowed.</summary> /**
* @brief Flag indicating the TX ring buffer has overflowed.
* @returns bool Flag indicating the TX ring buffer has overflowed.
*/
bool hasTXOverflow(void); bool hasTXOverflow(void);
/// <summary>Flag indicating the RX ring buffer has overflowed.</summary> /**
* @brief Flag indicating the RX ring buffer has overflowed.
* @returns bool Flag indicating the RX ring buffer has overflowed.
*/
bool hasRXOverflow(void); bool hasRXOverflow(void);
/// <summary></summary> /**
* @brief
*/
void resetWatchdog(void); void resetWatchdog(void);
/// <summary></summary> /**
* @brief
* @returns uint32_t
*/
uint32_t getWatchdog(void); uint32_t getWatchdog(void);
/// <summary>Gets the CPU type the firmware is running on.</summary> /**
* @brief Gets the CPU type the firmware is running on.
* @returns uint8_t
*/
uint8_t getCPU() const; uint8_t getCPU() const;
/// <summary>Gets the unique identifier for the air interface.</summary> /**
* @brief Gets the unique identifier for the air interface.
* @param buffer
*/
void getUDID(uint8_t* buffer); void getUDID(uint8_t* buffer);
/// <summary></summary> /**
* @brief
* @param modemState
*/
void updateCal(DVM_STATE modemState); void updateCal(DVM_STATE modemState);
/// <summary></summary> /**
* @brief
*/
void delayBit(void); void delayBit(void);
/// <summary></summary> /**
* @brief
* @returns uint16_t
*/
uint16_t readRSSI(void); uint16_t readRSSI(void);
/// <summary></summary> /**
* @brief
*/
void selfTest(); void selfTest();
/// <summary></summary> /**
* @brief
* @param[out] int1
* @param[out] int2
*/
void getIntCounter(uint16_t& int1, uint16_t& int2); void getIntCounter(uint16_t& int1, uint16_t& int2);
#if defined(ZUMSPOT_ADF7021) || defined(LONESTAR_USB) || defined(SKYBRIDGE_HS) #if defined(ZUMSPOT_ADF7021) || defined(LONESTAR_USB) || defined(SKYBRIDGE_HS)
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool isDualBand(); bool isDualBand();
#endif #endif
/// <summary></summary> /**
* @brief
* @param on
*/
void SCLK(bool on); void SCLK(bool on);
/// <summary></summary> /**
* @brief
* @param on
*/
void SDATA(bool on); void SDATA(bool on);
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool SREAD(); bool SREAD();
/// <summary></summary> /**
* @brief
* @param on
*/
void SLE1(bool on); void SLE1(bool on);
#if defined(DUPLEX) #if defined(DUPLEX)
/// <summary></summary> /**
* @brief
* @param on
*/
void SLE2(bool on); void SLE2(bool on);
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool RXD2(); bool RXD2();
#endif #endif
/// <summary></summary> /**
* @brief
* @param on
*/
void CE(bool on); void CE(bool on);
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool RXD1(); bool RXD1();
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool CLK(); bool CLK();
private: private:
@ -169,58 +295,116 @@ private:
uint8_t m_rfPower; uint8_t m_rfPower;
ADF_GAIN_MODE m_gainMode; ADF_GAIN_MODE m_gainMode;
/// <summary>Helper to check the frequencies are within band ranges of the ADF7021.</summary> /**
* @brief Helper to check the frequencies are within band ranges of the ADF7021.
* @param rxFreq Receive Frequency (hz).
* @param txFreq Transmit Frequency (hz).
*/
void checkBand(uint32_t rxFreq, uint32_t txFreq); void checkBand(uint32_t rxFreq, uint32_t txFreq);
#if defined(ZUMSPOT_ADF7021) || defined(LONESTAR_USB) || defined(SKYBRIDGE_HS) #if defined(ZUMSPOT_ADF7021) || defined(LONESTAR_USB) || defined(SKYBRIDGE_HS)
/// <summary></summary> /**
* @brief
* @param enable
*/
void setBandVHF(bool enable); void setBandVHF(bool enable);
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool hasSingleADF7021(); bool hasSingleADF7021();
#endif #endif
/// <summary></summary> /**
* @brief
*/
void configureBand(); void configureBand();
/// <summary></summary> /**
* @brief
* @param modemState
*/
void configureTxRx(DVM_STATE modemState); void configureTxRx(DVM_STATE modemState);
/// <summary></summary> /**
* @brief
*/
void setTX(); void setTX();
/// <summary></summary> /**
* @brief
* @param doSle
*/
void setRX(bool doSle = true); void setRX(bool doSle = true);
/// <summary></summary> /**
* @brief
*/
void delayIfCal(); void delayIfCal();
/// <summary></summary> /**
* @brief
*/
void delayReset(); void delayReset();
/// <summary></summary> /**
* @brief
* @param us
*/
void delayUS(uint32_t us); void delayUS(uint32_t us);
// Hardware specific routines // Hardware specific routines
/// <summary>Initializes hardware interrupts.</summary> /**
* @brief Initializes hardware interrupts.
*/
void initInt(); void initInt();
/// <summary>Starts hardware interrupts.</summary> /**
* @brief Starts hardware interrupts.
*/
void startInt(); void startInt();
/// <summary></summary> /**
* @brief
* @param on
*/
void setTXDInt(bool on); void setTXDInt(bool on);
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
/// <summary></summary> /**
* @brief
* @param dir
*/
void setDataDirOut(bool dir); void setDataDirOut(bool dir);
/// <summary></summary> /**
* @brief
* @param on
*/
void setRXDInt(bool on); void setRXDInt(bool on);
#endif #endif
/// <summary></summary> /**
* @brief
* @param on
*/
void setLEDInt(bool on); void setLEDInt(bool on);
/// <summary></summary> /**
* @brief
* @param on
*/
void setPTTInt(bool on); void setPTTInt(bool on);
/// <summary></summary> /**
* @brief
* @param on
*/
void setCOSInt(bool on); void setCOSInt(bool on);
/// <summary></summary> /**
* @brief
* @param on
*/
void setDMRInt(bool on); void setDMRInt(bool on);
/// <summary></summary> /**
* @brief
* @param on
*/
void setP25Int(bool on); void setP25Int(bool on);
/// <summary></summary> /**
* @brief
* @param on
*/
void setNXDNInt(bool on); void setNXDNInt(bool on);
}; };

@ -1,20 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2020 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Jim McLaughlin, KI6ZUM
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU
* * Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2020 Jonathan Naylor, G4KLX * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* Copyright (C) 2016 Jim McLaughlin, KI6ZUM *
* Copyright (C) 2016,2017,2018,2019,2020 Andy Uribe, CA6JAU */
* Copyright (C) 2017 Danilo, DB4PLE
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "IO.h" #include "IO.h"
@ -293,10 +289,8 @@ extern "C" {
#endif #endif
} }
/// <summary> /* Function delay_us() from stm32duino project */
/// Function delay_us() from stm32duino project
/// </summary>
/// <param name="us">Number of microseconds to delay.</param>
static inline void delay_us(uint32_t us) static inline void delay_us(uint32_t us)
{ {
us *= 12; us *= 12;
@ -312,9 +306,8 @@ static inline void delay_us(uint32_t us)
: "r0"); : "r0");
} }
/// <summary> /* */
///
/// </summary>
static inline void delay_ns() static inline void delay_ns()
{ {
@ -329,121 +322,96 @@ static inline void delay_ns()
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Gets the CPU type the firmware is running on. */
/// Gets the CPU type the firmware is running on.
/// </summary>
/// <returns></returns>
uint8_t IO::getCPU() const uint8_t IO::getCPU() const
{ {
return CPU_TYPE_STM32; return CPU_TYPE_STM32;
} }
/// <summary> /* Gets the unique identifier for the air interface. */
/// Gets the unique identifier for the air interface.
/// </summary>
/// <returns></returns>
void IO::getUDID(uint8_t* buffer) void IO::getUDID(uint8_t* buffer)
{ {
::memcpy(buffer, (void*)STM32_UUID, 12U); ::memcpy(buffer, (void*)STM32_UUID, 12U);
} }
/// <summary> /* */
///
/// </summary>
void IO::delayBit() void IO::delayBit()
{ {
delay_ns(); delay_ns();
} }
#if defined(ZUMSPOT_ADF7021) || defined(SKYBRIDGE_HS) #if defined(ZUMSPOT_ADF7021) || defined(SKYBRIDGE_HS)
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool IO::isDualBand() bool IO::isDualBand()
{ {
return GPIO_ReadInputDataBit(PORT_DL_DPX, PIN_DL_DPX) == Bit_SET; return GPIO_ReadInputDataBit(PORT_DL_DPX, PIN_DL_DPX) == Bit_SET;
} }
#endif #endif
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::SCLK(bool on) void IO::SCLK(bool on)
{ {
GPIO_WriteBit(PORT_SCLK, PIN_SCLK, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_SCLK, PIN_SCLK, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::SDATA(bool on) void IO::SDATA(bool on)
{ {
GPIO_WriteBit(PORT_SDATA, PIN_SDATA, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_SDATA, PIN_SDATA, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool IO::SREAD() bool IO::SREAD()
{ {
return GPIO_ReadInputDataBit(PORT_SREAD, PIN_SREAD) == Bit_SET; return GPIO_ReadInputDataBit(PORT_SREAD, PIN_SREAD) == Bit_SET;
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::SLE1(bool on) void IO::SLE1(bool on)
{ {
GPIO_WriteBit(PORT_SLE, PIN_SLE, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_SLE, PIN_SLE, on ? Bit_SET : Bit_RESET);
} }
#if defined(DUPLEX) #if defined(DUPLEX)
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::SLE2(bool on) void IO::SLE2(bool on)
{ {
GPIO_WriteBit(PORT_SLE2, PIN_SLE2, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_SLE2, PIN_SLE2, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool IO::RXD2() bool IO::RXD2()
{ {
return GPIO_ReadInputDataBit(PORT_RXD2, PIN_RXD2) == Bit_SET; return GPIO_ReadInputDataBit(PORT_RXD2, PIN_RXD2) == Bit_SET;
} }
#endif #endif
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::CE(bool on) void IO::CE(bool on)
{ {
GPIO_WriteBit(PORT_CE, PIN_CE, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_CE, PIN_CE, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool IO::RXD1() bool IO::RXD1()
{ {
return GPIO_ReadInputDataBit(PORT_RXD, PIN_RXD) == Bit_SET; return GPIO_ReadInputDataBit(PORT_RXD, PIN_RXD) == Bit_SET;
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool IO::CLK() bool IO::CLK()
{ {
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
@ -458,53 +426,44 @@ bool IO::CLK()
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#if defined(ZUMSPOT_ADF7021) || defined(SKYBRIDGE_HS) #if defined(ZUMSPOT_ADF7021) || defined(SKYBRIDGE_HS)
/// <summary> /* */
///
/// </summary>
/// <param name="enable"></param>
void IO::setBandVHF(bool enable) void IO::setBandVHF(bool enable)
{ {
GPIO_WriteBit(PORT_SET_BAND, PIN_SET_BAND, enable ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_SET_BAND, PIN_SET_BAND, enable ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
bool IO::hasSingleADF7021() bool IO::hasSingleADF7021()
{ {
return GPIO_ReadInputDataBit(PORT_SGL_DBL, PIN_SGL_DBL) == Bit_SET; return GPIO_ReadInputDataBit(PORT_SGL_DBL, PIN_SGL_DBL) == Bit_SET;
} }
#endif #endif
/// <summary> /* */
///
/// </summary>
void IO::delayIfCal() void IO::delayIfCal()
{ {
delayUS(10000); delayUS(10000);
} }
/// <summary> /* */
///
/// </summary>
void IO::delayReset() void IO::delayReset()
{ {
delayUS(300); delayUS(300);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="us"></param>
void IO::delayUS(uint32_t us) void IO::delayUS(uint32_t us)
{ {
::delay_us(us); ::delay_us(us);
} }
/// <summary> /* Initializes hardware interrupts. */
/// Initializes hardware interrupts.
/// </summary>
void IO::initInt() void IO::initInt()
{ {
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
@ -726,9 +685,8 @@ void IO::initInt()
#endif #endif
} }
/// <summary> /* Starts hardware interrupts. */
/// Starts hardware interrupts.
/// </summary>
void IO::startInt() void IO::startInt()
{ {
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
@ -772,11 +730,8 @@ void IO::startInt()
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
/// <summary> /* */
///
/// </summary>
/// <remarks>RXD pin is bidirectional in standard interfaces</remarks>
/// <param name="dir"></param>
void IO::setDataDirOut(bool dir) void IO::setDataDirOut(bool dir)
{ {
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
@ -794,74 +749,58 @@ void IO::setDataDirOut(bool dir)
#endif #endif
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setRXDInt(bool on) void IO::setRXDInt(bool on)
{ {
GPIO_WriteBit(PORT_RXD, PIN_RXD, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_RXD, PIN_RXD, on ? Bit_SET : Bit_RESET);
} }
#endif #endif
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setTXDInt(bool on) void IO::setTXDInt(bool on)
{ {
GPIO_WriteBit(PORT_TXD, PIN_TXD, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_TXD, PIN_TXD, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setLEDInt(bool on) void IO::setLEDInt(bool on)
{ {
GPIO_WriteBit(PORT_LED, PIN_LED, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_LED, PIN_LED, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setPTTInt(bool on) void IO::setPTTInt(bool on)
{ {
GPIO_WriteBit(PORT_PTT_LED, PIN_PTT_LED, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_PTT_LED, PIN_PTT_LED, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setCOSInt(bool on) void IO::setCOSInt(bool on)
{ {
GPIO_WriteBit(PORT_COS_LED, PIN_COS_LED, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_COS_LED, PIN_COS_LED, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setDMRInt(bool on) void IO::setDMRInt(bool on)
{ {
GPIO_WriteBit(PORT_DMR_LED, PIN_DMR_LED, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_DMR_LED, PIN_DMR_LED, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setP25Int(bool on) void IO::setP25Int(bool on)
{ {
GPIO_WriteBit(PORT_P25_LED, PIN_P25_LED, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_P25_LED, PIN_P25_LED, on ? Bit_SET : Bit_RESET);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="on"></param>
void IO::setNXDNInt(bool on) void IO::setNXDNInt(bool on)
{ {
GPIO_WriteBit(PORT_NXDN_LED, PIN_NXDN_LED, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_NXDN_LED, PIN_NXDN_LED, on ? Bit_SET : Bit_RESET);

@ -1,17 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (c) 2020 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (c) 2020 Geoffrey Merck, F4FXL - KC3FRA
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) *
* */
* Copyright (c) 2020 Jonathan Naylor, G4KLX
* Copyright (c) 2020 Geoffrey Merck, F4FXL - KC3FRA
*
*/
#if defined(STM32F10X_MD) || defined(STM32F4XX) #if defined(STM32F10X_MD) || defined(STM32F4XX)
#include "STM_UART.h" #include "STM_UART.h"
@ -20,25 +16,23 @@
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the STM_UART class. */
/// Initializes a new instance of the STM_UART class.
/// </summary>
STM_UART::STM_UART() : STM_UART::STM_UART() :
m_usart(NULL) m_usart(NULL)
{ {
/* stub */ /* stub */
} }
/// <summary></summary> /* */
/// <param name="usart"></param>
void STM_UART::init(USART_TypeDef* usart) void STM_UART::init(USART_TypeDef* usart)
{ {
m_usart = usart; m_usart = usart;
} }
/// <summary></summary> /* */
/// <param name="data"></param>
/// <param name="length"></param>
void STM_UART::write(const uint8_t* data, uint16_t length) void STM_UART::write(const uint8_t* data, uint16_t length)
{ {
if (length == 0U || m_usart == NULL) if (length == 0U || m_usart == NULL)
@ -55,14 +49,15 @@ void STM_UART::write(const uint8_t* data, uint16_t length)
USART_ITConfig(m_usart, USART_IT_TXE, ENABLE);//make sure TX IRQ is on USART_ITConfig(m_usart, USART_IT_TXE, ENABLE);//make sure TX IRQ is on
} }
/// <summary></summary> /* */
/// <returns></returns>
uint8_t STM_UART::read() uint8_t STM_UART::read()
{ {
return m_rxFifo.get(); return m_rxFifo.get();
} }
/// <summary></summary> /* */
void STM_UART::handleIRQ() void STM_UART::handleIRQ()
{ {
if (m_usart == NULL) if (m_usart == NULL)
@ -85,12 +80,8 @@ void STM_UART::handleIRQ()
} }
} }
/// <summary> /* Flushes the transmit shift register. */
/// Flushes the transmit shift register.
/// </summary>
/// <remarks>
/// This call is blocking!
/// </remarks>
void STM_UART::flush() void STM_UART::flush()
{ {
if (m_usart == NULL) if (m_usart == NULL)
@ -101,15 +92,15 @@ void STM_UART::flush()
; ;
} }
/// <summary></summary> /* */
/// <returns></returns>
uint16_t STM_UART::available() uint16_t STM_UART::available()
{ {
return m_rxFifo.isEmpty() ? 0U : 1U; return m_rxFifo.isEmpty() ? 0U : 1U;
} }
/// <summary></summary> /* */
/// <returns></returns>
uint16_t STM_UART::availableForWrite() uint16_t STM_UART::availableForWrite()
{ {
return m_txFifo.isFull() ? 0U : 1U; return m_txFifo.isFull() ? 0U : 1U;

@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (c) 2020 Jonathan Naylor, G4KLX
* Copyright (c) 2020 Geoffrey Merck, F4FXL - KC3FRA
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file STM_UART.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file STM_UART.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (c) 2020 Jonathan Naylor, G4KLX
* Copyright (c) 2020 Geoffrey Merck, F4FXL - KC3FRA
*
*/
#if defined(STM32F10X_MD) || defined(STM32F4XX) #if defined(STM32F10X_MD) || defined(STM32F4XX)
#if !defined(__STM_UART_H__) #if !defined(__STM_UART_H__)
#define __STM_UART_H__ #define __STM_UART_H__
@ -29,12 +31,17 @@ const uint16_t BUFFER_MASK = BUFFER_SIZE - 1;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// This class represents a FIFO buffer on a STM32 UART.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief This class represents a FIFO buffer on a STM32 UART.
* @ingroup hotspot_fw
*/
class DSP_FW_API STM_UARTFIFO { class DSP_FW_API STM_UARTFIFO {
public: public:
/// <summary>Initializes a new instance of the STM_UARTFIFO class.</summary> /**
* @brief Initializes a new instance of the STM_UARTFIFO class.
*/
STM_UARTFIFO() : STM_UARTFIFO() :
m_head(0U), m_head(0U),
m_tail(0U) m_tail(0U)
@ -42,32 +49,46 @@ public:
/* stub */ /* stub */
} }
/// <summary></summary> /**
* @brief
* @returns uint8_t
*/
uint8_t get() uint8_t get()
{ {
return m_buffer[BUFFER_MASK & (m_tail++)]; return m_buffer[BUFFER_MASK & (m_tail++)];
} }
/// <summary></summary> /**
* @brief
* @param data
*/
void put(uint8_t data) void put(uint8_t data)
{ {
m_buffer[BUFFER_MASK & (m_head++)] = data; m_buffer[BUFFER_MASK & (m_head++)] = data;
} }
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset() void reset()
{ {
m_tail = 0U; m_tail = 0U;
m_head = 0U; m_head = 0U;
} }
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool isEmpty() bool isEmpty()
{ {
return m_tail == m_head; return m_tail == m_head;
} }
/// <summary></summary> /**
* @brief
* @returns bool
*/
bool isFull() bool isFull()
{ {
return ((m_head + 1U) & BUFFER_MASK) == (m_tail & BUFFER_MASK); return ((m_head + 1U) & BUFFER_MASK) == (m_tail & BUFFER_MASK);
@ -81,32 +102,59 @@ private:
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// This class represents an STM32 UART.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief This class represents an STM32 UART.
* @ingroup hotspot_fw
*/
class STM_UART { class STM_UART {
public: public:
/// <summary>Initializes a new instance of the STM_UART class.</summary> /**
* @brief Initializes a new instance of the STM_UART class.
*/
STM_UART(); STM_UART();
/// <summary></summary> /**
* @brief Initializes the UART.
* @param usart
*/
void init(USART_TypeDef* usart); void init(USART_TypeDef* usart);
/// <summary></summary> /**
* @brief
* @returns uint8_t
*/
uint8_t read(); uint8_t read();
/// <summary></summary> /**
* @brief
* @param[in] data
* @param length
*/
void write(const uint8_t* data, uint16_t length); void write(const uint8_t* data, uint16_t length);
/// <summary></summary> /**
* @brief
*/
void handleIRQ(); void handleIRQ();
/// <summary>Flushes the transmit shift register.</summary> /**
* @brief Flushes the transmit shift register.
*
* This call is blocking!
*/
void flush(); void flush();
/// <summary></summary> /**
* @brief
* @returns uint16_t
*/
uint16_t available(); uint16_t available();
/// <summary></summary> /**
* @brief
* @returns uint16_t
*/
uint16_t availableForWrite(); uint16_t availableForWrite();
private: private:

@ -1,27 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2022 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX */
* Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
#include "SerialBuffer.h" #include "SerialBuffer.h"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the SerialBuffer class. */
/// Initializes a new instance of the SerialBuffer class.
/// </summary>
SerialBuffer::SerialBuffer(uint16_t length) : SerialBuffer::SerialBuffer(uint16_t length) :
m_length(length), m_length(length),
m_buffer(NULL), m_buffer(NULL),
@ -32,18 +27,15 @@ SerialBuffer::SerialBuffer(uint16_t length) :
m_buffer = new uint8_t[length]; m_buffer = new uint8_t[length];
} }
/// <summary> /* Finalizes a instance of the SerialBuffer class. */
/// Finalizes a instance of the SerialBuffer class.
/// </summary>
SerialBuffer::~SerialBuffer() SerialBuffer::~SerialBuffer()
{ {
delete[] m_buffer; delete[] m_buffer;
} }
/// <summary> /* Helper to get how much space the ring buffer has for samples. */
/// Helper to get how much space the ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint16_t SerialBuffer::getSpace() const uint16_t SerialBuffer::getSpace() const
{ {
uint16_t n = 0U; uint16_t n = 0U;
@ -61,10 +53,8 @@ uint16_t SerialBuffer::getSpace() const
return n; return n;
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
uint16_t SerialBuffer::getData() const uint16_t SerialBuffer::getData() const
{ {
if (m_tail == m_head) if (m_tail == m_head)
@ -75,9 +65,8 @@ uint16_t SerialBuffer::getData() const
return m_length - m_tail + m_head; return m_length - m_tail + m_head;
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void SerialBuffer::reset() void SerialBuffer::reset()
{ {
m_head = 0U; m_head = 0U;
@ -85,9 +74,8 @@ void SerialBuffer::reset()
m_full = false; m_full = false;
} }
/// <summary> /* Helper to reset and reinitialize data values to defaults. */
/// Helper to reset and reinitialize data values to defaults.
/// </summary>
void SerialBuffer::reinitialize(uint16_t length) void SerialBuffer::reinitialize(uint16_t length)
{ {
reset(); reset();
@ -98,11 +86,8 @@ void SerialBuffer::reinitialize(uint16_t length)
m_buffer = new uint8_t[length]; m_buffer = new uint8_t[length];
} }
/// <summary> /* */
///
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
bool SerialBuffer::put(uint8_t c) bool SerialBuffer::put(uint8_t c)
{ {
if (m_full) if (m_full)
@ -120,19 +105,15 @@ bool SerialBuffer::put(uint8_t c)
return true; return true;
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
uint8_t SerialBuffer::peek() const uint8_t SerialBuffer::peek() const
{ {
return m_buffer[m_tail]; return m_buffer[m_tail];
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
uint8_t SerialBuffer::get() uint8_t SerialBuffer::get()
{ {
uint8_t value = m_buffer[m_tail]; uint8_t value = m_buffer[m_tail];

@ -1,18 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Hotspot Firmware
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file SerialBuffer.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file SerialBuffer.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Serial FIFO Control Copyright (C) 2015 by James McLaughlin, KI6ZUM
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__SERIAL_RB_H__) #if !defined(__SERIAL_RB_H__)
#define __SERIAL_RB_H__ #define __SERIAL_RB_H__
@ -33,34 +39,64 @@ const uint16_t SERIAL_RINGBUFFER_SIZE = 396U;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements a circular buffer for serial data. //
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements a circular ring buffer for serial data.
* @ingroup hotspot_fw
*/
class DSP_FW_API SerialBuffer { class DSP_FW_API SerialBuffer {
public: public:
/// <summary>Initializes a new instance of the SerialBuffer class.</summary> /**
* @brief Initializes a new instance of the SerialBuffer class.
* @param length Length of buffer.
*/
SerialBuffer(uint16_t length = SERIAL_RINGBUFFER_SIZE); SerialBuffer(uint16_t length = SERIAL_RINGBUFFER_SIZE);
/// <summary>Finalizes a instance of the SerialBuffer class.</summary> /**
* @brief Finalizes a instance of the SerialBuffer class.
*/
~SerialBuffer(); ~SerialBuffer();
/// <summary>Helper to get how much space the ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the ring buffer has for samples.
* @returns uint16_t Amount of space remaining for data.
*/
uint16_t getSpace() const; uint16_t getSpace() const;
/// <summary></summary> /**
* @brief
* @returns uint16_t
*/
uint16_t getData() const; uint16_t getData() const;
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
/// <summary>Helper to reset and reinitialize data values to defaults.</summary> /**
* @brief Helper to reset and reinitialize data values to defaults.
* @param length Length of buffer.
*/
void reinitialize(uint16_t length); void reinitialize(uint16_t length);
/// <summary></summary> /**
* @brief
* @param c
* @returns bool
*/
bool put(uint8_t c); bool put(uint8_t c);
/// <summary></summary> /**
* @brief
* @returns uint8_t
*/
uint8_t peek() const; uint8_t peek() const;
/// <summary></summary> /**
* @brief
* @returns uint8_t
*/
uint8_t get(); uint8_t get();
private: private:

@ -1,20 +1,16 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2013,2015,2016,2018,2020,2021 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Colin Durbridge, G4EML
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU
* * Copyright (C) 2019 Florian Wolters, DF2ET
* Copyright (C) 2013,2015,2016,2018,2020,2021 Jonathan Naylor, G4KLX * Copyright (C) 2017-2024 Bryan Biedenkapp, N2PLL
* Copyright (C) 2016 Colin Durbridge, G4EML *
* Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU */
* Copyright (C) 2019 Florian Wolters, DF2ET
* Copyright (C) 2017-2024 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "SerialPort.h" #include "SerialPort.h"
@ -31,9 +27,8 @@ const uint8_t PROTOCOL_VERSION = 4U;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the SerialPort class. */
/// Initializes a new instance of the SerialPort class.
/// </summary>
SerialPort::SerialPort() : SerialPort::SerialPort() :
m_buffer(), m_buffer(),
m_ptr(0U), m_ptr(0U),
@ -44,17 +39,15 @@ SerialPort::SerialPort() :
// stub // stub
} }
/// <summary> /* Starts serial port communications. */
/// Starts serial port communications.
/// </summary>
void SerialPort::start() void SerialPort::start()
{ {
beginInt(1U, SERIAL_SPEED); beginInt(1U, SERIAL_SPEED);
} }
/// <summary> /* Process data from serial port. */
/// Process data from serial port.
/// </summary>
void SerialPort::process() void SerialPort::process()
{ {
while (availableInt(1U)) { while (availableInt(1U)) {
@ -409,11 +402,8 @@ void SerialPort::process()
} }
} }
/// <summary> /* Helper to check if the modem is in a calibration state. */
/// Helper to check if the modem is in a calibration state.
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
bool SerialPort::isCalState(DVM_STATE state) bool SerialPort::isCalState(DVM_STATE state)
{ {
// calibration mode check // calibration mode check
@ -429,11 +419,8 @@ bool SerialPort::isCalState(DVM_STATE state)
return false; return false;
} }
/// <summary> /* Helper to determine digital mode if the modem is in a calibration state. */
/// Helper to determine digital mode if the modem is in a calibration state.
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
DVM_STATE SerialPort::calRelativeState(DVM_STATE state) DVM_STATE SerialPort::calRelativeState(DVM_STATE state)
{ {
if (isCalState(state)) { if (isCalState(state)) {
@ -452,12 +439,8 @@ DVM_STATE SerialPort::calRelativeState(DVM_STATE state)
return STATE_CW; return STATE_CW;
} }
/// <summary> /* Write DMR frame data to serial port. */
/// Write DMR frame data to serial port.
/// </summary>
/// <param name="slot"></param>
/// <param name="data"></param>
/// <param name="length"></param>
void SerialPort::writeDMRData(bool slot, const uint8_t* data, uint8_t length) void SerialPort::writeDMRData(bool slot, const uint8_t* data, uint8_t length)
{ {
if (m_modemState != STATE_DMR && m_modemState != STATE_IDLE) if (m_modemState != STATE_DMR && m_modemState != STATE_IDLE)
@ -484,10 +467,8 @@ void SerialPort::writeDMRData(bool slot, const uint8_t* data, uint8_t length)
writeInt(1U, reply, length + 3U); writeInt(1U, reply, length + 3U);
} }
/// <summary> /* Write lost DMR frame data to serial port. */
/// Write lost DMR frame data to serial port.
/// </summary>
/// <param name="slot"></param>
void SerialPort::writeDMRLost(bool slot) void SerialPort::writeDMRLost(bool slot)
{ {
if (m_modemState != STATE_DMR && m_modemState != STATE_IDLE) if (m_modemState != STATE_DMR && m_modemState != STATE_IDLE)
@ -505,11 +486,8 @@ void SerialPort::writeDMRLost(bool slot)
writeInt(1U, reply, 3); writeInt(1U, reply, 3);
} }
/// <summary> /* Write P25 frame data to serial port. */
/// Write P25 frame data to serial port.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
void SerialPort::writeP25Data(const uint8_t* data, uint16_t length) void SerialPort::writeP25Data(const uint8_t* data, uint16_t length)
{ {
if (m_modemState != STATE_P25 && m_modemState != STATE_IDLE) if (m_modemState != STATE_P25 && m_modemState != STATE_IDLE)
@ -547,9 +525,8 @@ void SerialPort::writeP25Data(const uint8_t* data, uint16_t length)
} }
} }
/// <summary> /* Write lost P25 frame data to serial port. */
/// Write lost P25 frame data to serial port.
/// </summary>
void SerialPort::writeP25Lost() void SerialPort::writeP25Lost()
{ {
if (m_modemState != STATE_P25 && m_modemState != STATE_IDLE) if (m_modemState != STATE_P25 && m_modemState != STATE_IDLE)
@ -567,11 +544,8 @@ void SerialPort::writeP25Lost()
writeInt(1U, reply, 3); writeInt(1U, reply, 3);
} }
/// <summary> /* Write NXDN frame data to serial port. */
/// Write NXDN frame data to serial port.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
void SerialPort::writeNXDNData(const uint8_t* data, uint8_t length) void SerialPort::writeNXDNData(const uint8_t* data, uint8_t length)
{ {
if (m_modemState != STATE_NXDN && m_modemState != STATE_IDLE) if (m_modemState != STATE_NXDN && m_modemState != STATE_IDLE)
@ -598,9 +572,8 @@ void SerialPort::writeNXDNData(const uint8_t* data, uint8_t length)
writeInt(1U, reply, length + 3U); writeInt(1U, reply, length + 3U);
} }
/// <summary> /* Write lost NXDN frame data to serial port. */
/// Write lost NXDN frame data to serial port.
/// </summary>
void SerialPort::writeNXDNLost() void SerialPort::writeNXDNLost()
{ {
if (m_modemState != STATE_NXDN && m_modemState != STATE_IDLE) if (m_modemState != STATE_NXDN && m_modemState != STATE_IDLE)
@ -618,11 +591,8 @@ void SerialPort::writeNXDNLost()
writeInt(1U, reply, 3); writeInt(1U, reply, 3);
} }
/// <summary> /* Write calibration frame data to serial port. */
/// Write calibration frame data to serial port.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
void SerialPort::writeCalData(const uint8_t* data, uint8_t length) void SerialPort::writeCalData(const uint8_t* data, uint8_t length)
{ {
if (length + 3U > 130U) { if (length + 3U > 130U) {
@ -643,11 +613,8 @@ void SerialPort::writeCalData(const uint8_t* data, uint8_t length)
writeInt(1U, reply, length + 3U); writeInt(1U, reply, length + 3U);
} }
/// <summary> /* Write RSSI frame data to serial port. */
/// Write RSSI frame data to serial port.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
void SerialPort::writeRSSIData(const uint8_t* data, uint8_t length) void SerialPort::writeRSSIData(const uint8_t* data, uint8_t length)
{ {
if (m_modemState != STATE_RSSI_CAL) if (m_modemState != STATE_RSSI_CAL)
@ -671,10 +638,8 @@ void SerialPort::writeRSSIData(const uint8_t* data, uint8_t length)
writeInt(1U, reply, length + 3U); writeInt(1U, reply, length + 3U);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="text"></param>
void SerialPort::writeDebug(const char* text) void SerialPort::writeDebug(const char* text)
{ {
if (!m_debug) if (!m_debug)
@ -696,11 +661,8 @@ void SerialPort::writeDebug(const char* text)
writeInt(1U, reply, count, true); writeInt(1U, reply, count, true);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="text"></param>
/// <param name="n1"></param>
void SerialPort::writeDebug(const char* text, int16_t n1) void SerialPort::writeDebug(const char* text, int16_t n1)
{ {
if (!m_debug) if (!m_debug)
@ -725,12 +687,8 @@ void SerialPort::writeDebug(const char* text, int16_t n1)
writeInt(1U, reply, count, true); writeInt(1U, reply, count, true);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="text"></param>
/// <param name="n1"></param>
/// <param name="n2"></param>
void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2) void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2)
{ {
if (!m_debug) if (!m_debug)
@ -758,13 +716,8 @@ void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2)
writeInt(1U, reply, count, true); writeInt(1U, reply, count, true);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="text"></param>
/// <param name="n1"></param>
/// <param name="n2"></param>
/// <param name="n3"></param>
void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3) void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3)
{ {
if (!m_debug) if (!m_debug)
@ -795,14 +748,8 @@ void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3
writeInt(1U, reply, count, true); writeInt(1U, reply, count, true);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="text"></param>
/// <param name="n1"></param>
/// <param name="n2"></param>
/// <param name="n3"></param>
/// <param name="n4"></param>
void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3, int16_t n4) void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3, int16_t n4)
{ {
if (!m_debug) if (!m_debug)
@ -836,11 +783,8 @@ void SerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3
writeInt(1U, reply, count, true); writeInt(1U, reply, count, true);
} }
/// <summary> /* */
///
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
void SerialPort::writeDump(const uint8_t* data, uint16_t length) void SerialPort::writeDump(const uint8_t* data, uint16_t length)
{ {
if (!m_debug) if (!m_debug)
@ -882,9 +826,8 @@ void SerialPort::writeDump(const uint8_t* data, uint16_t length)
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Write acknowlegement. */
/// Write acknowlegement.
/// </summary>
void SerialPort::sendACK() void SerialPort::sendACK()
{ {
uint8_t reply[4U]; uint8_t reply[4U];
@ -897,10 +840,8 @@ void SerialPort::sendACK()
writeInt(1U, reply, 4); writeInt(1U, reply, 4);
} }
/// <summary> /* Write negative acknowlegement. */
/// Write negative acknowlegement.
/// </summary>
/// <param name="err"></param>
void SerialPort::sendNAK(uint8_t err) void SerialPort::sendNAK(uint8_t err)
{ {
uint8_t reply[5U]; uint8_t reply[5U];
@ -914,9 +855,8 @@ void SerialPort::sendNAK(uint8_t err)
writeInt(1U, reply, 5); writeInt(1U, reply, 5);
} }
/// <summary> /* Write modem DSP status. */
/// Write modem DSP status.
/// </summary>
void SerialPort::getStatus() void SerialPort::getStatus()
{ {
io.resetWatchdog(); io.resetWatchdog();
@ -983,9 +923,8 @@ void SerialPort::getStatus()
writeInt(1U, reply, 12); writeInt(1U, reply, 12);
} }
/// <summary> /* Write modem DSP version. */
/// Write modem DSP version.
/// </summary>
void SerialPort::getVersion() void SerialPort::getVersion()
{ {
uint8_t reply[200U]; uint8_t reply[200U];
@ -1011,11 +950,8 @@ void SerialPort::getVersion()
writeInt(1U, reply, count); writeInt(1U, reply, count);
} }
/// <summary> /* Helper to validate the passed modem state is valid. */
/// Helper to validate the passed modem state is valid.
/// </summary>
/// <param name="state"></param>
/// <returns></returns>
uint8_t SerialPort::modemStateCheck(DVM_STATE state) uint8_t SerialPort::modemStateCheck(DVM_STATE state)
{ {
// invalid mode check // invalid mode check
@ -1041,12 +977,8 @@ uint8_t SerialPort::modemStateCheck(DVM_STATE state)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Set modem DSP configuration from serial port data. */
/// Set modem DSP configuration from serial port data.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t SerialPort::setConfig(const uint8_t* data, uint8_t length) uint8_t SerialPort::setConfig(const uint8_t* data, uint8_t length)
{ {
if (length < 15U) if (length < 15U)
@ -1144,12 +1076,8 @@ uint8_t SerialPort::setConfig(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Set modem DSP mode from serial port data. */
/// Set modem DSP mode from serial port data.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t SerialPort::setMode(const uint8_t* data, uint8_t length) uint8_t SerialPort::setMode(const uint8_t* data, uint8_t length)
{ {
if (length < 1U) if (length < 1U)
@ -1169,10 +1097,8 @@ uint8_t SerialPort::setMode(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Sets the modem state. */
/// Sets the modem state.
/// </summary>
/// <param name="modemState"></param>
void SerialPort::setMode(DVM_STATE modemState) void SerialPort::setMode(DVM_STATE modemState)
{ {
switch (modemState) { switch (modemState) {
@ -1301,12 +1227,8 @@ void SerialPort::setMode(DVM_STATE modemState)
io.setMode(m_modemState); io.setMode(m_modemState);
} }
/// <summary> /* Sets the RF parameters. */
/// Sets the RF parameters.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t SerialPort::setRFParams(const uint8_t* data, uint8_t length) uint8_t SerialPort::setRFParams(const uint8_t* data, uint8_t length)
{ {
if (length < 17U) if (length < 17U)
@ -1386,12 +1308,8 @@ uint8_t SerialPort::setRFParams(const uint8_t* data, uint8_t length)
return io.setRFParams(rxFreq, txFreq, rfPower, gainMode); return io.setRFParams(rxFreq, txFreq, rfPower, gainMode);
} }
/// <summary> /* Sets the protocol ring buffer sizes. */
/// Sets the protocol ring buffer sizes.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t SerialPort::setBuffers(const uint8_t* data, uint8_t length) uint8_t SerialPort::setBuffers(const uint8_t* data, uint8_t length)
{ {
if (length < 1U) if (length < 1U)

@ -1,18 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2018,2020,2021 Jonathan Naylor, G4KLX
* Copyright (C) 2018 Andy Uribe, CA6JAU
* Copyright (C) 2018,2021-2024 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file SerialPort.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file SerialPort.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware * @file SerialSTM.cpp
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * @ingroup hotspot_fw
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) */
*
* Copyright (C) 2015,2016,2018,2020,2021 Jonathan Naylor, G4KLX
* Copyright (C) 2018 Andy Uribe, CA6JAU
* Copyright (C) 2018,2021-2024 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__SERIAL_PORT_H__) #if !defined(__SERIAL_PORT_H__)
#define __SERIAL_PORT_H__ #define __SERIAL_PORT_H__
@ -24,171 +28,260 @@
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @addtogroup modem
* @{
*/
/**
* @brief Modem operation states.
*/
enum DVM_STATE { enum DVM_STATE {
STATE_IDLE = 0U, STATE_IDLE = 0U, //! Idle
// DMR // DMR
STATE_DMR = 1U, STATE_DMR = 1U, //! DMR
// Project 25 // Project 25
STATE_P25 = 2U, STATE_P25 = 2U, //! Project 25
// NXDN // NXDN
STATE_NXDN = 3U, STATE_NXDN = 3U, //! NXDN
// CW // CW
STATE_CW = 10U, STATE_CW = 10U, //! Continuous Wave
// Calibration States // Calibration States
STATE_INT_CAL = 90U, STATE_INT_CAL = 90U, //!
STATE_P25_CAL_1K = 92U, STATE_P25_CAL_1K = 92U, //! Project 25 Calibration 1K
STATE_DMR_DMO_CAL_1K = 93U, STATE_DMR_DMO_CAL_1K = 93U, //! DMR DMO Calibration 1K
STATE_DMR_CAL_1K = 94U, STATE_DMR_CAL_1K = 94U, //! DMR Calibration 1K
STATE_DMR_LF_CAL = 95U, STATE_DMR_LF_CAL = 95U, //! DMR Low Frequency Calibration
STATE_RSSI_CAL = 96U, STATE_RSSI_CAL = 96U, //! RSSI Calibration
STATE_P25_CAL = 97U, STATE_P25_CAL = 97U, //! Project 25 Calibration
STATE_DMR_CAL = 98U, STATE_DMR_CAL = 98U, //! DMR Calibration
STATE_NXDN_CAL = 99U STATE_NXDN_CAL = 99U //! NXDN Calibration
}; };
/**
* @brief Modem commands.
*/
enum DVM_COMMANDS { enum DVM_COMMANDS {
CMD_GET_VERSION = 0x00U, CMD_GET_VERSION = 0x00U, //! Get Modem Version
CMD_GET_STATUS = 0x01U, CMD_GET_STATUS = 0x01U, //! Get Modem Status
CMD_SET_CONFIG = 0x02U, CMD_SET_CONFIG = 0x02U, //! Set Modem Configuration
CMD_SET_MODE = 0x03U, CMD_SET_MODE = 0x03U, //! Set Modem Mode
CMD_SET_SYMLVLADJ = 0x04U, CMD_SET_SYMLVLADJ = 0x04U, //! Set Symbol Level Adjustments
CMD_SET_RXLEVEL = 0x05U, CMD_SET_RXLEVEL = 0x05U, //! Set Rx Level
CMD_SET_RFPARAMS = 0x06U, CMD_SET_RFPARAMS = 0x06U, //! (Hotspot) Set RF Parameters
CMD_CAL_DATA = 0x08U, CMD_CAL_DATA = 0x08U, //! Calibration Data
CMD_RSSI_DATA = 0x09U, CMD_RSSI_DATA = 0x09U, //! RSSI Data
CMD_SEND_CWID = 0x0AU, CMD_SEND_CWID = 0x0AU, //! Send Continous Wave ID (Morse)
CMD_SET_BUFFERS = 0x0FU, CMD_SET_BUFFERS = 0x0FU, //! Set FIFO Buffer Lengths
CMD_DMR_DATA1 = 0x18U, CMD_DMR_DATA1 = 0x18U, //! DMR Data Slot 1
CMD_DMR_LOST1 = 0x19U, CMD_DMR_LOST1 = 0x19U, //! DMR Data Lost Slot 1
CMD_DMR_DATA2 = 0x1AU, CMD_DMR_DATA2 = 0x1AU, //! DMR Data Slot 2
CMD_DMR_LOST2 = 0x1BU, CMD_DMR_LOST2 = 0x1BU, //! DMR Data Lost Slot 2
CMD_DMR_SHORTLC = 0x1CU, CMD_DMR_SHORTLC = 0x1CU, //! DMR Short Link Control
CMD_DMR_START = 0x1DU, CMD_DMR_START = 0x1DU, //! DMR Start Transmit
CMD_DMR_ABORT = 0x1EU, CMD_DMR_ABORT = 0x1EU, //! DMR Abort
CMD_DMR_CACH_AT_CTRL = 0x1FU, CMD_DMR_CACH_AT_CTRL = 0x1FU, //! DMR Set CACH AT Control
CMD_DMR_CLEAR1 = 0x20U, CMD_DMR_CLEAR1 = 0x20U, //! DMR Clear Slot 1 Buffer
CMD_DMR_CLEAR2 = 0x21U, CMD_DMR_CLEAR2 = 0x21U, //! DMR Clear Slot 2 Buffer
CMD_P25_DATA = 0x31U, CMD_P25_DATA = 0x31U, //! Project 25 Data
CMD_P25_LOST = 0x32U, CMD_P25_LOST = 0x32U, //! Project 25 Data Lost
CMD_P25_CLEAR = 0x33U, CMD_P25_CLEAR = 0x33U, //! Project 25 Clear Buffer
CMD_NXDN_DATA = 0x41U, CMD_NXDN_DATA = 0x41U, //! NXDN Data
CMD_NXDN_LOST = 0x42U, CMD_NXDN_LOST = 0x42U, //! NXDN Data Lost
CMD_NXDN_CLEAR = 0x43U, CMD_NXDN_CLEAR = 0x43U, //! NXDN Clear Buffer
CMD_ACK = 0x70U, CMD_ACK = 0x70U, //! Command ACK
CMD_NAK = 0x7FU, CMD_NAK = 0x7FU, //! Command NACK
CMD_FLSH_READ = 0xE0U, CMD_FLSH_READ = 0xE0U, //! Read Flash Partition
CMD_FLSH_WRITE = 0xE1U, CMD_FLSH_WRITE = 0xE1U, //! Write Flash Partition
CMD_DEBUG1 = 0xF1U, CMD_DEBUG1 = 0xF1U, //!
CMD_DEBUG2 = 0xF2U, CMD_DEBUG2 = 0xF2U, //!
CMD_DEBUG3 = 0xF3U, CMD_DEBUG3 = 0xF3U, //!
CMD_DEBUG4 = 0xF4U, CMD_DEBUG4 = 0xF4U, //!
CMD_DEBUG5 = 0xF5U, CMD_DEBUG5 = 0xF5U, //!
CMD_DEBUG_DUMP = 0xFAU, CMD_DEBUG_DUMP = 0xFAU, //!
}; };
/**
* @brief Modem response reason codes.
*/
enum CMD_REASON_CODE { enum CMD_REASON_CODE {
RSN_OK = 0U, RSN_OK = 0U, //! OK
RSN_NAK = 1U, RSN_NAK = 1U, //! Negative Acknowledge
RSN_ILLEGAL_LENGTH = 2U, RSN_ILLEGAL_LENGTH = 2U, //! Illegal Length
RSN_INVALID_REQUEST = 4U, RSN_INVALID_REQUEST = 4U, //! Invalid Request
RSN_RINGBUFF_FULL = 8U, RSN_RINGBUFF_FULL = 8U, //! Ring Buffer Full
RSN_INVALID_FDMA_PREAMBLE = 10U, RSN_INVALID_FDMA_PREAMBLE = 10U, //! Invalid FDMA Preamble Length
RSN_INVALID_MODE = 11U, RSN_INVALID_MODE = 11U, //! Invalid Mode
RSN_INVALID_DMR_CC = 12U, RSN_INVALID_DMR_CC = 12U, //! Invalid DMR CC
RSN_INVALID_DMR_SLOT = 13U, RSN_INVALID_DMR_SLOT = 13U, //! Invalid DMR Slot
RSN_INVALID_DMR_START = 14U, RSN_INVALID_DMR_START = 14U, //! Invaild DMR Start Transmit
RSN_INVALID_DMR_RX_DELAY = 15U, RSN_INVALID_DMR_RX_DELAY = 15U, //! Invalid DMR Rx Delay
RSN_INVALID_P25_CORR_COUNT = 16U, RSN_INVALID_P25_CORR_COUNT = 16U, //! Invalid P25 Correlation Count
RSN_NO_INTERNAL_FLASH = 20U, RSN_NO_INTERNAL_FLASH = 20U, //! No Internal Flash
RSN_FAILED_ERASE_FLASH = 21U, RSN_FAILED_ERASE_FLASH = 21U, //! Failed to erase flash partition
RSN_FAILED_WRITE_FLASH = 22U, RSN_FAILED_WRITE_FLASH = 22U, //! Failed to write flash partition
RSN_FLASH_WRITE_TOO_BIG = 23U, RSN_FLASH_WRITE_TOO_BIG = 23U, //! Data to large for flash partition
RSN_HS_NO_DUAL_MODE = 32U, RSN_HS_NO_DUAL_MODE = 32U, //! (Hotspot) No Dual Mode Operation
RSN_DMR_DISABLED = 63U, RSN_DMR_DISABLED = 63U, //! DMR Disabled
RSN_P25_DISABLED = 64U, RSN_P25_DISABLED = 64U, //! Project 25 Disabled
RSN_NXDN_DISABLED = 65U RSN_NXDN_DISABLED = 65U //! NXDN Disabled
}; };
const uint8_t DVM_SHORT_FRAME_START = 0xFEU; const uint8_t DVM_SHORT_FRAME_START = 0xFEU;
const uint8_t DVM_LONG_FRAME_START = 0xFDU; const uint8_t DVM_LONG_FRAME_START = 0xFDU;
#define SERIAL_SPEED 115200 #define SERIAL_SPEED 115200
/** @} */
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements the RS232 serial bus to communicate with the HOST S/W.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements the RS232 serial bus to communicate with the HOST S/W.
* @ingroup hotspot_fw
*/
class DSP_FW_API SerialPort { class DSP_FW_API SerialPort {
public: public:
/// <summary>Initializes a new instance of the SerialPort class.</summary> /**
* @brief Initializes a new instance of the SerialPort class.
*/
SerialPort(); SerialPort();
/// <summary>Starts serial port communications.</summary> /**
* @brief Starts serial port communications.
*/
void start(); void start();
/// <summary>Process data from serial port.</summary> /**
* @brief Process data from serial port.
*/
void process(); void process();
/// <summary>Helper to check if the modem is in a calibration state.</summary> /**
* @brief Helper to check if the modem is in a calibration state.
* @param state
* @returns bool
*/
bool isCalState(DVM_STATE state); bool isCalState(DVM_STATE state);
/// <summary>Helper to determine digital mode if the modem is in a calibration state.</summary> /**
* @brief Helper to determine digital mode if the modem is in a calibration state.
* @param state
* @returns DVM_STATE
*/
DVM_STATE calRelativeState(DVM_STATE state); DVM_STATE calRelativeState(DVM_STATE state);
/// <summary>Write DMR frame data to serial port.</summary> /**
* @brief Write DMR frame data to serial port.
* @param slot DMR slot number.
* @param[in] data Data to write.
* @param length Length of data to write.
*/
void writeDMRData(bool slot, const uint8_t* data, uint8_t length); void writeDMRData(bool slot, const uint8_t* data, uint8_t length);
/// <summary>Write lost DMR frame data to serial port.</summary> /**
* @brief Write lost DMR frame data to serial port.
* @param slot DMR slot number.
*/
void writeDMRLost(bool slot); void writeDMRLost(bool slot);
/// <summary>Write P25 frame data to serial port.</summary> /**
* @brief Write P25 frame data to serial port.
* @param[in] data Data to write.
* @param length Length of data to write.
*/
void writeP25Data(const uint8_t* data, uint16_t length); void writeP25Data(const uint8_t* data, uint16_t length);
/// <summary>Write lost P25 frame data to serial port.</summary> /**
* @brief Write lost P25 frame data to serial port.
*/
void writeP25Lost(); void writeP25Lost();
/// <summary>Write NXDN frame data to serial port.</summary> /**
* @brief Write NXDN frame data to serial port.
* @param[in] data Data to write.
* @param length Length of data to write.
*/
void writeNXDNData(const uint8_t* data, uint8_t length); void writeNXDNData(const uint8_t* data, uint8_t length);
/// <summary>Write lost NXDN frame data to serial port.</summary> /**
* @brief Write lost NXDN frame data to serial port.
*/
void writeNXDNLost(); void writeNXDNLost();
/// <summary>Write calibration frame data to serial port.</summary> /**
* @brief Write calibration frame data to serial port.
* @param[in] data Data to write.
* @param length Length of data to write.
*/
void writeCalData(const uint8_t* data, uint8_t length); void writeCalData(const uint8_t* data, uint8_t length);
/// <summary>Write RSSI frame data to serial port.</summary> /**
* @brief Write RSSI frame data to serial port.
* @param[in] data Data to write.
* @param length Length of data to write.
*/
void writeRSSIData(const uint8_t* data, uint8_t length); void writeRSSIData(const uint8_t* data, uint8_t length);
/// <summary></summary> /**
* @brief
* @param[in] text
*/
void writeDebug(const char* text); void writeDebug(const char* text);
/// <summary></summary> /**
* @brief
* @param[in] text
* @param n1
*/
void writeDebug(const char* text, int16_t n1); void writeDebug(const char* text, int16_t n1);
/// <summary></summary> /**
* @brief
* @param[in] text
* @param n1
* @param n2
*/
void writeDebug(const char* text, int16_t n1, int16_t n2); void writeDebug(const char* text, int16_t n1, int16_t n2);
/// <summary></summary> /**
* @brief
* @param[in] text
* @param n1
* @param n2
* @param n3
*/
void writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3); void writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3);
/// <summary></summary> /**
* @brief
* @param[in] text
* @param n1
* @param n2
* @param n3
* @param n4
*/
void writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3, int16_t n4); void writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3, int16_t n4);
/// <summary></summary> /**
* @brief
* @param[in] data
* @param length
*/
void writeDump(const uint8_t* data, uint16_t length); void writeDump(const uint8_t* data, uint16_t length);
private: private:
@ -199,42 +292,104 @@ private:
bool m_debug; bool m_debug;
/// <summary>Write acknowlegement.</summary> /**
* @brief Write acknowlegement.
*/
void sendACK(); void sendACK();
/// <summary>Write negative acknowlegement.</summary> /**
* @brief Write negative acknowlegement.
* @param err
*/
void sendNAK(uint8_t err); void sendNAK(uint8_t err);
/// <summary>Write modem DSP status.</summary> /**
* @brief Write modem DSP status.
*/
void getStatus(); void getStatus();
/// <summary>Write modem DSP version.</summary> /**
* @brief Write modem DSP version.
*/
void getVersion(); void getVersion();
/// <summary>Helper to validate the passed modem state is valid.</summary> /**
* @brief Helper to validate the passed modem state is valid.
* @param state
* @returns uint8_t Reason code.
*/
uint8_t modemStateCheck(DVM_STATE state); uint8_t modemStateCheck(DVM_STATE state);
/// <summary>Set modem DSP configuration from serial port data.</summary> /**
* @brief Set modem DSP configuration from serial port data.
* @param[in] data Buffer containing configuration frame.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t setConfig(const uint8_t* data, uint8_t length); uint8_t setConfig(const uint8_t* data, uint8_t length);
/// <summary>Set modem DSP mode from serial port data.</summary> /**
* @brief Set modem DSP mode from serial port data.
* @param[in] data Buffer containing mode frame.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t setMode(const uint8_t* data, uint8_t length); uint8_t setMode(const uint8_t* data, uint8_t length);
/// <summary>Sets the modem state.</summary> /**
* @brief Sets the modem state.
* @param modemState
*/
void setMode(DVM_STATE modemState); void setMode(DVM_STATE modemState);
/// <summary>Sets the RF parameters.</summary> /**
* @brief Sets the RF parameters.
* @param[in] data Buffer containing RF parameters frame.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t setRFParams(const uint8_t* data, uint8_t length); uint8_t setRFParams(const uint8_t* data, uint8_t length);
/// <summary>Sets the protocol ring buffer sizes.</summary> /**
* @brief Sets the protocol ring buffer sizes.
* @param[in] data Buffer containing set buffers frame.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t setBuffers(const uint8_t* data, uint8_t length); uint8_t setBuffers(const uint8_t* data, uint8_t length);
/// <summary></summary> /**
* @brief Reads data from the modem flash parititon.
*/
void flashRead(); void flashRead();
/// <summary></summary> /**
* @brief Writes data to the modem flash partition.
* @param[in] data Buffer containing data to write to flash partition.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t flashWrite(const uint8_t* data, uint8_t length); uint8_t flashWrite(const uint8_t* data, uint8_t length);
// Hardware specific routines // Hardware specific routines
/// <summary></summary> /**
* @brief
* @param n
* @param speed
*/
void beginInt(uint8_t n, int speed); void beginInt(uint8_t n, int speed);
/// <summary></summary> /**
* @brief
* @param n
*/
int availableInt(uint8_t n); int availableInt(uint8_t n);
/// <summary></summary> /**
* @brief
* @param n
*/
int availableForWriteInt(uint8_t n); int availableForWriteInt(uint8_t n);
/// <summary></summary> /**
* @brief
* @param n
*/
uint8_t readInt(uint8_t n); uint8_t readInt(uint8_t n);
/// <summary></summary> /**
* @brief
* @param n
* @param[in] data
* @param length
* @param flush
*/
void writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush = false); void writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush = false);
}; };

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2016 Jim McLaughlin, KI6ZUM
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2021,2022,2024 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2016 Jim McLaughlin, KI6ZUM */
* Copyright (C) 2016,2017,2018,2019 Andy Uribe, CA6JAU
* Copyright (C) 2021,2022,2024 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "SerialPort.h" #include "SerialPort.h"
#include "STM_UART.h" #include "STM_UART.h"
@ -54,18 +50,18 @@ extern "C" {
static STM_UART m_USART1; static STM_UART m_USART1;
/// <summary> /**
/// * @brief Helper to handle the USART1 IRQ.
/// </summary> */
void USART1_IRQHandler() void USART1_IRQHandler()
{ {
m_USART1.handleIRQ(); m_USART1.handleIRQ();
} }
/// <summary> /**
/// * @brief Initializes the USART1.
/// </summary> * @param speed Port speed.
/// <param name="speed"></param> */
void InitUSART1(int speed) void InitUSART1(int speed)
{ {
// USART1 - TXD PA9 - RXD PA10 // USART1 - TXD PA9 - RXD PA10
@ -119,18 +115,18 @@ void InitUSART1(int speed)
static STM_UART m_USART2; static STM_UART m_USART2;
/// <summary> /**
/// * @brief Helper to handle the USART5 IRQ.
/// </summary> */
void USART2_IRQHandler() void USART2_IRQHandler()
{ {
m_USART2.handleIRQ(); m_USART2.handleIRQ();
} }
/// <summary> /**
/// * @brief Initializes the USART5.
/// </summary> * @param speed Port speed.
/// <param name="speed"></param> */
void InitUSART2(int speed) void InitUSART2(int speed)
{ {
// USART2 - TXD PA2 - RXD PA3 // USART2 - TXD PA2 - RXD PA3
@ -180,9 +176,8 @@ void InitUSART2(int speed)
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Reads data from the modem flash parititon. */
///
/// </summary>
void SerialPort::flashRead() void SerialPort::flashRead()
{ {
uint8_t reply[249U]; uint8_t reply[249U];
@ -196,11 +191,8 @@ void SerialPort::flashRead()
writeInt(1U, reply, 249U); writeInt(1U, reply, 249U);
} }
/// <summary> /* Writes data to the modem flash partition. */
///
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
uint8_t SerialPort::flashWrite(const uint8_t* data, uint8_t length) uint8_t SerialPort::flashWrite(const uint8_t* data, uint8_t length)
{ {
if (length > 249U) { if (length > 249U) {
@ -246,11 +238,8 @@ uint8_t SerialPort::flashWrite(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* */
///
/// </summary>
/// <param name="n"></param>
/// <param name="speed"></param>
void SerialPort::beginInt(uint8_t n, int speed) void SerialPort::beginInt(uint8_t n, int speed)
{ {
switch (n) { switch (n) {
@ -265,11 +254,8 @@ void SerialPort::beginInt(uint8_t n, int speed)
} }
} }
/// <summary> /* */
///
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
int SerialPort::availableInt(uint8_t n) int SerialPort::availableInt(uint8_t n)
{ {
switch (n) { switch (n) {
@ -282,11 +268,8 @@ int SerialPort::availableInt(uint8_t n)
} }
} }
/// <summary> /* */
///
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
int SerialPort::availableForWriteInt(uint8_t n) int SerialPort::availableForWriteInt(uint8_t n)
{ {
switch (n) { switch (n) {
@ -299,11 +282,8 @@ int SerialPort::availableForWriteInt(uint8_t n)
} }
} }
/// <summary> /* */
///
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
uint8_t SerialPort::readInt(uint8_t n) uint8_t SerialPort::readInt(uint8_t n)
{ {
switch (n) { switch (n) {
@ -317,13 +297,8 @@ uint8_t SerialPort::readInt(uint8_t n)
} }
/// <summary> /* */
///
/// </summary>
/// <param name="n"></param>
/// <param name="data"></param>
/// <param name="length"></param>
/// <param name="flush"></param>
void SerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush) void SerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush)
{ {
switch (n) { switch (n) {

@ -1,17 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * @package DVM / Hotspot Firmware
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
* Copyright (C) 2015,2020 Jonathan Naylor, G4KLX * Copyright (C) 2015,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2017 Andy Uribe, CA6JAU * Copyright (C) 2017 Andy Uribe, CA6JAU
* *
*/ */
#include "Utils.h" #include "Utils.h"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -29,11 +29,15 @@ const uint8_t BITS_TABLE[] = {
// Global Functions // Global Functions
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/* Returns the count of bits in the passed 8 byte value. */
uint8_t countBits8(uint8_t bits) uint8_t countBits8(uint8_t bits)
{ {
return BITS_TABLE[bits]; return BITS_TABLE[bits];
} }
/* Returns the count of bits in the passed 16 byte value. */
uint8_t countBits16(uint16_t bits) uint8_t countBits16(uint16_t bits)
{ {
uint8_t* p = (uint8_t*)&bits; uint8_t* p = (uint8_t*)&bits;
@ -43,6 +47,8 @@ uint8_t countBits16(uint16_t bits)
return n; return n;
} }
/* Returns the count of bits in the passed 32 byte value. */
uint8_t countBits32(uint32_t bits) uint8_t countBits32(uint32_t bits)
{ {
uint8_t* p = (uint8_t*)&bits; uint8_t* p = (uint8_t*)&bits;
@ -54,6 +60,8 @@ uint8_t countBits32(uint32_t bits)
return n; return n;
} }
/* Returns the count of bits in the passed 64 byte value. */
uint8_t countBits64(uint64_t bits) uint8_t countBits64(uint64_t bits)
{ {
uint8_t* p = (uint8_t*)&bits; uint8_t* p = (uint8_t*)&bits;

@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2017 Andy Uribe, CA6JAU
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file Utils.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup hotspot_fw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file Utils.cpp
* * @ingroup hotspot_fw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2017 Andy Uribe, CA6JAU
*
*/
#if !defined(__UTILS_H__) #if !defined(__UTILS_H__)
#define __UTILS_H__ #define __UTILS_H__
@ -29,9 +31,29 @@
// Global Functions // Global Functions
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Returns the count of bits in the passed 8 byte value.
* @param bits uint8_t to count bits for.
* @returns uint8_t Count of bits in passed value.
*/
DSP_FW_API uint8_t countBits8(uint8_t bits); DSP_FW_API uint8_t countBits8(uint8_t bits);
/**
* @brief Returns the count of bits in the passed 16 byte value.
* @param bits uint16_t to count bits for.
* @returns uint8_t Count of bits in passed value.
*/
DSP_FW_API uint8_t countBits16(uint16_t bits); DSP_FW_API uint8_t countBits16(uint16_t bits);
/**
* @brief Returns the count of bits in the passed 32 byte value.
* @param bits uint32_t to count bits for.
* @returns uint8_t Count of bits in passed value.
*/
DSP_FW_API uint8_t countBits32(uint32_t bits); DSP_FW_API uint8_t countBits32(uint32_t bits);
/**
* @brief Returns the count of bits in the passed 64 byte value.
* @param bits ulong64_t to count bits for.
* @returns uint8_t Count of bits in passed value.
*/
DSP_FW_API uint8_t countBits64(ulong64_t bits); DSP_FW_API uint8_t countBits64(ulong64_t bits);
#endif // __UTILS_H__ #endif // __UTILS_H__

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2015 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Colin Durbridge, G4EML
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2018,2019 Andy Uribe, CA6JAU
* *
* Copyright (C) 2009-2015 Jonathan Naylor, G4KLX */
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2018,2019 Andy Uribe, CA6JAU
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/CalDMR.h" #include "dmr/CalDMR.h"
@ -79,9 +75,8 @@ const uint8_t SHORTLC_1K[] = { 0x33U, 0x3AU, 0xA0U, 0x30U, 0x00U, 0x55U, 0xA6U,
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the CalDMR class. */
/// Initializes a new instance of the CalDMR class.
/// </summary>
CalDMR::CalDMR() : CalDMR::CalDMR() :
m_transmit(false), m_transmit(false),
m_state(DMRCAL1K_IDLE), m_state(DMRCAL1K_IDLE),
@ -93,9 +88,8 @@ CalDMR::CalDMR() :
::memcpy(m_dmr1k, VOICE_1K, DMR_FRAME_LENGTH_BYTES + 1U); ::memcpy(m_dmr1k, VOICE_1K, DMR_FRAME_LENGTH_BYTES + 1U);
} }
/// <summary> /* Process local state and transmit on the air interface. */
/// Process local state and transmit on the air interface.
/// </summary>
void CalDMR::process() void CalDMR::process()
{ {
switch (m_modemState) { switch (m_modemState) {
@ -133,10 +127,8 @@ void CalDMR::process()
} }
} }
/// <summary> /* */
///
/// </summary>
/// <param name="n"></param>
void CalDMR::createData1k(uint8_t n) void CalDMR::createData1k(uint8_t n)
{ {
for (uint8_t i = 0; i < 5U; i++) for (uint8_t i = 0; i < 5U; i++)
@ -148,10 +140,8 @@ void CalDMR::createData1k(uint8_t n)
m_dmr1k[20U] |= SYNCEMB_1K[n][6] & 0xF0U; m_dmr1k[20U] |= SYNCEMB_1K[n][6] & 0xF0U;
} }
/// <summary> /* */
///
/// </summary>
/// <param name="n"></param>
void CalDMR::createDataDMO1k(uint8_t n) void CalDMR::createDataDMO1k(uint8_t n)
{ {
for (uint8_t i = 0; i < 5U; i++) for (uint8_t i = 0; i < 5U; i++)
@ -163,9 +153,8 @@ void CalDMR::createDataDMO1k(uint8_t n)
m_dmr1k[20U] |= SYNCEMB_DMO1K[n][6] & 0xF0U; m_dmr1k[20U] |= SYNCEMB_DMO1K[n][6] & 0xF0U;
} }
/// <summary> /* */
///
/// </summary>
void CalDMR::dmr1kcal() void CalDMR::dmr1kcal()
{ {
#if defined(DUPLEX) #if defined(DUPLEX)
@ -214,9 +203,8 @@ void CalDMR::dmr1kcal()
#endif #endif
} }
/// <summary> /* */
///
/// </summary>
void CalDMR::dmrDMO1kcal() void CalDMR::dmrDMO1kcal()
{ {
dmrDMOTX.process(); dmrDMOTX.process();
@ -252,12 +240,8 @@ void CalDMR::dmrDMO1kcal()
} }
} }
/// <summary> /* Write DMR calibration state. */
/// Write DMR calibration state.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t CalDMR::write(const uint8_t* data, uint8_t length) uint8_t CalDMR::write(const uint8_t* data, uint8_t length)
{ {
if (length != 1U) if (length != 1U)

@ -1,18 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2009-2015 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2018 Andy Uribe, CA6JAU
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file CalDMR.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file CalDMR.h
* * @ingroup dmr_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2009-2015 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2018 Andy Uribe, CA6JAU
*
*/
#if !defined(__CAL_DMR_H__) #if !defined(__CAL_DMR_H__)
#define __CAL_DMR_H__ #define __CAL_DMR_H__
@ -25,43 +27,69 @@ namespace dmr
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
enum DMRCAL1K { /**
DMRCAL1K_IDLE, * @brief Calibration States
DMRCAL1K_VH, * @ingroup dmr_mfw
DMRCAL1K_VOICE, */
DMRCAL1K_VT, enum DMR1KCAL {
DMRCAL1K_WAIT DMRCAL1K_IDLE, //! Idle
DMRCAL1K_VH, //! Voice Header
DMRCAL1K_VOICE, //! Voice
DMRCAL1K_VT, //! Voice Terminator
DMRCAL1K_WAIT //!
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements logic for DMR calibration mode.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements logic for DMR calibration mode.
* @ingroup dmr_hfw
*/
class DSP_FW_API CalDMR { class DSP_FW_API CalDMR {
public: public:
/// <summary>Initializes a new instance of the CalDMR class.</summary> /**
* @brief Initializes a new instance of the CalDMR class.
*/
CalDMR(); CalDMR();
/// <summary>Process local state and transmit on the air interface.</summary> /**
* @brief Process local state and transmit on the air interface.
*/
void process(); void process();
/// <summary></summary> /**
* @brief
* @param n
*/
void createData1k(uint8_t n); void createData1k(uint8_t n);
/// <summary></summary> /**
* @brief
* @param n
*/
void createDataDMO1k(uint8_t n); void createDataDMO1k(uint8_t n);
/// <summary></summary> /**
* @brief
*/
void dmr1kcal(); void dmr1kcal();
/// <summary></summary> /**
* @brief
*/
void dmrDMO1kcal(); void dmrDMO1kcal();
/// <summary>Write DMR calibration state.</summary> /**
* @brief Write DMR calibration state.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t write(const uint8_t* data, uint8_t length); uint8_t write(const uint8_t* data, uint8_t length);
private: private:
bool m_transmit; bool m_transmit;
DMRCAL1K m_state; DMR1KCAL m_state;
uint32_t m_frameStart; uint32_t m_frameStart;
uint8_t m_dmr1k[DMR_FRAME_LENGTH_BYTES + 1U]; uint8_t m_dmr1k[DMR_FRAME_LENGTH_BYTES + 1U];

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2016 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2009-2016 Jonathan Naylor, G4KLX */
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/DMRDMORX.h" #include "dmr/DMRDMORX.h"
#include "dmr/DMRSlotType.h" #include "dmr/DMRSlotType.h"
@ -38,9 +34,8 @@ const uint8_t CONTROL_DATA = 0x40U;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the DMRDMORX class. */
/// Initializes a new instance of the DMRDMORX class.
/// </summary>
DMRDMORX::DMRDMORX() : DMRDMORX::DMRDMORX() :
m_bitBuffer(0x00U), m_bitBuffer(0x00U),
m_buffer(), m_buffer(),
@ -58,9 +53,8 @@ DMRDMORX::DMRDMORX() :
/* stub */ /* stub */
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void DMRDMORX::reset() void DMRDMORX::reset()
{ {
m_syncPtr = 0U; m_syncPtr = 0U;
@ -71,10 +65,8 @@ void DMRDMORX::reset()
m_endPtr = NOENDPTR; m_endPtr = NOENDPTR;
} }
/// <summary> /* Sample DMR bits from the air interface. */
/// Sample DMR bits from the air interface.
/// </summary>
/// <param name="bit"></param>
void DMRDMORX::databit(bool bit) void DMRDMORX::databit(bool bit)
{ {
_WRITE_BIT(m_buffer, m_dataPtr, bit); _WRITE_BIT(m_buffer, m_dataPtr, bit);
@ -215,10 +207,8 @@ void DMRDMORX::databit(bool bit)
io.setDecode(m_state != DMORXS_NONE); io.setDecode(m_state != DMORXS_NONE);
} }
/// <summary> /* Sets the DMR color code. */
/// Sets the DMR color code.
/// </summary>
/// <param name="colorCode">Color code.</param>
void DMRDMORX::setColorCode(uint8_t colorCode) void DMRDMORX::setColorCode(uint8_t colorCode)
{ {
m_colorCode = colorCode; m_colorCode = colorCode;
@ -228,9 +218,8 @@ void DMRDMORX::setColorCode(uint8_t colorCode)
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Frame synchronization correlator. */
/// Frame synchronization correlator.
/// </summary>
void DMRDMORX::correlateSync() void DMRDMORX::correlateSync()
{ {
// unpack sync bytes // unpack sync bytes
@ -294,12 +283,8 @@ void DMRDMORX::correlateSync()
} }
} }
/// <summary> /* */
///
/// </summary>
/// <param name="start"></param>
/// <param name="count"></param>
/// <param name="buffer"></param>
void DMRDMORX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer) void DMRDMORX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer)
{ {
for (uint8_t i = 0U; i < count; i++) { for (uint8_t i = 0U; i < count; i++) {
@ -346,10 +331,8 @@ void DMRDMORX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer)
} }
} }
/// <summary> /* */
///
/// </summary>
/// <param name="frame"></param>
void DMRDMORX::writeRSSIData(uint8_t* frame) void DMRDMORX::writeRSSIData(uint8_t* frame)
{ {
#if defined(SEND_RSSI_DATA) #if defined(SEND_RSSI_DATA)

@ -1,18 +1,24 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Hotspot Firmware
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file DMRDMORX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file DMRDMORX.h
* * @ingroup dmr_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__DMR_DMO_RX_H__) #if !defined(__DMR_DMO_RX_H__)
#define __DMR_DMO_RX_H__ #define __DMR_DMO_RX_H__
@ -27,29 +33,46 @@ namespace dmr
const uint16_t DMO_BUFFER_LENGTH_BITS = 576U; const uint16_t DMO_BUFFER_LENGTH_BITS = 576U;
/**
* @brief DMR DMO Receiver State
* @ingroup dmr_hfw
*/
enum DMORX_STATE { enum DMORX_STATE {
DMORXS_NONE, DMORXS_NONE, //! None
DMORXS_VOICE, DMORXS_VOICE, //! Voice Data
DMORXS_DATA DMORXS_DATA //! PDU Data
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements receiver logic for DMR DMO mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements receiver logic for DMR DMO mode operation.
* @ingroup dmr_hfw
*/
class DSP_FW_API DMRDMORX { class DSP_FW_API DMRDMORX {
public: public:
/// <summary>Initializes a new instance of the DMRDMORX class.</summary> /**
* @brief Initializes a new instance of the DMRDMORX class.
*/
DMRDMORX(); DMRDMORX();
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
/// <summary>Sample DMR bits from the air interface.</summary> /**
* @brief Sample DMR bits from the air interface.
* @param bit
*/
void databit(bool bit); void databit(bool bit);
/// <summary>Sets the DMR color code.</summary> /**
* @brief Sets the DMR color code.
* @param colorCode
*/
void setColorCode(uint8_t colorCode); void setColorCode(uint8_t colorCode);
private: private:
@ -74,12 +97,22 @@ namespace dmr
uint8_t m_type; uint8_t m_type;
/// <summary>Frame synchronization correlator.</summary> /**
* @brief Frame synchronization correlator.
*/
void correlateSync(); void correlateSync();
/// <summary></summary> /**
* @brief
* @param start
* @param count
* @param buffer
*/
void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer); void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer);
/// <summary></summary> /**
* @brief
* @param frame
*/
void writeRSSIData(uint8_t* frame); void writeRSSIData(uint8_t* frame);
}; };
} // namespace dmr } // namespace dmr

@ -1,19 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2016 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Colin Durbridge, G4EML
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* Copyright (C) 2009-2016 Jonathan Naylor, G4KLX *
* Copyright (C) 2016 Colin Durbridge, G4EML */
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/DMRSlotType.h" #include "dmr/DMRSlotType.h"
@ -34,9 +30,8 @@ const uint8_t PR_FILL[] =
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the DMRDMOTX class. */
/// Initializes a new instance of the DMRDMOTX class.
/// </summary>
DMRDMOTX::DMRDMOTX() : DMRDMOTX::DMRDMOTX() :
m_fifo(DMR_TX_BUFFER_LEN), m_fifo(DMR_TX_BUFFER_LEN),
m_poBuffer(), m_poBuffer(),
@ -47,9 +42,8 @@ DMRDMOTX::DMRDMOTX() :
/* stub */ /* stub */
} }
/// <summary> /* Process local buffer and transmit on the air interface. */
/// Process local buffer and transmit on the air interface.
/// </summary>
void DMRDMOTX::process() void DMRDMOTX::process()
{ {
if (m_poLen == 0U && m_fifo.getData() > 0U) { if (m_poLen == 0U && m_fifo.getData() > 0U) {
@ -91,12 +85,8 @@ void DMRDMOTX::process()
} }
} }
/// <summary> /* Write data to the local buffer. */
/// Write data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t DMRDMOTX::writeData(const uint8_t* data, uint8_t length) uint8_t DMRDMOTX::writeData(const uint8_t* data, uint8_t length)
{ {
if (length != (DMR_FRAME_LENGTH_BYTES + 1U)) if (length != (DMR_FRAME_LENGTH_BYTES + 1U))
@ -113,10 +103,8 @@ uint8_t DMRDMOTX::writeData(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Sets the FDMA preamble count. */
/// Sets the FDMA preamble count.
/// </summary>
/// <param name="preambleCnt">Count of preambles.</param>
void DMRDMOTX::setPreambleCount(uint8_t preambleCnt) void DMRDMOTX::setPreambleCount(uint8_t preambleCnt)
{ {
uint32_t preambles = (uint32_t)((float)preambleCnt / 0.2083F); uint32_t preambles = (uint32_t)((float)preambleCnt / 0.2083F);
@ -127,20 +115,16 @@ void DMRDMOTX::setPreambleCount(uint8_t preambleCnt)
m_preambleCnt = 80U; m_preambleCnt = 80U;
} }
/// <summary> /* Helper to resize the FIFO buffer. */
/// Helper to resize the FIFO buffer.
/// </summary>
/// <param name="size"></param>
void DMRDMOTX::resizeBuffer(uint16_t size) void DMRDMOTX::resizeBuffer(uint16_t size)
{ {
m_fifo.reset(); m_fifo.reset();
m_fifo.reinitialize(size); m_fifo.reinitialize(size);
} }
/// <summary> /* Helper to get how much space the ring buffer has for samples. */
/// Helper to get how much space the ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint16_t DMRDMOTX::getSpace() const uint16_t DMRDMOTX::getSpace() const
{ {
return m_fifo.getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U); return m_fifo.getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
@ -150,10 +134,8 @@ uint16_t DMRDMOTX::getSpace() const
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Helper to write a raw byte to the DAC. */
///
/// </summary>
/// <param name="c"></param>
void DMRDMOTX::writeByte(uint8_t c) void DMRDMOTX::writeByte(uint8_t c)
{ {
uint8_t bit; uint8_t bit;

@ -1,19 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file DMRDMOTX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file DMRDMOTX.h
* * @ingroup dmr_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__DMR_DMO_TX_H__) #if !defined(__DMR_DMO_TX_H__)
#define __DMR_DMO_TX_H__ #define __DMR_DMO_TX_H__
@ -32,27 +34,48 @@ namespace dmr
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements transmitter logic for DMR DMO mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements transmitter logic for DMR DMO mode operation.
* @ingroup dmr_hfw
*/
class DSP_FW_API DMRDMOTX { class DSP_FW_API DMRDMOTX {
public: public:
/// <summary>Initializes a new instance of the DMRDMOTX class.</summary> /**
* @brief Initializes a new instance of the DMRDMOTX class.
*/
DMRDMOTX(); DMRDMOTX();
/// <summary>Process local buffer and transmit on the air interface.</summary> /**
* @brief Process local buffer and transmit on the air interface.
*/
void process(); void process();
/// <summary>Write data to the local buffer.</summary> /**
* @brief Write data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t writeData(const uint8_t* data, uint8_t length); uint8_t writeData(const uint8_t* data, uint8_t length);
/// <summary>Sets the FDMA preamble count.</summary> /**
* @brief Sets the FDMA preamble count.
* @param preambleCnt FDMA preamble count.
*/
void setPreambleCount(uint8_t preambleCnt); void setPreambleCount(uint8_t preambleCnt);
/// <summary>Helper to resize the FIFO buffer.</summary> /**
* @brief Helper to resize the FIFO buffer.
* @param size
*/
void resizeBuffer(uint16_t size); void resizeBuffer(uint16_t size);
/// <summary>Helper to get how much space the ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the ring buffer has for samples.
* @returns uint8_t Amount of space in ring buffer for samples.
*/
uint16_t getSpace() const; uint16_t getSpace() const;
private: private:
@ -64,7 +87,10 @@ namespace dmr
uint32_t m_preambleCnt; uint32_t m_preambleCnt;
/// <summary></summary> /**
* @brief Helper to write a raw byte to the DAC.
* @param c Byte.
*/
void writeByte(uint8_t c); void writeByte(uint8_t c);
}; };
} // namespace dmr } // namespace dmr

@ -1,16 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2009-2016 Jonathan Naylor, G4KLX
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @defgroup dmr_hfw Digital Mobile Radio
* GPLv2 Open Source. Use is subject to license terms. * @brief Implementation for the ETSI TS-102 Digital Mobile Radio (DMR) standard.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @ingroup hotspot_fw
* *
* @package DVM / Hotspot Firmware * @file DMRDefines.h
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * @ingroup dmr_hfw
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) */
*
* Copyright (C) 2009-2016 Jonathan Naylor, G4KLX
*
*/
#if !defined(__DMR_DEFINES_H__) #if !defined(__DMR_DEFINES_H__)
#define __DMR_DEFINES_H__ #define __DMR_DEFINES_H__
@ -22,6 +26,11 @@ namespace dmr
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @addtogroup dmr_hfw
* @{
*/
const uint32_t DMR_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate const uint32_t DMR_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
const uint32_t DMR_FRAME_LENGTH_BYTES = 33U; const uint32_t DMR_FRAME_LENGTH_BYTES = 33U;
@ -123,6 +132,8 @@ namespace dmr
const uint8_t DT_RATE_34_DATA = 8U; const uint8_t DT_RATE_34_DATA = 8U;
const uint8_t DT_IDLE = 9U; const uint8_t DT_IDLE = 9U;
const uint8_t DT_RATE_1_DATA = 10U; const uint8_t DT_RATE_1_DATA = 10U;
/** @} */
} // namespace dmr } // namespace dmr
#endif // __DMR_DEFINES_H__ #endif // __DMR_DEFINES_H__

@ -1,17 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2017 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2017,2018 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) *
* */
* Copyright (C) 2009-2017 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2018 Andy Uribe, CA6JAU
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/DMRIdleRX.h" #include "dmr/DMRIdleRX.h"
#include "dmr/DMRSlotType.h" #include "dmr/DMRSlotType.h"
@ -36,9 +32,8 @@ const uint8_t CONTROL_DATA = 0x40U;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the DMRIdleRX class. */
/// Initializes a new instance of the DMRIdleRX class.
/// </summary>
DMRIdleRX::DMRIdleRX() : DMRIdleRX::DMRIdleRX() :
m_bitBuffer(0U), m_bitBuffer(0U),
m_buffer(), m_buffer(),
@ -49,19 +44,16 @@ DMRIdleRX::DMRIdleRX() :
/* stub */ /* stub */
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void DMRIdleRX::reset() void DMRIdleRX::reset()
{ {
m_dataPtr = 0U; m_dataPtr = 0U;
m_endPtr = NOENDPTR; m_endPtr = NOENDPTR;
} }
/// <summary> /* Sample DMR bits from the air interface. */
/// Sample DMR bits from the air interface.
/// </summary>
/// <param name="bit"></param>
void DMRIdleRX::databit(bool bit) void DMRIdleRX::databit(bool bit)
{ {
_WRITE_BIT(m_buffer, m_dataPtr, bit); _WRITE_BIT(m_buffer, m_dataPtr, bit);
@ -104,10 +96,8 @@ void DMRIdleRX::databit(bool bit)
m_dataPtr = 0U; m_dataPtr = 0U;
} }
/// <summary> /* Sets the DMR color code. */
/// Sets the DMR color code.
/// </summary>
/// <param name="colorCode">Color code.</param>
void DMRIdleRX::setColorCode(uint8_t colorCode) void DMRIdleRX::setColorCode(uint8_t colorCode)
{ {
m_colorCode = colorCode; m_colorCode = colorCode;
@ -117,12 +107,8 @@ void DMRIdleRX::setColorCode(uint8_t colorCode)
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* */
///
/// </summary>
/// <param name="start"></param>
/// <param name="count"></param>
/// <param name="buffer"></param>
void DMRIdleRX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer) void DMRIdleRX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer)
{ {
for (uint8_t i = 0U; i < count; i++) { for (uint8_t i = 0U; i < count; i++) {

@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2018 Andy Uribe, CA6JAU
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file DMRIdleRX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_mfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file DMRIdleRX.h
* * @ingroup dmr_mfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2018 Andy Uribe, CA6JAU
*
*/
#if !defined(__DMR_IDLE_RX_H__) #if !defined(__DMR_IDLE_RX_H__)
#define __DMR_IDLE_RX_H__ #define __DMR_IDLE_RX_H__
@ -30,21 +32,34 @@ namespace dmr
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements receiver logic for idle DMR mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements receiver logic for idle DMR mode operation.
* @ingroup dmr_hfw
*/
class DSP_FW_API DMRIdleRX { class DSP_FW_API DMRIdleRX {
public: public:
/// <summary>Initializes a new instance of the DMRIdleRX class.</summary> /**
* @brief Initializes a new instance of the DMRIdleRX class.
*/
DMRIdleRX(); DMRIdleRX();
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
/// <summary>Sample DMR bits from the air interface.</summary> /**
* @brief Sample DMR bits from the air interface.
* @param bit
*/
void databit(bool bit); void databit(bool bit);
/// <summary>Sets the DMR color code.</summary> /**
* @brief Sets the DMR color code.
* @param colorCode
*/
void setColorCode(uint8_t colorCode); void setColorCode(uint8_t colorCode);
private: private:
@ -56,11 +71,15 @@ namespace dmr
uint8_t m_colorCode; uint8_t m_colorCode;
/// <summary></summary> /**
* @brief
* @param start
* @param count
* @param buffer
*/
void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer); void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer);
}; };
} // namespace dmr } // namespace dmr
#endif // DUPLEX #endif // DUPLEX
#endif // __DMR_IDLE_RX_H__ #endif // __DMR_IDLE_RX_H__

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2017 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX */
* Copyright (C) 2017 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/DMRRX.h" #include "dmr/DMRRX.h"
@ -24,9 +20,8 @@ using namespace dmr;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the DMRRX class. */
/// Initializes a new instance of the DMRRX class.
/// </summary>
DMRRX::DMRRX() : DMRRX::DMRRX() :
m_slot1RX(false), m_slot1RX(false),
m_slot2RX(true) m_slot2RX(true)
@ -35,19 +30,16 @@ DMRRX::DMRRX() :
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void DMRRX::reset() void DMRRX::reset()
{ {
m_slot1RX.reset(); m_slot1RX.reset();
m_slot2RX.reset(); m_slot2RX.reset();
} }
/// <summary> /* Sample DMR bits from the air interface. */
/// Sample DMR bits from the air interface.
/// </summary>
/// <param name="bit"></param>
void DMRRX::databit(bool bit, const uint8_t control) void DMRRX::databit(bool bit, const uint8_t control)
{ {
bool dcd1 = false; bool dcd1 = false;
@ -70,20 +62,16 @@ void DMRRX::databit(bool bit, const uint8_t control)
io.setDecode(dcd1 || dcd2); io.setDecode(dcd1 || dcd2);
} }
/// <summary> /* Sets the DMR color code. */
/// Sets the DMR color code.
/// </summary>
/// <param name="colorCode">Color code.</param>
void DMRRX::setColorCode(uint8_t colorCode) void DMRRX::setColorCode(uint8_t colorCode)
{ {
m_slot1RX.setColorCode(colorCode); m_slot1RX.setColorCode(colorCode);
m_slot2RX.setColorCode(colorCode); m_slot2RX.setColorCode(colorCode);
} }
/// <summary> /* Sets the number of samples to delay before processing. */
/// Sets the number of samples to delay before processing.
/// </summary>
/// <param name="delay">Number of samples to delay.</param>
void DMRRX::setRxDelay(uint8_t delay) void DMRRX::setRxDelay(uint8_t delay)
{ {
m_slot1RX.setRxDelay(delay); m_slot1RX.setRxDelay(delay);

@ -1,18 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Copyright (C) 2017 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file DMRRX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file DMRRX.h
* * @ingroup dmr_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
* Copyright (C) 2017 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__DMR_RX_H__) #if !defined(__DMR_RX_H__)
#define __DMR_RX_H__ #define __DMR_RX_H__
@ -25,23 +27,40 @@ namespace dmr
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements receiver logic for duplex DMR mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements receiver logic for duplex DMR mode operation.
* @ingroup dmr_hfw
*/
class DSP_FW_API DMRRX { class DSP_FW_API DMRRX {
public: public:
/// <summary>Initializes a new instance of the DMRRX class.</summary> /**
* @brief Initializes a new instance of the DMRRX class.
*/
DMRRX(); DMRRX();
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
/// <summary>Sample DMR bits from the air interface.</summary> /**
* @brief Sample DMR bits from the air interface.
* @param bit
* @param[in] control
*/
void databit(bool bit, const uint8_t control); void databit(bool bit, const uint8_t control);
/// <summary>Sets the DMR color code.</summary> /**
* @brief Sets the DMR color code.
* @param colorCode
*/
void setColorCode(uint8_t colorCode); void setColorCode(uint8_t colorCode);
/// <summary>Sets the number of samples to delay before processing.</summary> /**
* @brief Sets the number of samples to delay before processing.
* @param delay
*/
void setRxDelay(uint8_t delay); void setRxDelay(uint8_t delay);
private: private:
@ -51,5 +70,4 @@ namespace dmr
} // namespace dmr } // namespace dmr
#endif // DUPLEX #endif // DUPLEX
#endif // __DMR_RX_H__ #endif // __DMR_RX_H__

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2017 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2017,2018 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2021 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2009-2017 Jonathan Naylor, G4KLX */
* Copyright (C) 2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/DMRSlotRX.h" #include "dmr/DMRSlotRX.h"
#include "dmr/DMRSlotType.h" #include "dmr/DMRSlotType.h"
@ -40,9 +36,8 @@ const uint8_t CONTROL_DATA = 0x40U;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the DMRSlotRX class. */
/// Initializes a new instance of the DMRSlotRX class.
/// </summary>
DMRSlotRX::DMRSlotRX(bool slot) : DMRSlotRX::DMRSlotRX(bool slot) :
m_slot(slot), m_slot(slot),
m_bitBuffer(0x00U), m_bitBuffer(0x00U),
@ -63,9 +58,8 @@ DMRSlotRX::DMRSlotRX(bool slot) :
/* stub */ /* stub */
} }
/// <summary> /* Helper to set data values for start of Rx. */
/// Helper to set data values for start of Rx.
/// </summary>
void DMRSlotRX::start() void DMRSlotRX::start()
{ {
m_dataPtr = 0U; m_dataPtr = 0U;
@ -73,9 +67,8 @@ void DMRSlotRX::start()
m_control = CONTROL_NONE; m_control = CONTROL_NONE;
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void DMRSlotRX::reset() void DMRSlotRX::reset()
{ {
m_dataPtr = 0U; m_dataPtr = 0U;
@ -86,10 +79,8 @@ void DMRSlotRX::reset()
resetSlot(); resetSlot();
} }
/// <summary> /* Sample DMR bits from the air interface. */
/// Sample DMR bits from the air interface.
/// </summary>
/// <param name="bit"></param>
bool DMRSlotRX::databit(bool bit) bool DMRSlotRX::databit(bool bit)
{ {
uint16_t min, max; uint16_t min, max;
@ -241,19 +232,15 @@ bool DMRSlotRX::databit(bool bit)
return m_state != DMRRXS_NONE; return m_state != DMRRXS_NONE;
} }
/// <summary> /* Sets the DMR color code. */
/// Sets the DMR color code.
/// </summary>
/// <param name="colorCode">Color code.</param>
void DMRSlotRX::setColorCode(uint8_t colorCode) void DMRSlotRX::setColorCode(uint8_t colorCode)
{ {
m_colorCode = colorCode; m_colorCode = colorCode;
} }
/// <summary> /* Sets the number of samples to delay before processing. */
/// Sets the number of samples to delay before processing.
/// </summary>
/// <param name="delay">Number of samples to delay.</param>
void DMRSlotRX::setRxDelay(uint8_t delay) void DMRSlotRX::setRxDelay(uint8_t delay)
{ {
m_delay = delay; m_delay = delay;
@ -263,10 +250,8 @@ void DMRSlotRX::setRxDelay(uint8_t delay)
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Frame synchronization correlator. */
/// Frame synchronization correlator.
/// </summary>
/// <param name="first"></param>
void DMRSlotRX::correlateSync() void DMRSlotRX::correlateSync()
{ {
// unpack sync bytes // unpack sync bytes
@ -328,9 +313,8 @@ void DMRSlotRX::correlateSync()
} }
} }
/// <summary> /* */
///
/// </summary>
void DMRSlotRX::resetSlot() void DMRSlotRX::resetSlot()
{ {
m_syncPtr = 0U; m_syncPtr = 0U;
@ -344,12 +328,8 @@ void DMRSlotRX::resetSlot()
m_n = 0U; m_n = 0U;
} }
/// <summary> /* */
///
/// </summary>
/// <param name="start"></param>
/// <param name="count"></param>
/// <param name="buffer"></param>
void DMRSlotRX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer) void DMRSlotRX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer)
{ {
for (uint8_t i = 0U; i < count; i++) { for (uint8_t i = 0U; i < count; i++) {
@ -396,10 +376,8 @@ void DMRSlotRX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer)
} }
} }
/// <summary> /* */
///
/// </summary>
/// <param name="frame"></param>
void DMRSlotRX::writeRSSIData(uint8_t* frame) void DMRSlotRX::writeRSSIData(uint8_t* frame)
{ {
#if defined(SEND_RSSI_DATA) #if defined(SEND_RSSI_DATA)

@ -1,18 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file DMRSlotRX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file DMRSlotRX.h
* * @ingroup dmr_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__DMR_SLOT_RX_H__) #if !defined(__DMR_SLOT_RX_H__)
#define __DMR_SLOT_RX_H__ #define __DMR_SLOT_RX_H__
@ -29,33 +31,56 @@ namespace dmr
const uint16_t DMR_BUFFER_LENGTH_BITS = 576U; const uint16_t DMR_BUFFER_LENGTH_BITS = 576U;
/**
* @brief DMR Slot Receiver State
* @ingroup dmr_hfw
*/
enum DMRRX_STATE { enum DMRRX_STATE {
DMRRXS_NONE, DMRRXS_NONE, //! None
DMRRXS_VOICE, DMRRXS_VOICE, //! Voice Data
DMRRXS_DATA DMRRXS_DATA //! PDU Data
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements receiver logic for DMR slots.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements receiver logic for DMR slots.
* @ingroup dmr_hfw
*/
class DSP_FW_API DMRSlotRX { class DSP_FW_API DMRSlotRX {
public: public:
/// <summary>Initializes a new instance of the DMRSlotRX class.</summary> /**
* @brief Initializes a new instance of the DMRSlotRX class.
* @param slot
*/
DMRSlotRX(bool slot); DMRSlotRX(bool slot);
/// <summary>Helper to set data values for start of Rx.</summary> /**
* @brief Helper to set data values for start of Rx.
*/
void start(); void start();
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
/// <summary>Sample DMR bits from the air interface.</summary> /**
* @brief Sample DMR bits from the air interface.
* @param bit
*/
bool databit(bool bit); bool databit(bool bit);
/// <summary>Sets the DMR color code.</summary> /**
* @brief Sets the DMR color code.
* @param colorCode
*/
void setColorCode(uint8_t colorCode); void setColorCode(uint8_t colorCode);
/// <summary>Sets the number of samples to delay before processing.</summary> /**
* @brief Sets the number of samples to delay before processing.
* @param delay
*/
void setRxDelay(uint8_t delay); void setRxDelay(uint8_t delay);
@ -84,18 +109,29 @@ namespace dmr
uint8_t m_type; uint8_t m_type;
/// <summary>Frame synchronization correlator.</summary> /**
* @brief Frame synchronization correlator.
*/
void correlateSync(); void correlateSync();
/// <summary></summary> /**
* @brief
*/
void resetSlot(); void resetSlot();
/// <summary></summary> /**
* @brief
* @param start
* @param count
* @param buffer
*/
void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer); void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer);
/// <summary></summary> /**
* @brief
* @param frame
*/
void writeRSSIData(uint8_t* frame); void writeRSSIData(uint8_t* frame);
}; };
} // namespace dmr } // namespace dmr
#endif // DUPLEX #endif // DUPLEX
#endif // __DMR_SLOT_RX_H__ #endif // __DMR_SLOT_RX_H__

@ -1,16 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2015 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) *
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) */
*
* Copyright (C) 2015 Jonathan Naylor, G4KLX
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/DMRSlotType.h" #include "dmr/DMRSlotType.h"
@ -213,20 +209,15 @@ const uint32_t DECODING_TABLE_1987[] = {
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the DMRSlotType class. */
/// Initializes a new instance of the DMRSlotType class.
/// </summary>
DMRSlotType::DMRSlotType() DMRSlotType::DMRSlotType()
{ {
/* stub */ /* stub */
} }
/// <summary> /* Decodes DMR slot type. */
/// Decodes DMR slot type.
/// </summary>
/// <param name="frame"></param>
/// <param name="colorCode"></param>
/// <param name="dataType"></param>
void DMRSlotType::decode(const uint8_t* frame, uint8_t& colorCode, uint8_t& dataType) const void DMRSlotType::decode(const uint8_t* frame, uint8_t& colorCode, uint8_t& dataType) const
{ {
uint8_t slotType[3U]; uint8_t slotType[3U];
@ -245,12 +236,8 @@ void DMRSlotType::decode(const uint8_t* frame, uint8_t& colorCode, uint8_t& data
dataType = (code >> 0) & 0x0FU; dataType = (code >> 0) & 0x0FU;
} }
/// <summary> /* Encodes DMR slot type. */
/// Encodes DMR slot type.
/// </summary>
/// <param name="colorCode"></param>
/// <param name="dataType"></param>
/// <param name="frame"></param>
void DMRSlotType::encode(uint8_t colorCode, uint8_t dataType, uint8_t* frame) const void DMRSlotType::encode(uint8_t colorCode, uint8_t dataType, uint8_t* frame) const
{ {
uint8_t slotType[3U]; uint8_t slotType[3U];
@ -272,11 +259,8 @@ void DMRSlotType::encode(uint8_t colorCode, uint8_t dataType, uint8_t* frame) co
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* */
///
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
uint8_t DMRSlotType::decode2087(const uint8_t* data) const uint8_t DMRSlotType::decode2087(const uint8_t* data) const
{ {
uint32_t code = (data[0U] << 11) + (data[1U] << 3) + (data[2U] >> 5); uint32_t code = (data[0U] << 11) + (data[1U] << 3) + (data[2U] >> 5);
@ -289,20 +273,8 @@ uint8_t DMRSlotType::decode2087(const uint8_t* data) const
return code >> 11; return code >> 11;
} }
/// <summary> /* */
///
/// </summary>
/// <remarks>
/// Compute the syndrome corresponding to the given pattern, i.e., the
/// remainder after dividing the pattern (when considering it as the vector
/// representation of a polynomial) by the generator polynomial, GENPOL.
/// In the program this pattern has several meanings: (1) pattern = infomation
/// bits, when constructing the encoding table; (2) pattern = error pattern,
/// when constructing the decoding table; and (3) pattern = received vector, to
/// obtain its syndrome in decoding.
/// </remarks>
/// <param name="pattern"></param>
/// <returns></returns>
uint32_t DMRSlotType::getSyndrome1987(uint32_t pattern) const uint32_t DMRSlotType::getSyndrome1987(uint32_t pattern) const
{ {
unsigned int aux = X18; unsigned int aux = X18;

@ -1,16 +1,18 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015 Jonathan Naylor, G4KLX
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file DMRSlotType.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file DMRSlotType.h
* * @ingroup dmr_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015 Jonathan Naylor, G4KLX
*
*/
#if !defined(__DMR_SLOT_TYPE_H__) #if !defined(__DMR_SLOT_TYPE_H__)
#define __DMR_SLOT_TYPE_H__ #define __DMR_SLOT_TYPE_H__
@ -20,23 +22,46 @@ namespace dmr
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
//
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Represents DMR slot type.
* @ingroup dmr_hfw
*/
class DSP_FW_API DMRSlotType { class DSP_FW_API DMRSlotType {
public: public:
/// <summary>Initializes a new instance of the DMRSlotType class.</summary> /**
* @brief Initializes a new instance of the DMRSlotType class.
*/
DMRSlotType(); DMRSlotType();
/// <summary>Decodes DMR slot type.</summary> /**
* @brief Decodes DMR slot type.
* @param[in] frame
* @param[out] colorCode
* @param[out] dataType
*/
void decode(const uint8_t* frame, uint8_t& colorCode, uint8_t& dataType) const; void decode(const uint8_t* frame, uint8_t& colorCode, uint8_t& dataType) const;
/// <summary>Encodes DMR slot type.</summary> /**
* @brief Encodes DMR slot type.
* @param colorCode
* @param dataType
* @param[out] frame
*/
void encode(uint8_t colorCode, uint8_t dataType, uint8_t* frame) const; void encode(uint8_t colorCode, uint8_t dataType, uint8_t* frame) const;
private: private:
/// <summary></summary> /**
* @brief
* @param[in] data
* @returns uint8_t
*/
uint8_t decode2087(const uint8_t* data) const; uint8_t decode2087(const uint8_t* data) const;
/// <summary></summary> /**
* @brief
* @param pattern
* @returns uint32_t
*/
uint32_t getSyndrome1987(uint32_t pattern) const; uint32_t getSyndrome1987(uint32_t pattern) const;
}; };
} // namespace dmr } // namespace dmr

@ -1,19 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2017 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016 Colin Durbridge, G4EML
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2017 Andy Uribe, CA6JAU
* * Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
* Copyright (C) 2009-2017 Jonathan Naylor, G4KLX *
* Copyright (C) 2016 Colin Durbridge, G4EML */
* Copyright (C) 2017 Andy Uribe, CA6JAU
* Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "dmr/DMRSlotType.h" #include "dmr/DMRSlotType.h"
@ -48,9 +44,8 @@ const uint32_t ABORT_COUNT = 6U;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the DMRTX class. */
/// Initializes a new instance of the DMRTX class.
/// </summary>
DMRTX::DMRTX() : DMRTX::DMRTX() :
m_fifo(), m_fifo(),
m_state(DMRTXSTATE_IDLE), m_state(DMRTXSTATE_IDLE),
@ -81,9 +76,8 @@ DMRTX::DMRTX() :
m_abortCount[1U] = 0U; m_abortCount[1U] = 0U;
} }
/// <summary> /* Process local buffer and transmit on the air interface. */
/// Process local buffer and transmit on the air interface.
/// </summary>
void DMRTX::process() void DMRTX::process()
{ {
if (m_state == DMRTXSTATE_IDLE) if (m_state == DMRTXSTATE_IDLE)
@ -138,12 +132,8 @@ void DMRTX::process()
} }
} }
/// <summary> /* Write slot 1 data to the local buffer. */
/// Write slot 1 data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t DMRTX::writeData1(const uint8_t* data, uint8_t length) uint8_t DMRTX::writeData1(const uint8_t* data, uint8_t length)
{ {
if (length != (DMR_FRAME_LENGTH_BYTES + 1U)) if (length != (DMR_FRAME_LENGTH_BYTES + 1U))
@ -169,12 +159,8 @@ uint8_t DMRTX::writeData1(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Write slot 2 data to the local buffer. */
/// Write slot 2 data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t DMRTX::writeData2(const uint8_t* data, uint8_t length) uint8_t DMRTX::writeData2(const uint8_t* data, uint8_t length)
{ {
if (length != (DMR_FRAME_LENGTH_BYTES + 1U)) if (length != (DMR_FRAME_LENGTH_BYTES + 1U))
@ -200,12 +186,8 @@ uint8_t DMRTX::writeData2(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Write short LC data to the local buffer. */
/// Write short LC data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t DMRTX::writeShortLC(const uint8_t* data, uint8_t length) uint8_t DMRTX::writeShortLC(const uint8_t* data, uint8_t length)
{ {
if (length != 9U) if (length != 9U)
@ -222,12 +204,8 @@ uint8_t DMRTX::writeShortLC(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Write abort data to the local buffer. */
/// Write abort data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t DMRTX::writeAbort(const uint8_t* data, uint8_t length) uint8_t DMRTX::writeAbort(const uint8_t* data, uint8_t length)
{ {
if (length != 1U) if (length != 1U)
@ -249,10 +227,8 @@ uint8_t DMRTX::writeAbort(const uint8_t* data, uint8_t length)
} }
} }
/// <summary> /* Helper to set the start state for Tx. */
/// Helper to set the start state for Tx.
/// </summary>
/// <param name="start"></param>
void DMRTX::setStart(bool start) void DMRTX::setStart(bool start)
{ {
m_state = start ? DMRTXSTATE_SLOT1 : DMRTXSTATE_IDLE; m_state = start ? DMRTXSTATE_SLOT1 : DMRTXSTATE_IDLE;
@ -265,37 +241,29 @@ void DMRTX::setStart(bool start)
m_abort[1U] = false; m_abort[1U] = false;
} }
/// <summary> /* Helper to set the calibration state for Tx. */
/// Helper to set the calibration state for Tx.
/// </summary>
/// <param name="start"></param>
void DMRTX::setCal(bool start) void DMRTX::setCal(bool start)
{ {
m_state = start ? DMRTXSTATE_CAL : DMRTXSTATE_IDLE; m_state = start ? DMRTXSTATE_CAL : DMRTXSTATE_IDLE;
} }
/// <summary> /* Helper to get how much space the slot 1 ring buffer has for samples. */
/// Helper to get how much space the slot 1 ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint8_t DMRTX::getSpace1() const uint8_t DMRTX::getSpace1() const
{ {
return m_fifo[0U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U); return m_fifo[0U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
} }
/// <summary> /* Helper to get how much space the slot 2 ring buffer has for samples. */
/// Helper to get how much space the slot 2 ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint8_t DMRTX::getSpace2() const uint8_t DMRTX::getSpace2() const
{ {
return m_fifo[1U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U); return m_fifo[1U].getSpace() / (DMR_FRAME_LENGTH_BYTES + 2U);
} }
/// <summary> /* Sets the ignore flags for setting the CACH Access Type bit. */
/// Sets the ignore flags for setting the CACH Access Type bit.
/// </summary>
/// <param name="slot"></param>
void DMRTX::setIgnoreCACH_AT(uint8_t slot) void DMRTX::setIgnoreCACH_AT(uint8_t slot)
{ {
m_cachATControl = slot; m_cachATControl = slot;
@ -304,10 +272,8 @@ void DMRTX::setIgnoreCACH_AT(uint8_t slot)
} }
} }
/// <summary> /* Sets the DMR color code. */
/// Sets the DMR color code.
/// </summary>
/// <param name="colorCode">Color code.</param>
void DMRTX::setColorCode(uint8_t colorCode) void DMRTX::setColorCode(uint8_t colorCode)
{ {
::memcpy(m_idle, IDLE_DATA, DMR_FRAME_LENGTH_BYTES); ::memcpy(m_idle, IDLE_DATA, DMR_FRAME_LENGTH_BYTES);
@ -316,26 +282,22 @@ void DMRTX::setColorCode(uint8_t colorCode)
slotType.encode(colorCode, DT_IDLE, m_idle); slotType.encode(colorCode, DT_IDLE, m_idle);
} }
/// <summary> /* Helper to reset data values to defaults for slot 1 FIFO. */
/// Helper to reset data values to defaults for slot 1 FIFO.
/// </summary>
void DMRTX::resetFifo1() void DMRTX::resetFifo1()
{ {
m_fifo[0U].reset(); m_fifo[0U].reset();
} }
/// <summary> /* Helper to reset data values to defaults for slot 2 FIFO. */
/// Helper to reset data values to defaults for slot 2 FIFO.
/// </summary>
void DMRTX::resetFifo2() void DMRTX::resetFifo2()
{ {
m_fifo[1U].reset(); m_fifo[1U].reset();
} }
/// <summary> /* Helper to resize the FIFO buffer. */
/// Helper to resize the FIFO buffer.
/// </summary>
/// <param name="size"></param>
void DMRTX::resizeBuffer(uint16_t size) void DMRTX::resizeBuffer(uint16_t size)
{ {
m_fifo[0U].reset(); m_fifo[0U].reset();
@ -344,10 +306,8 @@ void DMRTX::resizeBuffer(uint16_t size)
m_fifo[1U].reinitialize(size); m_fifo[1U].reinitialize(size);
} }
/// <summary> /* */
///
/// </summary>
/// <returns></returns>
uint32_t DMRTX::getFrameCount() uint32_t DMRTX::getFrameCount()
{ {
return m_frameCount; return m_frameCount;
@ -357,10 +317,8 @@ uint32_t DMRTX::getFrameCount()
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Helper to generate data. */
///
/// </summary>
/// <param name="slotIndex"></param>
void DMRTX::createData(uint8_t slotIndex) void DMRTX::createData(uint8_t slotIndex)
{ {
if (m_fifo[slotIndex].getData() > 0U && m_frameCount >= STARTUP_COUNT) { if (m_fifo[slotIndex].getData() > 0U && m_frameCount >= STARTUP_COUNT) {
@ -388,47 +346,8 @@ void DMRTX::createData(uint8_t slotIndex)
m_poPtr = 0U; m_poPtr = 0U;
} }
/// <summary> /* Helper to generate the common access channel. */
///
/// </summary>
void DMRTX::createCal()
{
// 1.2 kHz sine wave generation
if (m_modemState == STATE_DMR_CAL) {
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
m_poBuffer[i] = DMR_START_SYNC;
m_markBuffer[i] = MARK_NONE;
}
m_poLen = DMR_FRAME_LENGTH_BYTES;
}
// 80 Hz square wave generation
if (m_modemState == STATE_DMR_LF_CAL) {
for (unsigned int i = 0U; i < 7U; i++) {
m_poBuffer[i] = 0x55U; // +3, +3, ... pattern
m_markBuffer[i] = MARK_NONE;
}
m_poBuffer[7U] = 0x5FU; // +3, +3, -3, -3 pattern
for (unsigned int i = 8U; i < 15U; i++) {
m_poBuffer[i] = 0xFFU; // -3, -3, ... pattern
m_markBuffer[i] = MARK_NONE;
}
m_poLen = 15U;
}
m_poLen = DMR_FRAME_LENGTH_BYTES;
m_poPtr = 0U;
}
/// <summary>
///
/// </summary>
/// <param name="txSlotIndex"></param>
/// <param name="rxSlotIndex"></param>
void DMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex) void DMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex)
{ {
m_frameCount++; m_frameCount++;
@ -488,11 +407,43 @@ void DMRTX::createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex)
m_cachPtr += 3U; m_cachPtr += 3U;
} }
/// <summary> /* Helper to generate calibration data. */
///
/// </summary> void DMRTX::createCal()
/// <param name="c"></param> {
/// <param name="control"></param> // 1.2 kHz sine wave generation
if (m_modemState == STATE_DMR_CAL) {
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++) {
m_poBuffer[i] = DMR_START_SYNC;
m_markBuffer[i] = MARK_NONE;
}
m_poLen = DMR_FRAME_LENGTH_BYTES;
}
// 80 Hz square wave generation
if (m_modemState == STATE_DMR_LF_CAL) {
for (unsigned int i = 0U; i < 7U; i++) {
m_poBuffer[i] = 0x55U; // +3, +3, ... pattern
m_markBuffer[i] = MARK_NONE;
}
m_poBuffer[7U] = 0x5FU; // +3, +3, -3, -3 pattern
for (unsigned int i = 8U; i < 15U; i++) {
m_poBuffer[i] = 0xFFU; // -3, -3, ... pattern
m_markBuffer[i] = MARK_NONE;
}
m_poLen = 15U;
}
m_poLen = DMR_FRAME_LENGTH_BYTES;
m_poPtr = 0U;
}
/* Helper to write a raw byte to the DAC. */
void DMRTX::writeByte(uint8_t c, uint8_t control) void DMRTX::writeByte(uint8_t c, uint8_t control)
{ {
uint8_t bit; uint8_t bit;

@ -1,19 +1,21 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2017 Andy Uribe, CA6JAU
* Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file DMRTX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup dmr_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file DMRTX.h
* * @ingroup dmr_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2016 Colin Durbridge, G4EML
* Copyright (C) 2017 Andy Uribe, CA6JAU
* Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__DMR_TX_H__) #if !defined(__DMR_TX_H__)
#define __DMR_TX_H__ #define __DMR_TX_H__
@ -27,62 +29,121 @@ namespace dmr
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief DMR Duplex Transmitter State
* @ingroup dmr_hfw
*/
enum DMRTXSTATE { enum DMRTXSTATE {
DMRTXSTATE_IDLE, DMRTXSTATE_IDLE, //! Idle
DMRTXSTATE_SLOT1, DMRTXSTATE_SLOT1, //! Slot 1
DMRTXSTATE_CACH1, DMRTXSTATE_CACH1, //! Common Access Channel 1
DMRTXSTATE_SLOT2, DMRTXSTATE_SLOT2, //! Slot 2
DMRTXSTATE_CACH2, DMRTXSTATE_CACH2, //! Common Access Channel 2
DMRTXSTATE_CAL DMRTXSTATE_CAL //! Calibration
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements receiver logic for duplex DMR mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements receiver logic for duplex DMR mode operation.
* @ingroup dmr_hfw
*/
class DSP_FW_API DMRTX { class DSP_FW_API DMRTX {
public: public:
/// <summary>Initializes a new instance of the DMRTX class.</summary> /**
* @brief Initializes a new instance of the DMRTX class.
*/
DMRTX(); DMRTX();
/// <summary>Process local buffer and transmit on the air interface.</summary> /**
* @brief Process local buffer and transmit on the air interface.
*/
void process(); void process();
/// <summary>Write slot 1 data to the local buffer.</summary> /**
* @brief Write slot 1 data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t writeData1(const uint8_t* data, uint8_t length); uint8_t writeData1(const uint8_t* data, uint8_t length);
/// <summary>Write slot 2 data to the local buffer.</summary> /**
* @brief Write slot 2 data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t writeData2(const uint8_t* data, uint8_t length); uint8_t writeData2(const uint8_t* data, uint8_t length);
/// <summary>Write short LC data to the local buffer.</summary> /**
* @brief Write short LC data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t writeShortLC(const uint8_t* data, uint8_t length); uint8_t writeShortLC(const uint8_t* data, uint8_t length);
/// <summary>Write abort data to the local buffer.</summary> /**
* @brief Write abort data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t writeAbort(const uint8_t* data, uint8_t length); uint8_t writeAbort(const uint8_t* data, uint8_t length);
/// <summary>Helper to set the start state for Tx.</summary> /**
* @brief Helper to set the start state for Tx.
* @param start
*/
void setStart(bool start); void setStart(bool start);
/// <summary>Helper to set the calibration state for Tx.</summary> /**
* @brief Helper to set the calibration state for Tx.
* @param start
*/
void setCal(bool start); void setCal(bool start);
/// <summary>Helper to get how much space the slot 1 ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the slot 1 ring buffer has for samples.
* @returns uint8_t Amount of space in the slot 1 ring buffer.
*/
uint8_t getSpace1() const; uint8_t getSpace1() const;
/// <summary>Helper to get how much space the slot 2 ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the slot 2 ring buffer has for samples.
* @returns uint8_t Amount of space in the slot 2 ring buffer.
*/
uint8_t getSpace2() const; uint8_t getSpace2() const;
/// <summary>Sets the ignore flags for setting the CACH Access Type bit.</summary> /**
* @brief Sets the ignore flags for setting the CACH Access Type bit.
* @param slot DMR slot number.
*/
void setIgnoreCACH_AT(uint8_t slot); void setIgnoreCACH_AT(uint8_t slot);
/// <summary>Sets the DMR color code.</summary> /**
* @brief Sets the DMR color code.
* @param colorCode Color code.
*/
void setColorCode(uint8_t colorCode); void setColorCode(uint8_t colorCode);
/// <summary>Helper to reset data values to defaults for slot 1 FIFO.</summary> /**
* @brief Helper to reset data values to defaults for slot 1 FIFO.
*/
void resetFifo1(); void resetFifo1();
/// <summary>Helper to reset data values to defaults for slot 2 FIFO.</summary> /**
* @brief Helper to reset data values to defaults for slot 2 FIFO.
*/
void resetFifo2(); void resetFifo2();
/// <summary>Helper to resize the FIFO buffer.</summary> /**
* @brief Helper to resize the FIFO buffer.
* @param size
*/
void resizeBuffer(uint16_t size); void resizeBuffer(uint16_t size);
/// <summary></summary> /**
* @brief
* @returns uint32_t
*/
uint32_t getFrameCount(); uint32_t getFrameCount();
private: private:
@ -111,14 +172,27 @@ namespace dmr
uint8_t m_controlPrev; uint8_t m_controlPrev;
/// <summary></summary> /**
* @brief Helper to generate data.
* @param slotIndex
*/
void createData(uint8_t slotIndex); void createData(uint8_t slotIndex);
/// <summary></summary> /**
* @brief Helper to generate the common access channel.
* @param txSlotIndex
* @param rxSlotIndex
*/
void createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex); void createCACH(uint8_t txSlotIndex, uint8_t rxSlotIndex);
/// <summary></summary> /**
* @brief Helper to generate calibration data.
*/
void createCal(); void createCal();
/// <summary></summary> /**
* @brief Helper to write a raw byte to the DAC.
* @param c Byte.
* @param control
*/
void writeByte(uint8_t c, uint8_t control); void writeByte(uint8_t c, uint8_t control);
}; };
} // namespace dmr } // namespace dmr

@ -1,17 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2018 Andy Uribe, CA6JAU
* @derivedfrom MMDVM (https://github.com/g4klx/MMDVM) * Copyright (C) 2020 Jonathan Naylor, G4KLX
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) *
* */
* Copyright (C) 2018 Andy Uribe, CA6JAU
* Copyright (C) 2020 Jonathan Naylor, G4KLX
*
*/
#include "Globals.h" #include "Globals.h"
#include "nxdn/CalNXDN.h" #include "nxdn/CalNXDN.h"
@ -56,9 +52,8 @@ const uint8_t NXDN_CAL1K[4][49] = {
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the CalNXDN class. */
/// Initializes a new instance of the CalNXDN class.
/// </summary>
CalNXDN::CalNXDN() : CalNXDN::CalNXDN() :
m_transmit(false), m_transmit(false),
m_state(NXDNCAL1K_IDLE), m_state(NXDNCAL1K_IDLE),
@ -67,9 +62,8 @@ CalNXDN::CalNXDN() :
/* stub */ /* stub */
} }
/// <summary> /* Process local state and transmit on the air interface. */
/// Process local state and transmit on the air interface.
/// </summary>
void CalNXDN::process() void CalNXDN::process()
{ {
if (m_transmit) { if (m_transmit) {
@ -104,12 +98,8 @@ void CalNXDN::process()
} }
} }
/// <summary> /* Write NXDN calibration data to the local buffer. */
/// Write P25 calibration data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t CalNXDN::write(const uint8_t* data, uint16_t length) uint8_t CalNXDN::write(const uint8_t* data, uint16_t length)
{ {
if (length != 1U) if (length != 1U)

@ -8,10 +8,16 @@
* @derivedfrom MMDVM (https://github.com/g4klx/MMDVM) * @derivedfrom MMDVM (https://github.com/g4klx/MMDVM)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
* Copyright (C) 2018 Andy Uribe, CA6JAU * Copyright (C) 2018 Andy Uribe, CA6JAU
* Copyright (C) 2020 Jonathan Naylor, G4KLX * Copyright (C) 2020 Jonathan Naylor, G4KLX
* *
*/ */
/**
* @file CalNXDN.h
* @ingroup nxdn_hfw
* @file CalNXDN.h
* @ingroup nxdn_hfw
*/
#if !defined(__CAL_NXDN_H__) #if !defined(__CAL_NXDN_H__)
#define __CAL_NXDN_H__ #define __CAL_NXDN_H__
@ -24,25 +30,41 @@ namespace nxdn
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Calibration States
* @ingroup nxdn_hfw
*/
enum NXDNCAL1K { enum NXDNCAL1K {
NXDNCAL1K_IDLE, NXDNCAL1K_IDLE, //! Idle
NXDNCAL1K_TX NXDNCAL1K_TX //! Transmit
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements logic for NXDN calibration mode.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements logic for NXDN calibration mode.
* @ingroup nxdn_hfw
*/
class DSP_FW_API CalNXDN { class DSP_FW_API CalNXDN {
public: public:
/// <summary>Initializes a new instance of the CalNXDN class.</summary> /**
* @brief Initializes a new instance of the CalNXDN class.
*/
CalNXDN(); CalNXDN();
/// <summary>Process local state and transmit on the air interface.</summary> /**
* @brief Process local state and transmit on the air interface.
*/
void process(); void process();
/// <summary>Write NXDN calibration state.</summary> /**
* @brief Write NXDN calibration state.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t write(const uint8_t* data, uint16_t length); uint8_t write(const uint8_t* data, uint16_t length);
private: private:

@ -1,16 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2016,2017,2018 Jonathan Naylor, G4KLX
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @defgroup nxdn_hfw Next Generation Digital Narrowband
* GPLv2 Open Source. Use is subject to license terms. * @brief Implementation for the NXDN standard.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @ingroup hotspot_fw
* *
* @package DVM / Hotspot Firmware * @file NXDNDefines.h
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * @ingroup nxdn_hfw
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) */
*
* Copyright (C) 2016,2017,2018 Jonathan Naylor, G4KLX
*
*/
#if !defined(__NXDN_DEFINES_H__) #if !defined(__NXDN_DEFINES_H__)
#define __NXDN_DEFINES_H__ #define __NXDN_DEFINES_H__
@ -22,6 +26,11 @@ namespace nxdn
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @addtogroup nxdn_hfw
* @{
*/
const uint32_t NXDN_RADIO_SYMBOL_LENGTH = 10U; // At 24 kHz sample rate const uint32_t NXDN_RADIO_SYMBOL_LENGTH = 10U; // At 24 kHz sample rate
const uint32_t NXDN_FRAME_LENGTH_BITS = 384U; const uint32_t NXDN_FRAME_LENGTH_BITS = 384U;
@ -54,6 +63,8 @@ namespace nxdn
// 538 = NXDN_FRAME_LENGTH_BYTES * 11 + 10 (BUFFER_LEN = NXDN_FRAME_LENGTH_BYTES * NO_OF_FRAMES) // 538 = NXDN_FRAME_LENGTH_BYTES * 11 + 10 (BUFFER_LEN = NXDN_FRAME_LENGTH_BYTES * NO_OF_FRAMES)
const uint32_t NXDN_TX_BUFFER_LEN = 538U; // 11 frames + pad const uint32_t NXDN_TX_BUFFER_LEN = 538U; // 11 frames + pad
/** @} */
} // namespace nxdn } // namespace nxdn
#endif // __NXDN_DEFINES_H__ #endif // __NXDN_DEFINES_H__

@ -1,17 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2018,2020 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2022 Bryan Biedenkapp, N2PLL
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) *
* */
* Copyright (C) 2009-2018,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "nxdn/NXDNRX.h" #include "nxdn/NXDNRX.h"
#include "Utils.h" #include "Utils.h"
@ -33,9 +29,8 @@ const uint16_t NOENDPTR = 9999U;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the NXDNRX class. */
/// Initializes a new instance of the NXDNRX class.
/// </summary>
NXDNRX::NXDNRX() : NXDNRX::NXDNRX() :
m_bitBuffer(0x00U), m_bitBuffer(0x00U),
m_outBuffer(), m_outBuffer(),
@ -48,9 +43,8 @@ NXDNRX::NXDNRX() :
m_buffer = m_outBuffer + 1U; m_buffer = m_outBuffer + 1U;
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void NXDNRX::reset() void NXDNRX::reset()
{ {
m_bitBuffer = 0x00U; m_bitBuffer = 0x00U;
@ -61,10 +55,8 @@ void NXDNRX::reset()
m_state = NXDNRXS_NONE; m_state = NXDNRXS_NONE;
} }
/// <summary> /* Sample NXDN bits from the air interface. */
/// Sample NXDN bits from the air interface.
/// </summary>
/// <param name="bit"></param>
void NXDNRX::databit(bool bit) void NXDNRX::databit(bool bit)
{ {
if (m_state == NXDNRXS_DATA) { if (m_state == NXDNRXS_DATA) {
@ -88,10 +80,8 @@ void NXDNRX::databit(bool bit)
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Helper to process NXDN data bits. */
/// Helper to process NXDN data bits.
/// </summary>
/// <param name="bit"></param>
void NXDNRX::processData(bool bit) void NXDNRX::processData(bool bit)
{ {
m_bitBuffer <<= 1; m_bitBuffer <<= 1;
@ -135,11 +125,8 @@ void NXDNRX::processData(bool bit)
} }
} }
/// <summary> /* Frame synchronization correlator. */
/// Frame synchronization correlator.
/// </summary>
/// <param name="first"></param>
/// <returns></returns>
bool NXDNRX::correlateSync(bool first) bool NXDNRX::correlateSync(bool first)
{ {
uint8_t maxErrs; uint8_t maxErrs;

@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2017,2018,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file NXDNRX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup nxdn_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file NXDNRX.h
* * @ingroup nxdn_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016,2017,2018,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__NXDN_RX_H__) #if !defined(__NXDN_RX_H__)
#define __NXDN_RX_H__ #define __NXDN_RX_H__
@ -24,25 +26,39 @@ namespace nxdn
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief NXDN Receiver State
* @ingroup nxdn_hfw
*/
enum NXDNRX_STATE { enum NXDNRX_STATE {
NXDNRXS_NONE, NXDNRXS_NONE, //! None
NXDNRXS_DATA NXDNRXS_DATA //! Data
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements receiver logic for DMR slots.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements receiver logic for NXDN mode operation.
* @ingroup nxdn_mfw
*/
class DSP_FW_API NXDNRX { class DSP_FW_API NXDNRX {
public: public:
/// <summary>Initializes a new instance of the NXDNRX class.</summary> /**
* @brief Initializes a new instance of the NXDNRX class.
*/
NXDNRX(); NXDNRX();
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
/// <summary>Sample NXDN bits from the air interface.</summary> /**
* @brief Sample NXDN bits from the air interface.
* @param bit
*/
void databit(bool bit); void databit(bool bit);
private: private:
@ -56,10 +72,16 @@ namespace nxdn
NXDNRX_STATE m_state; NXDNRX_STATE m_state;
/// <summary>Helper to process NXDN data bits.</summary> /**
* @brief Helper to process NXDN data bits.
* @param bit
*/
void processData(bool bit); void processData(bool bit);
/// <summary>Frame synchronization correlator.</summary> /**
* @brief Frame synchronization correlator.
* @param first
*/
bool correlateSync(bool first = false); bool correlateSync(bool first = false);
}; };
} // namespace nxdn } // namespace nxdn

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2009-2018,2020 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2017 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2022 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2009-2018,2020 Jonathan Naylor, G4KLX */
* Copyright (C) 2017 Andy Uribe, CA6JAU
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "nxdn/NXDNTX.h" #include "nxdn/NXDNTX.h"
#include "nxdn/NXDNDefines.h" #include "nxdn/NXDNDefines.h"
@ -23,9 +19,8 @@ using namespace nxdn;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the NXDNTX class. */
/// Initializes a new instance of the NXDNTX class.
/// </summary>
NXDNTX::NXDNTX() : NXDNTX::NXDNTX() :
m_fifo(NXDN_TX_BUFFER_LEN), m_fifo(NXDN_TX_BUFFER_LEN),
m_state(NXDNTXSTATE_NORMAL), m_state(NXDNTXSTATE_NORMAL),
@ -39,9 +34,8 @@ NXDNTX::NXDNTX() :
/* stub */ /* stub */
} }
/// <summary> /* Process local buffer and transmit on the air interface. */
/// Process local buffer and transmit on the air interface.
/// </summary>
void NXDNTX::process() void NXDNTX::process()
{ {
if (m_fifo.getData() == 0U && m_poLen == 0U && m_tailCnt > 0U && if (m_fifo.getData() == 0U && m_poLen == 0U && m_tailCnt > 0U &&
@ -97,12 +91,8 @@ void NXDNTX::process()
} }
} }
/// <summary> /* Write data to the local buffer. */
/// Write data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t NXDNTX::writeData(const uint8_t* data, uint16_t length) uint8_t NXDNTX::writeData(const uint8_t* data, uint16_t length)
{ {
if (length != (NXDN_FRAME_LENGTH_BYTES + 1U)) if (length != (NXDN_FRAME_LENGTH_BYTES + 1U))
@ -119,18 +109,15 @@ uint8_t NXDNTX::writeData(const uint8_t* data, uint16_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Clears the local buffer. */
/// Clears the local buffer.
/// </summary>
void NXDNTX::clear() void NXDNTX::clear()
{ {
m_fifo.reset(); m_fifo.reset();
} }
/// <summary> /* Sets the FDMA preamble count. */
/// Sets the FDMA preamble count.
/// </summary>
/// <param name="preambleCnt">Count of preambles.</param>
void NXDNTX::setPreambleCount(uint8_t preambleCnt) void NXDNTX::setPreambleCount(uint8_t preambleCnt)
{ {
m_preambleCnt = 300U + uint16_t(preambleCnt) * 6U; // 500ms + tx delay m_preambleCnt = 300U + uint16_t(preambleCnt) * 6U; // 500ms + tx delay
@ -140,38 +127,30 @@ void NXDNTX::setPreambleCount(uint8_t preambleCnt)
m_preambleCnt = 60U; m_preambleCnt = 60U;
} }
/// <summary> /* Sets the Tx hang time. */
/// Sets the Tx hang time.
/// </summary>
/// <param name="txHang">Transmit hang time in seconds.</param>
void NXDNTX::setTxHang(uint8_t txHang) void NXDNTX::setTxHang(uint8_t txHang)
{ {
m_txHang = txHang * NXDN_FIXED_TX_HANG; m_txHang = txHang * NXDN_FIXED_TX_HANG;
} }
/// <summary> /* Helper to set the calibration state for Tx. */
/// Helper to set the calibration state for Tx.
/// </summary>
/// <param name="start"></param>
void NXDNTX::setCal(bool start) void NXDNTX::setCal(bool start)
{ {
m_state = start ? NXDNTXSTATE_CAL : NXDNTXSTATE_NORMAL; m_state = start ? NXDNTXSTATE_CAL : NXDNTXSTATE_NORMAL;
} }
/// <summary> /* Helper to resize the FIFO buffer. */
/// Helper to resize the FIFO buffer.
/// </summary>
/// <param name="size"></param>
void NXDNTX::resizeBuffer(uint16_t size) void NXDNTX::resizeBuffer(uint16_t size)
{ {
m_fifo.reset(); m_fifo.reset();
m_fifo.reinitialize(size); m_fifo.reinitialize(size);
} }
/// <summary> /* Helper to get how much space the ring buffer has for samples. */
/// Helper to get how much space the ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint8_t NXDNTX::getSpace() const uint8_t NXDNTX::getSpace() const
{ {
return m_fifo.getSpace() / NXDN_FRAME_LENGTH_BYTES; return m_fifo.getSpace() / NXDN_FRAME_LENGTH_BYTES;
@ -181,9 +160,8 @@ uint8_t NXDNTX::getSpace() const
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Helper to generate data. */
///
/// </summary>
void NXDNTX::createData() void NXDNTX::createData()
{ {
if (!m_tx) { if (!m_tx) {
@ -204,10 +182,8 @@ void NXDNTX::createData()
m_poPtr = 0U; m_poPtr = 0U;
} }
/// <summary> /* Helper to write a raw byte to the DAC. */
///
/// </summary>
/// <param name="c"></param>
void NXDNTX::writeByte(uint8_t c) void NXDNTX::writeByte(uint8_t c)
{ {
uint8_t bit; uint8_t bit;
@ -223,9 +199,8 @@ void NXDNTX::writeByte(uint8_t c)
} }
} }
/// <summary> /* */
///
/// </summary>
void NXDNTX::writeSilence() void NXDNTX::writeSilence()
{ {
uint8_t bit; uint8_t bit;

@ -1,17 +1,19 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2017,2018,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file NXDNTX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup nxdn_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file NXDNTX.h
* * @ingroup nxdn_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016,2017,2018,2020 Jonathan Naylor, G4KLX
* Copyright (C) 2022 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__NXDN_TX_H__) #if !defined(__NXDN_TX_H__)
#define __NXDN_TX_H__ #define __NXDN_TX_H__
@ -26,41 +28,74 @@ namespace nxdn
#define NXDN_FIXED_TX_HANG 600 #define NXDN_FIXED_TX_HANG 600
/**
* @brief NXDN Transmitter States
* @ingroup nxdn_hfw
*/
enum NXDNTXSTATE { enum NXDNTXSTATE {
NXDNTXSTATE_NORMAL, NXDNTXSTATE_NORMAL, //! Normal
NXDNTXSTATE_CAL NXDNTXSTATE_CAL //! Calibration
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements transmitter logic for NXDN mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements transmitter logic for NXDN mode operation.
* @ingroup nxdn_hfw
*/
class DSP_FW_API NXDNTX { class DSP_FW_API NXDNTX {
public: public:
/// <summary>Initializes a new instance of the NXDNTX class.</summary> /**
* @brief Initializes a new instance of the NXDNTX class.
*/
NXDNTX(); NXDNTX();
/// <summary>Process local buffer and transmit on the air interface.</summary> /**
* @brief Process local buffer and transmit on the air interface.
*/
void process(); void process();
/// <summary>Write data to the local buffer.</summary> /**
* @brief Write data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t writeData(const uint8_t* data, uint16_t length); uint8_t writeData(const uint8_t* data, uint16_t length);
/// <summary>Clears the local buffer.</summary> /**
* @brief Clears the local buffer.
*/
void clear(); void clear();
/// <summary>Sets the FDMA preamble count.</summary> /**
* @brief Sets the FDMA preamble count.
* @param preambleCnt FDMA preamble count.
*/
void setPreambleCount(uint8_t preambleCnt); void setPreambleCount(uint8_t preambleCnt);
/// <summary>Sets the transmit hang time.</summary> /**
* @brief Sets the transmit hang time.
* @param txHang Transmit hang time.
*/
void setTxHang(uint8_t txHang); void setTxHang(uint8_t txHang);
/// <summary>Helper to set the calibration state for Tx.</summary> /**
* @brief Helper to set the calibration state for Tx.
* @param start
*/
void setCal(bool start); void setCal(bool start);
/// <summary>Helper to resize the FIFO buffer.</summary> /**
* @brief Helper to resize the FIFO buffer.
* @param size
*/
void resizeBuffer(uint16_t size); void resizeBuffer(uint16_t size);
/// <summary>Helper to get how much space the ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the ring buffer has for samples.
* @returns uint8_t Amount of space in ring buffer for samples.
*/
uint8_t getSpace() const; uint8_t getSpace() const;
private: private:
@ -76,12 +111,19 @@ namespace nxdn
uint32_t m_txHang; uint32_t m_txHang;
uint32_t m_tailCnt; uint32_t m_tailCnt;
/// <summary></summary> /**
* @brief Helper to generate data.
*/
void createData(); void createData();
/// <summary></summary> /**
* @brief Helper to write a raw byte to the DAC.
* @param c Byte.
*/
void writeByte(uint8_t c); void writeByte(uint8_t c);
/// <summary></summary> /**
* @brief
*/
void writeSilence(); void writeSilence();
}; };
} // namespace nxdn } // namespace nxdn

@ -1,16 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2018 Andy Uribe, CA6JAU
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) *
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) */
*
* Copyright (C) 2018 Andy Uribe, CA6JAU
*
*/
#include "Globals.h" #include "Globals.h"
#include "p25/CalP25.h" #include "p25/CalP25.h"
@ -54,9 +50,8 @@ unsigned char LDU2_1K[] = { 0x00,
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the CalP25 class. */
/// Initializes a new instance of the CalP25 class.
/// </summary>
CalP25::CalP25() : CalP25::CalP25() :
m_transmit(false), m_transmit(false),
m_state(P25CAL1K_IDLE) m_state(P25CAL1K_IDLE)
@ -64,9 +59,8 @@ CalP25::CalP25() :
/* stub */ /* stub */
} }
/// <summary> /* Process local state and transmit on the air interface. */
/// Process local state and transmit on the air interface.
/// </summary>
void CalP25::process() void CalP25::process()
{ {
if (m_modemState == STATE_P25_CAL) { if (m_modemState == STATE_P25_CAL) {
@ -106,12 +100,8 @@ void CalP25::process()
} }
} }
/// <summary> /* Write P25 calibration data to the local buffer. */
/// Write P25 calibration data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t CalP25::write(const uint8_t* data, uint8_t length) uint8_t CalP25::write(const uint8_t* data, uint8_t length)
{ {
if (length != 1U) if (length != 1U)

@ -8,9 +8,15 @@
* @derivedfrom MMDVM (https://github.com/g4klx/MMDVM) * @derivedfrom MMDVM (https://github.com/g4klx/MMDVM)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
* Copyright (C) 2018 Andy Uribe, CA6JAU * Copyright (C) 2018 Andy Uribe, CA6JAU
* *
*/ */
/**
* @file CalP25.h
* @ingroup p25_hfw
* @file CalP25.h
* @ingroup p25_hfw
*/
#if !defined(__CAL_P25_H__) #if !defined(__CAL_P25_H__)
#define __CAL_P25_H__ #define __CAL_P25_H__
@ -23,26 +29,42 @@ namespace p25
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Calibration States
* @ingroup p25_hfw
*/
enum P25CAL1K { enum P25CAL1K {
P25CAL1K_IDLE, P25CAL1K_IDLE, //! Idle
P25CAL1K_LDU1, P25CAL1K_LDU1, //! LDU1
P25CAL1K_LDU2 P25CAL1K_LDU2 //! LDU2
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements logic for P25 calibration mode.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements logic for P25 calibration mode.
* @ingroup p25_hfw
*/
class DSP_FW_API CalP25 { class DSP_FW_API CalP25 {
public: public:
/// <summary>Initializes a new instance of the CalP25 class.</summary> /**
* @brief Initializes a new instance of the CalP25 class.
*/
CalP25(); CalP25();
/// <summary>Process local state and transmit on the air interface.</summary> /**
* @brief Process local state and transmit on the air interface.
*/
void process(); void process();
/// <summary>Write P25 calibration state.</summary> /**
* @brief Write P25 calibration state.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t write(const uint8_t* data, uint8_t length); uint8_t write(const uint8_t* data, uint8_t length);
private: private:

@ -1,18 +1,22 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2009-2016 Jonathan Naylor, G4KLX
* Copyright (C) 2018 Andy Uribe, CA6JAU
* Copyright (C) 2017-2024 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @defgroup p25_hfw Project 25
* GPLv2 Open Source. Use is subject to license terms. * @brief Implementation for the TIA-102 Project 25 standard.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @ingroup hotspot_fw
* *
* @package DVM / Hotspot Firmware * @file P25Defines.h
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * @ingroup p25_hfw
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) */
*
* Copyright (C) 2009-2016 Jonathan Naylor, G4KLX
* Copyright (C) 2018 Andy Uribe, CA6JAU
* Copyright (C) 2017-2024 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__P25_DEFINES_H__) #if !defined(__P25_DEFINES_H__)
#define __P25_DEFINES_H__ #define __P25_DEFINES_H__
@ -24,6 +28,11 @@ namespace p25
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @addtogroup p25_hfw
* @{
*/
const uint32_t P25_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate const uint32_t P25_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
const uint32_t P25_HDU_FRAME_LENGTH_BYTES = 99U; const uint32_t P25_HDU_FRAME_LENGTH_BYTES = 99U;
@ -99,6 +108,8 @@ namespace p25
const uint8_t P25_DUID_LDU2 = 0x0AU; // Logical Link Data Unit 2 const uint8_t P25_DUID_LDU2 = 0x0AU; // Logical Link Data Unit 2
const uint8_t P25_DUID_PDU = 0x0CU; // Packet Data Unit const uint8_t P25_DUID_PDU = 0x0CU; // Packet Data Unit
const uint8_t P25_DUID_TDULC = 0x0FU; // Terminator Data Unit with Link Control const uint8_t P25_DUID_TDULC = 0x0FU; // Terminator Data Unit with Link Control
/** @} */
} // namespace p25 } // namespace p25
#endif // __P25_DEFINES_H__ #endif // __P25_DEFINES_H__

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2016,2017 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2021-2024 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2016,2017 Jonathan Naylor, G4KLX */
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021-2024 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "p25/P25RX.h" #include "p25/P25RX.h"
#include "Utils.h" #include "Utils.h"
@ -34,9 +30,8 @@ const uint16_t NOENDPTR = 9999U;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the P25RX class. */
/// Initializes a new instance of the P25RX class.
/// </summary>
P25RX::P25RX() : P25RX::P25RX() :
m_bitBuffer(0x00U), m_bitBuffer(0x00U),
m_buffer(), m_buffer(),
@ -51,9 +46,8 @@ P25RX::P25RX() :
::memset(m_buffer, 0x00U, P25_LDU_FRAME_LENGTH_BYTES + 3U); ::memset(m_buffer, 0x00U, P25_LDU_FRAME_LENGTH_BYTES + 3U);
} }
/// <summary> /* Helper to reset data values to defaults. */
/// Helper to reset data values to defaults.
/// </summary>
void P25RX::reset() void P25RX::reset()
{ {
m_bitBuffer = 0x00U; m_bitBuffer = 0x00U;
@ -71,10 +65,8 @@ void P25RX::reset()
m_duid = 0xFFU; m_duid = 0xFFU;
} }
/// <summary> /* Sample P25 bits from the air interface. */
/// Sample P25 bits from the air interface.
/// </summary>
/// <param name="bit"></param>
void P25RX::databit(bool bit) void P25RX::databit(bool bit)
{ {
m_bitBuffer <<= 1; m_bitBuffer <<= 1;
@ -116,10 +108,8 @@ void P25RX::databit(bool bit)
} }
} }
/// <summary> /* Sets the P25 NAC. */
/// Sets the P25 NAC.
/// </summary>
/// <param name="nac">NAC.</param>
void P25RX::setNAC(uint16_t nac) void P25RX::setNAC(uint16_t nac)
{ {
m_nac = nac; m_nac = nac;
@ -129,10 +119,8 @@ void P25RX::setNAC(uint16_t nac)
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Helper to process P25 samples. */
/// Helper to process P25 samples.
/// </summary>
/// <param name="bit"></param>
void P25RX::processBit(bool bit) void P25RX::processBit(bool bit)
{ {
// process NID // process NID
@ -227,10 +215,8 @@ void P25RX::processBit(bool bit)
} }
} }
/// <summary> /* Helper to process LDU P25 bits. */
/// Helper to process LDU P25 bits.
/// </summary>
/// <param name="bit"></param>
void P25RX::processVoice(bool bit) void P25RX::processVoice(bool bit)
{ {
// only search for a sync in the right place +-2 bits // only search for a sync in the right place +-2 bits
@ -323,10 +309,8 @@ void P25RX::processVoice(bool bit)
} }
} }
/// <summary> /* Helper to process PDU P25 bits. */
/// Helper to process PDU P25 bits.
/// </summary>
/// <param name="bit"></param>
void P25RX::processData(bool bit) void P25RX::processData(bool bit)
{ {
// only search for a sync in the right place +-2 bits // only search for a sync in the right place +-2 bits
@ -384,10 +368,8 @@ void P25RX::processData(bool bit)
} }
} }
/// <summary> /* Frame synchronization correlator. */
/// Frame synchronization correlator.
/// </summary>
/// <returns></returns>
bool P25RX::correlateSync() bool P25RX::correlateSync()
{ {
uint8_t maxErrs; uint8_t maxErrs;
@ -439,9 +421,8 @@ bool P25RX::correlateSync()
return false; return false;
} }
/// <summary> /* Helper to decode the P25 NID. */
/// Helper to decode the P25 NID.
/// </summary>
bool P25RX::decodeNid() bool P25RX::decodeNid()
{ {
uint8_t nid[P25_NID_LENGTH_BYTES]; uint8_t nid[P25_NID_LENGTH_BYTES];

@ -1,18 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021-2024 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file P25RX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup p25_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file P25RX.h
* * @ingroup p25_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017,2018 Andy Uribe, CA6JAU
* Copyright (C) 2021-2024 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__P25_RX_H__) #if !defined(__P25_RX_H__)
#define __P25_RX_H__ #define __P25_RX_H__
@ -25,30 +27,47 @@ namespace p25
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief P25 Receiver State
* @ingroup p25_hfw
*/
enum P25RX_STATE { enum P25RX_STATE {
P25RXS_NONE, P25RXS_NONE, //! None
P25RXS_SYNC, P25RXS_SYNC, //! Found Sync
P25RXS_VOICE, P25RXS_VOICE, //! Voice Data
P25RXS_DATA P25RXS_DATA //! PDU Data
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements receiver logic for P25 mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements receiver logic for P25 mode operation.
* @ingroup p25_hfw
*/
class DSP_FW_API P25RX { class DSP_FW_API P25RX {
public: public:
/// <summary>Initializes a new instance of the P25RX class.</summary> /**
* @brief Initializes a new instance of the P25RX class.
*/
P25RX(); P25RX();
/// <summary>Helper to reset data values to defaults.</summary> /**
* @brief Helper to reset data values to defaults.
*/
void reset(); void reset();
/// <summary>Sample P25 bits from the air interface.</summary> /**
* @brief Sample P25 bits from the air interface.
* @param bit
*/
void databit(bool bit); void databit(bool bit);
/// <summary>Sets the P25 NAC.</summary> /**
* @brief Sets the P25 NAC.
* @param nac Network Access Code.
*/
void setNAC(uint16_t nac); void setNAC(uint16_t nac);
private: private:
@ -68,17 +87,32 @@ namespace p25
uint8_t m_duid; uint8_t m_duid;
/// <summary>Helper to process P25 bits.</summary> /**
* @brief Helper to process P25 bits.
* @param bit
*/
void processBit(bool bit); void processBit(bool bit);
/// <summary>Helper to process LDU P25 bits.</summary> /**
* @brief Helper to process LDU P25 bits.
* @param bit
*/
void processVoice(bool bit); void processVoice(bool bit);
/// <summary>Helper to process PDU P25 bits.</summary> /**
* @brief Helper to process PDU P25 bits.
* @param bit
*/
void processData(bool bit); void processData(bool bit);
/// <summary>Frame synchronization correlator.</summary> /**
* @brief Frame synchronization correlator.
* @returns bool
*/
bool correlateSync(); bool correlateSync();
/// <summary>Helper to decode the P25 NID.</summary> /**
* @brief Helper to decode the P25 NID.
* @returns bool True, if P25 NID was decoded, otherwise false.
*/
bool decodeNid(); bool decodeNid();
}; };
} // namespace p25 } // namespace p25

@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /*
* Digital Voice Modem - Hotspot Firmware * Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / Hotspot Firmware * Copyright (C) 2016 Jonathan Naylor, G4KLX
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS) * Copyright (C) 2016,2017 Andy Uribe, CA6JAU
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
* *
* Copyright (C) 2016 Jonathan Naylor, G4KLX */
* Copyright (C) 2016,2017 Andy Uribe, CA6JAU
* Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
*
*/
#include "Globals.h" #include "Globals.h"
#include "p25/P25TX.h" #include "p25/P25TX.h"
#include "p25/P25Defines.h" #include "p25/P25Defines.h"
@ -23,9 +19,8 @@ using namespace p25;
// Public Class Members // Public Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Initializes a new instance of the P25TX class. */
/// Initializes a new instance of the P25TX class.
/// </summary>
P25TX::P25TX() : P25TX::P25TX() :
m_fifo(P25_TX_BUFFER_LEN), m_fifo(P25_TX_BUFFER_LEN),
m_state(P25TXSTATE_NORMAL), m_state(P25TXSTATE_NORMAL),
@ -39,9 +34,8 @@ P25TX::P25TX() :
/* stub */ /* stub */
} }
/// <summary> /* Process local buffer and transmit on the air interface. */
/// Process local buffer and transmit on the air interface.
/// </summary>
void P25TX::process() void P25TX::process()
{ {
if (m_fifo.getData() == 0U && m_poLen == 0U && m_tailCnt > 0U && if (m_fifo.getData() == 0U && m_poLen == 0U && m_tailCnt > 0U &&
@ -100,12 +94,8 @@ void P25TX::process()
} }
} }
/// <summary> /* Write data to the local buffer. */
/// Write data to the local buffer.
/// </summary>
/// <param name="data"></param>
/// <param name="length"></param>
/// <returns></returns>
uint8_t P25TX::writeData(const uint8_t* data, uint8_t length) uint8_t P25TX::writeData(const uint8_t* data, uint8_t length)
{ {
if (length < (P25_TDU_FRAME_LENGTH_BYTES + 1U)) if (length < (P25_TDU_FRAME_LENGTH_BYTES + 1U))
@ -125,18 +115,15 @@ uint8_t P25TX::writeData(const uint8_t* data, uint8_t length)
return RSN_OK; return RSN_OK;
} }
/// <summary> /* Clears the local buffer. */
/// Clears the local buffer.
/// </summary>
void P25TX::clear() void P25TX::clear()
{ {
m_fifo.reset(); m_fifo.reset();
} }
/// <summary> /* Sets the FDMA preamble count. */
/// Sets the FDMA preamble count.
/// </summary>
/// <param name="preambleCnt">Count of preambles.</param>
void P25TX::setPreambleCount(uint8_t preambleCnt) void P25TX::setPreambleCount(uint8_t preambleCnt)
{ {
m_preambleCnt = P25_FIXED_DELAY + preambleCnt; m_preambleCnt = P25_FIXED_DELAY + preambleCnt;
@ -146,10 +133,8 @@ void P25TX::setPreambleCount(uint8_t preambleCnt)
m_preambleCnt = 1200U; m_preambleCnt = 1200U;
} }
/// <summary> /* Sets the Tx hang time. */
/// Sets the Tx hang time.
/// </summary>
/// <param name="txHang">Transmit hang time in seconds.</param>
void P25TX::setTxHang(uint8_t txHang) void P25TX::setTxHang(uint8_t txHang)
{ {
if (txHang > 0U) if (txHang > 0U)
@ -162,29 +147,23 @@ void P25TX::setTxHang(uint8_t txHang)
m_txHang = 13U * 1200U; m_txHang = 13U * 1200U;
} }
/// <summary> /* Helper to set the calibration state for Tx. */
/// Helper to set the calibration state for Tx.
/// </summary>
/// <param name="start"></param>
void P25TX::setCal(bool start) void P25TX::setCal(bool start)
{ {
m_state = start ? P25TXSTATE_CAL : P25TXSTATE_NORMAL; m_state = start ? P25TXSTATE_CAL : P25TXSTATE_NORMAL;
} }
/// <summary> /* Helper to resize the FIFO buffer. */
/// Helper to resize the FIFO buffer.
/// </summary>
/// <param name="size"></param>
void P25TX::resizeBuffer(uint16_t size) void P25TX::resizeBuffer(uint16_t size)
{ {
m_fifo.reset(); m_fifo.reset();
m_fifo.reinitialize(size); m_fifo.reinitialize(size);
} }
/// <summary> /* Helper to get how much space the ring buffer has for samples. */
/// Helper to get how much space the ring buffer has for samples.
/// </summary>
/// <returns></returns>
uint8_t P25TX::getSpace() const uint8_t P25TX::getSpace() const
{ {
return m_fifo.getSpace() / P25_LDU_FRAME_LENGTH_BYTES; return m_fifo.getSpace() / P25_LDU_FRAME_LENGTH_BYTES;
@ -194,9 +173,8 @@ uint8_t P25TX::getSpace() const
// Private Class Members // Private Class Members
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /* Helper to generate data. */
///
/// </summary>
void P25TX::createData() void P25TX::createData()
{ {
if (!m_tx) { if (!m_tx) {
@ -214,9 +192,8 @@ void P25TX::createData()
m_poPtr = 0U; m_poPtr = 0U;
} }
/// <summary> /* Helper to generate calibration data. */
///
/// </summary>
void P25TX::createCal() void P25TX::createCal()
{ {
// 1.2 kHz sine wave generation // 1.2 kHz sine wave generation
@ -232,10 +209,8 @@ void P25TX::createCal()
m_poPtr = 0U; m_poPtr = 0U;
} }
/// <summary> /* Helper to write a raw byte to the DAC. */
///
/// </summary>
/// <param name="c"></param>
void P25TX::writeByte(uint8_t c) void P25TX::writeByte(uint8_t c)
{ {
uint8_t bit; uint8_t bit;
@ -251,9 +226,8 @@ void P25TX::writeByte(uint8_t c)
} }
} }
/// <summary> /* */
///
/// </summary>
void P25TX::writeSilence() void P25TX::writeSilence()
{ {
uint8_t bit; uint8_t bit;

@ -1,18 +1,20 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Hotspot Firmware
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017 Andy Uribe, CA6JAU
* Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
*
*/
/** /**
* Digital Voice Modem - Hotspot Firmware * @file P25TX.h
* GPLv2 Open Source. Use is subject to license terms. * @ingroup p25_hfw
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @file P25TX.h
* * @ingroup p25_hfw
* @package DVM / Hotspot Firmware */
* @derivedfrom MMDVM_HS (https://github.com/g4klx/MMDVM_HS)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2016,2017 Jonathan Naylor, G4KLX
* Copyright (C) 2016,2017 Andy Uribe, CA6JAU
* Copyright (C) 2021-2022 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__P25_TX_H__) #if !defined(__P25_TX_H__)
#define __P25_TX_H__ #define __P25_TX_H__
@ -28,41 +30,74 @@ namespace p25
#define P25_FIXED_DELAY 90 // 90 = 20ms #define P25_FIXED_DELAY 90 // 90 = 20ms
#define P25_FIXED_TX_HANG 750 // 750 = 625ms #define P25_FIXED_TX_HANG 750 // 750 = 625ms
/**
* @brief P25 Transmitter State
* @ingroup p25_hfw
*/
enum P25TXSTATE { enum P25TXSTATE {
P25TXSTATE_NORMAL, P25TXSTATE_NORMAL, //! Normal
P25TXSTATE_CAL P25TXSTATE_CAL //! Calibration
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Class Declaration // Class Declaration
// Implements transmitter logic for P25 mode operation.
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/**
* @brief Implements transmitter logic for P25 mode operation.
* @ingroup p25_hfw
*/
class DSP_FW_API P25TX { class DSP_FW_API P25TX {
public: public:
/// <summary>Initializes a new instance of the P25TX class.</summary> /**
* @brief Initializes a new instance of the P25TX class.
*/
P25TX(); P25TX();
/// <summary>Process local buffer and transmit on the air interface.</summary> /**
* @brief Process local buffer and transmit on the air interface.
*/
void process(); void process();
/// <summary>Write data to the local buffer.</summary> /**
* @brief Write data to the local buffer.
* @param[in] data Buffer.
* @param length Length of buffer.
* @returns uint8_t Reason code.
*/
uint8_t writeData(const uint8_t* data, uint8_t length); uint8_t writeData(const uint8_t* data, uint8_t length);
/// <summary>Clears the local buffer.</summary> /**
* @brief Clears the local buffer.
*/
void clear(); void clear();
/// <summary>Sets the FDMA preamble count.</summary> /**
* @brief Sets the FDMA preamble count.
* @param preambleCnt FDMA preamble count.
*/
void setPreambleCount(uint8_t preambleCnt); void setPreambleCount(uint8_t preambleCnt);
/// <summary>Sets the transmit hang time.</summary> /**
* @brief Sets the transmit hang time.
* @param txHang Transmit hang time.
*/
void setTxHang(uint8_t txHang); void setTxHang(uint8_t txHang);
/// <summary>Helper to set the calibration state for Tx.</summary> /**
* @brief Helper to set the calibration state for Tx.
* @param start
*/
void setCal(bool start); void setCal(bool start);
/// <summary>Helper to resize the FIFO buffer.</summary> /**
* @brief Helper to resize the FIFO buffer.
* @param size
*/
void resizeBuffer(uint16_t size); void resizeBuffer(uint16_t size);
/// <summary>Helper to get how much space the ring buffer has for samples.</summary> /**
* @brief Helper to get how much space the ring buffer has for samples.
* @returns uint8_t Amount of space in ring buffer for samples.
*/
uint8_t getSpace() const; uint8_t getSpace() const;
private: private:
@ -78,14 +113,23 @@ namespace p25
uint32_t m_txHang; uint32_t m_txHang;
uint32_t m_tailCnt; uint32_t m_tailCnt;
/// <summary></summary> /**
* @brief Helper to generate data.
*/
void createData(); void createData();
/// <summary></summary> /**
* @brief Helper to generate calibration data.
*/
void createCal(); void createCal();
/// <summary></summary> /**
* @brief Helper to write a raw byte to the DAC.
* @param c Byte.
*/
void writeByte(uint8_t c); void writeByte(uint8_t c);
/// <summary></summary> /**
* @brief
*/
void writeSilence(); void writeSilence();
}; };
} // namespace p25 } // namespace p25

Loading…
Cancel
Save

Powered by TurnKey Linux.