mirror of https://github.com/g4klx/MMDVM.git
commit
c84dbd02e5
46
FM.cpp
46
FM.cpp
|
@ -51,13 +51,14 @@ m_useCOS(true),
|
|||
m_cosInvert(false),
|
||||
m_rfAudioBoost(1U),
|
||||
m_extAudioBoost(1U),
|
||||
m_downsampler(128U), //Size might need adjustement
|
||||
m_downsampler(128U),//Size might need adjustement
|
||||
m_extEnabled(false),
|
||||
m_rxLevel(1)
|
||||
m_rxLevel(1),
|
||||
m_outputRB(2400U) // 100ms of audio
|
||||
{
|
||||
}
|
||||
|
||||
void CFM::samples(bool cos, q15_t* samples, uint8_t length)
|
||||
void CFM::samples(bool cos, const q15_t* samples, uint8_t length)
|
||||
{
|
||||
if (m_useCOS) {
|
||||
if (m_cosInvert)
|
||||
|
@ -135,15 +136,34 @@ void CFM::samples(bool cos, q15_t* samples, uint8_t length)
|
|||
|
||||
currentSample += m_ctcssTX.getAudio();
|
||||
|
||||
samples[i] = currentSample;
|
||||
if (m_modemState == STATE_FM)
|
||||
m_outputRB.put(currentSample);
|
||||
}
|
||||
|
||||
if (m_modemState == STATE_FM)
|
||||
io.write(STATE_FM, samples, i);//only write the actual number of processed samples to IO
|
||||
}
|
||||
|
||||
void CFM::process()
|
||||
{
|
||||
if (m_modemState != STATE_FM)
|
||||
return;
|
||||
|
||||
uint16_t length = m_outputRB.getData();
|
||||
if (length == 0U)
|
||||
return;
|
||||
|
||||
uint16_t space = io.getSpace();
|
||||
if (space < 3U)
|
||||
return;
|
||||
|
||||
space -= 2U;
|
||||
|
||||
if (space < length)
|
||||
length = space;
|
||||
|
||||
for (uint16_t i = 0U; i < length; i++) {
|
||||
q15_t sample;
|
||||
m_outputRB.get(sample);
|
||||
io.write(STATE_FM, &sample, 1U);
|
||||
}
|
||||
}
|
||||
|
||||
void CFM::reset()
|
||||
|
@ -162,6 +182,8 @@ void CFM::reset()
|
|||
m_extAck.stop();
|
||||
m_callsign.stop();
|
||||
m_timeoutTone.stop();
|
||||
|
||||
m_outputRB.reset();
|
||||
}
|
||||
|
||||
uint8_t CFM::setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t highLevel, uint8_t lowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch)
|
||||
|
@ -328,6 +350,8 @@ void CFM::listeningState(bool validRFSignal, bool validExtSignal)
|
|||
sendCallsign();
|
||||
}
|
||||
|
||||
insertSilence(50U);
|
||||
|
||||
beginRelaying();
|
||||
|
||||
m_callsignTimer.start();
|
||||
|
@ -664,3 +688,11 @@ uint8_t CFM::writeData(const uint8_t* data, uint8_t length)
|
|||
|
||||
return 0U;
|
||||
}
|
||||
|
||||
void CFM::insertSilence(uint16_t ms)
|
||||
{
|
||||
uint32_t nSamples = ms * 24U;
|
||||
|
||||
for (uint32_t i = 0U; i < nSamples; i++)
|
||||
m_outputRB.put(0);
|
||||
}
|
||||
|
|
5
FM.h
5
FM.h
|
@ -27,6 +27,7 @@
|
|||
#include "FMTimeout.h"
|
||||
#include "FMKeyer.h"
|
||||
#include "FMTimer.h"
|
||||
#include "FMRB.h"
|
||||
#include "FMDirectForm1.h"
|
||||
#include "FMDownsampler.h"
|
||||
|
||||
|
@ -50,7 +51,7 @@ class CFM {
|
|||
public:
|
||||
CFM();
|
||||
|
||||
void samples(bool cos, q15_t* samples, uint8_t length);
|
||||
void samples(bool cos, const q15_t* samples, uint8_t length);
|
||||
|
||||
void process();
|
||||
|
||||
|
@ -94,6 +95,7 @@ private:
|
|||
CFMDownsampler m_downsampler;
|
||||
bool m_extEnabled;
|
||||
q15_t m_rxLevel;
|
||||
CFMRB m_outputRB;
|
||||
|
||||
void stateMachine(bool validRFSignal, bool validExtSignal);
|
||||
void listeningState(bool validRFSignal, bool validExtSignal);
|
||||
|
@ -113,6 +115,7 @@ private:
|
|||
|
||||
void sendCallsign();
|
||||
void beginRelaying();
|
||||
void insertSilence(uint16_t ms);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(FMRB_H)
|
||||
#define FMRB_H
|
||||
#if !defined(FMDOWNSAMPLERB_H)
|
||||
#define FMDOWNSAMPLERB_H
|
||||
|
||||
#if defined(STM32F4XX)
|
||||
#include "stm32f4xx.h"
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
TX fifo control - Copyright (C) KI6ZUM 2015
|
||||
Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "FMRB.h"
|
||||
|
||||
CFMRB::CFMRB(uint16_t length) :
|
||||
m_length(length),
|
||||
m_head(0U),
|
||||
m_tail(0U),
|
||||
m_full(false),
|
||||
m_overflow(false)
|
||||
{
|
||||
m_samples = new q15_t[length];
|
||||
}
|
||||
|
||||
uint16_t CFMRB::getSpace() const
|
||||
{
|
||||
uint16_t n = 0U;
|
||||
|
||||
if (m_tail == m_head)
|
||||
n = m_full ? 0U : m_length;
|
||||
else if (m_tail < m_head)
|
||||
n = m_length - m_head + m_tail;
|
||||
else
|
||||
n = m_tail - m_head;
|
||||
|
||||
if (n > m_length)
|
||||
n = 0U;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
uint16_t CFMRB::getData() const
|
||||
{
|
||||
if (m_tail == m_head)
|
||||
return m_full ? m_length : 0U;
|
||||
else if (m_tail < m_head)
|
||||
return m_head - m_tail;
|
||||
else
|
||||
return m_length - m_tail + m_head;
|
||||
}
|
||||
|
||||
bool CFMRB::put(q15_t sample)
|
||||
{
|
||||
if (m_full) {
|
||||
m_overflow = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_samples[m_head] = sample;
|
||||
|
||||
m_head++;
|
||||
if (m_head >= m_length)
|
||||
m_head = 0U;
|
||||
|
||||
if (m_head == m_tail)
|
||||
m_full = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFMRB::get(q15_t& sample)
|
||||
{
|
||||
if (m_head == m_tail && !m_full)
|
||||
return false;
|
||||
|
||||
sample = m_samples[m_tail];
|
||||
|
||||
m_full = false;
|
||||
|
||||
m_tail++;
|
||||
if (m_tail >= m_length)
|
||||
m_tail = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFMRB::hasOverflowed()
|
||||
{
|
||||
bool overflow = m_overflow;
|
||||
|
||||
m_overflow = false;
|
||||
|
||||
return overflow;
|
||||
}
|
||||
|
||||
void CFMRB::reset()
|
||||
{
|
||||
m_head = 0U;
|
||||
m_tail = 0U;
|
||||
m_full = false;
|
||||
m_overflow = false;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Serial fifo control - Copyright (C) KI6ZUM 2015
|
||||
Copyright (C) 2015,2016,2020 by Jonathan Naylor G4KLX
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#if !defined(FMRB_H)
|
||||
#define FMRB_H
|
||||
|
||||
#if defined(STM32F4XX)
|
||||
#include "stm32f4xx.h"
|
||||
#elif defined(STM32F7XX)
|
||||
#include "stm32f7xx.h"
|
||||
#elif defined(STM32F105xC)
|
||||
#include "stm32f1xx.h"
|
||||
#include <cstddef>
|
||||
#else
|
||||
#include <Arduino.h>
|
||||
#endif
|
||||
|
||||
#if defined(__SAM3X8E__) || defined(STM32F105xC)
|
||||
#define ARM_MATH_CM3
|
||||
#elif defined(STM32F7XX)
|
||||
#define ARM_MATH_CM7
|
||||
#elif defined(STM32F4XX) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
|
||||
#define ARM_MATH_CM4
|
||||
#else
|
||||
#error "Unknown processor type"
|
||||
#endif
|
||||
|
||||
#include <arm_math.h>
|
||||
|
||||
class CFMRB {
|
||||
public:
|
||||
CFMRB(uint16_t length);
|
||||
|
||||
uint16_t getSpace() const;
|
||||
|
||||
uint16_t getData() const;
|
||||
|
||||
bool put(q15_t sample);
|
||||
|
||||
bool get(q15_t& sample);
|
||||
|
||||
bool hasOverflowed();
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
uint16_t m_length;
|
||||
volatile q15_t* m_samples;
|
||||
volatile uint16_t m_head;
|
||||
volatile uint16_t m_tail;
|
||||
volatile bool m_full;
|
||||
bool m_overflow;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue