mirror of https://github.com/g4klx/MMDVM.git
Merge remote-tracking branch 'g4klx/master'
This commit is contained in:
commit
399b6e1d85
|
@ -3,3 +3,4 @@ obj/
|
|||
bin/
|
||||
STM32F4XX_Lib/
|
||||
GitVersion.h
|
||||
build/
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "CWIdTX.h"
|
||||
|
|
5
Config.h
5
Config.h
|
@ -60,11 +60,6 @@
|
|||
// Use separate mode pins to switch external filters/bandwidth for example
|
||||
// #define STM32F4_NUCLEO_MODE_PINS
|
||||
|
||||
// To use wider C4FSK filters for DMR, System Fusion and P25 on transmit
|
||||
// #define WIDE_C4FSK_FILTERS_TX
|
||||
// To use wider C4FSK filters for DMR, System Fusion and P25 on receive
|
||||
// #define WIDE_C4FSK_FILTERS_RX
|
||||
|
||||
// Pass RSSI information to the host
|
||||
// #define SEND_RSSI_DATA
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "DMRDMORX.h"
|
||||
|
|
102
DMRDMOTX.cpp
102
DMRDMOTX.cpp
|
@ -18,44 +18,20 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "DMRSlotType.h"
|
||||
|
||||
#if defined(WIDE_C4FSK_FILTERS_TX)
|
||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
||||
static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688}; // numTaps = 25, L = 5
|
||||
const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 5U; // phaseLength = numTaps/L
|
||||
#else
|
||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
||||
static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
||||
-553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5
|
||||
const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||
#endif
|
||||
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 850, 219, -720, -1548, -1795, -1172, 237, 1927, 3120, 3073, 1447, -1431, -4544, -6442,
|
||||
-5735, -1633, 5651, 14822, 23810, 30367, 32767, 30367, 23810, 14822, 5651, -1633, -5735, -6442,
|
||||
-4544, -1431, 1447, 3073, 3120, 1927, 237, -1172, -1795, -1548, -720, 219, 850}; // numTaps = 45, L = 5
|
||||
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||
|
||||
const q15_t DMR_LEVELA = 2889;
|
||||
const q15_t DMR_LEVELB = 963;
|
||||
const q15_t DMR_LEVELC = -963;
|
||||
const q15_t DMR_LEVELD = -2889;
|
||||
|
||||
// The PR FILL and BS Data Sync pattern.
|
||||
const uint8_t IDLE_DATA[] =
|
||||
{0x53U, 0xC2U, 0x5EU, 0xABU, 0xA8U, 0x67U, 0x1DU, 0xC7U, 0x38U, 0x3BU, 0xD9U,
|
||||
0x36U, 0x00U, 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U, 0x03U, 0xF6U,
|
||||
0xE4U, 0x65U, 0x17U, 0x1BU, 0x48U, 0xCAU, 0x6DU, 0x4FU, 0xC6U, 0x10U, 0xB4U};
|
||||
|
||||
const uint8_t CACH_INTERLEAVE[] =
|
||||
{1U, 2U, 3U, 5U, 6U, 7U, 9U, 10U, 11U, 13U, 15U, 16U, 17U, 19U, 20U, 21U, 23U,
|
||||
25U, 26U, 27U, 29U, 30U, 31U, 33U, 34U, 35U, 37U, 39U, 40U, 41U, 43U, 44U, 45U, 47U,
|
||||
49U, 50U, 51U, 53U, 54U, 55U, 57U, 58U, 59U, 61U, 63U, 64U, 65U, 67U, 68U, 69U, 71U,
|
||||
73U, 74U, 75U, 77U, 78U, 79U, 81U, 82U, 83U, 85U, 87U, 88U, 89U, 91U, 92U, 93U, 95U};
|
||||
|
||||
const uint8_t EMPTY_SHORT_LC[] =
|
||||
{0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||
const q15_t DMR_LEVELA = 1362;
|
||||
const q15_t DMR_LEVELB = 454;
|
||||
const q15_t DMR_LEVELC = -454;
|
||||
const q15_t DMR_LEVELD = -1362;
|
||||
|
||||
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
|
@ -71,16 +47,14 @@ m_modState(),
|
|||
m_poBuffer(),
|
||||
m_poLen(0U),
|
||||
m_poPtr(0U),
|
||||
m_txDelay(240U), // 200ms
|
||||
m_idle(),
|
||||
m_cachPtr(0U)
|
||||
m_txDelay(240U) // 200ms
|
||||
{
|
||||
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||
|
||||
m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = DMR_C4FSK_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = DMR_C4FSK_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = RRC_0_2_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
}
|
||||
|
||||
void CDMRDMOTX::process()
|
||||
|
@ -92,15 +66,11 @@ void CDMRDMOTX::process()
|
|||
|
||||
m_poLen = m_txDelay;
|
||||
} else {
|
||||
createCACH(m_poBuffer + 0U, 0U);
|
||||
for (unsigned int i = 0U; i < 72U; i++)
|
||||
m_poBuffer[i] = DMR_SYNC;
|
||||
|
||||
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++)
|
||||
m_poBuffer[i + 3U] = m_fifo.get();
|
||||
|
||||
createCACH(m_poBuffer + 36U, 1U);
|
||||
|
||||
for (unsigned int i = 0U; i < DMR_FRAME_LENGTH_BYTES; i++)
|
||||
m_poBuffer[i + 39U] = m_idle[i];
|
||||
m_poBuffer[i + 39U] = m_fifo.get();
|
||||
|
||||
m_poLen = 72U;
|
||||
}
|
||||
|
@ -184,43 +154,3 @@ void CDMRDMOTX::setTXDelay(uint8_t delay)
|
|||
m_txDelay = 1200U;
|
||||
}
|
||||
|
||||
void CDMRDMOTX::createCACH(uint8_t* buffer, uint8_t slotIndex)
|
||||
{
|
||||
if (m_cachPtr >= 12U)
|
||||
m_cachPtr = 0U;
|
||||
|
||||
::memcpy(buffer, EMPTY_SHORT_LC + m_cachPtr, 3U);
|
||||
|
||||
bool at = true;
|
||||
bool tc = slotIndex == 1U;
|
||||
bool ls0 = true; // For 1 and 2
|
||||
bool ls1 = true;
|
||||
|
||||
if (m_cachPtr == 0U) // For 0
|
||||
ls1 = false;
|
||||
else if (m_cachPtr == 9U) // For 3
|
||||
ls0 = false;
|
||||
|
||||
bool h0 = at ^ tc ^ ls1;
|
||||
bool h1 = tc ^ ls1 ^ ls0;
|
||||
bool h2 = at ^ tc ^ ls0;
|
||||
|
||||
buffer[0U] |= at ? 0x80U : 0x00U;
|
||||
buffer[0U] |= tc ? 0x08U : 0x00U;
|
||||
buffer[1U] |= ls1 ? 0x80U : 0x00U;
|
||||
buffer[1U] |= ls0 ? 0x08U : 0x00U;
|
||||
buffer[1U] |= h0 ? 0x02U : 0x00U;
|
||||
buffer[2U] |= h1 ? 0x20U : 0x00U;
|
||||
buffer[2U] |= h2 ? 0x02U : 0x00U;
|
||||
|
||||
m_cachPtr += 3U;
|
||||
}
|
||||
|
||||
void CDMRDMOTX::setColorCode(uint8_t colorCode)
|
||||
{
|
||||
::memcpy(m_idle, IDLE_DATA, DMR_FRAME_LENGTH_BYTES);
|
||||
|
||||
CDMRSlotType slotType;
|
||||
slotType.encode(colorCode, DT_IDLE, m_idle);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ public:
|
|||
|
||||
uint8_t getSpace() const;
|
||||
|
||||
void setColorCode(uint8_t colorCode);
|
||||
|
||||
private:
|
||||
CSerialRB m_fifo;
|
||||
arm_fir_interpolate_instance_q15 m_modFilter;
|
||||
|
@ -47,10 +45,7 @@ private:
|
|||
uint16_t m_poLen;
|
||||
uint16_t m_poPtr;
|
||||
uint32_t m_txDelay;
|
||||
uint8_t m_idle[DMR_FRAME_LENGTH_BYTES];
|
||||
uint8_t m_cachPtr;
|
||||
|
||||
void createCACH(uint8_t* buffer, uint8_t slotIndex);
|
||||
void writeByte(uint8_t c);
|
||||
};
|
||||
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "DMRIdleRX.h"
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "DMRSlotRX.h"
|
||||
|
|
33
DMRTX.cpp
33
DMRTX.cpp
|
@ -18,29 +18,20 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "DMRSlotType.h"
|
||||
|
||||
#if defined(WIDE_C4FSK_FILTERS_TX)
|
||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
||||
static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688}; // numTaps = 25, L = 5
|
||||
const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 5U; // phaseLength = numTaps/L
|
||||
#else
|
||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
||||
static q15_t DMR_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
||||
-553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5
|
||||
const uint16_t DMR_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||
#endif
|
||||
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 850, 219, -720, -1548, -1795, -1172, 237, 1927, 3120, 3073, 1447, -1431, -4544, -6442,
|
||||
-5735, -1633, 5651, 14822, 23810, 30367, 32767, 30367, 23810, 14822, 5651, -1633, -5735, -6442,
|
||||
-4544, -1431, 1447, 3073, 3120, 1927, 237, -1172, -1795, -1548, -720, 219, 850}; // numTaps = 45, L = 5
|
||||
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||
|
||||
const q15_t DMR_LEVELA = 2889;
|
||||
const q15_t DMR_LEVELB = 963;
|
||||
const q15_t DMR_LEVELC = -963;
|
||||
const q15_t DMR_LEVELD = -2889;
|
||||
const q15_t DMR_LEVELA = 1362;
|
||||
const q15_t DMR_LEVELB = 454;
|
||||
const q15_t DMR_LEVELC = -454;
|
||||
const q15_t DMR_LEVELD = -1362;
|
||||
|
||||
// The PR FILL and BS Data Sync pattern.
|
||||
const uint8_t IDLE_DATA[] =
|
||||
|
@ -82,10 +73,10 @@ m_abort()
|
|||
{
|
||||
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||
|
||||
m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = DMR_C4FSK_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = DMR_C4FSK_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
m_modFilter.L = DMR_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = RRC_0_2_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
|
||||
::memcpy(m_newShortLC, EMPTY_SHORT_LC, 12U);
|
||||
::memcpy(m_shortLC, EMPTY_SHORT_LC, 12U);
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "DStarRX.h"
|
||||
|
@ -439,12 +437,11 @@ void CDStarRX::processData(bool bit)
|
|||
bool syncSeen = false;
|
||||
if (m_dataBits >= SYNC_SCAN_START && m_dataBits <= (SYNC_POS + 1U)) {
|
||||
if (countBits32((m_patternBuffer & DATA_SYNC_MASK) ^ DATA_SYNC_DATA) <= DATA_SYNC_ERRS) {
|
||||
#if defined(WANT_DEBUG)
|
||||
if (m_dataBits < SYNC_POS)
|
||||
DEBUG2("DStarRX: found data sync in Data, early", SYNC_POS - m_dataBits);
|
||||
else
|
||||
DEBUG1("DStarRX: found data sync in Data");
|
||||
#endif
|
||||
|
||||
m_rxBufferBits = DSTAR_DATA_LENGTH_BITS;
|
||||
m_dataBits = 0U;
|
||||
syncSeen = true;
|
||||
|
|
18
DStarTX.cpp
18
DStarTX.cpp
|
@ -17,8 +17,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "DStarTX.h"
|
||||
|
@ -30,11 +28,11 @@ const uint8_t BIT_SYNC = 0xAAU;
|
|||
const uint8_t FRAME_SYNC[] = {0xEAU, 0xA6U, 0x00U};
|
||||
|
||||
// Generated using gaussfir(0.35, 1, 5) in MATLAB
|
||||
static q15_t DSTAR_GMSK_FILTER[] = {0, 0, 0, 0, 212, 743, 1974, 3965, 6026, 6929, 6026, 3965, 1974, 743, 212}; // numTaps = 15, L = 5
|
||||
const uint16_t DSTAR_GMSK_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L
|
||||
static q15_t GAUSSIAN_0_35_FILTER[] = {0, 0, 0, 0, 1001, 3514, 9333, 18751, 28499, 32767, 28499, 18751, 9333, 3514, 1001}; // numTaps = 15, L = 5
|
||||
const uint16_t GAUSSIAN_0_35_FILTER_PHASE_LEN = 3U; // phaseLength = numTaps/L
|
||||
|
||||
const q15_t DSTAR_LEVEL0 = -4000;
|
||||
const q15_t DSTAR_LEVEL1 = 4000;
|
||||
const q15_t DSTAR_LEVEL0 = -841;
|
||||
const q15_t DSTAR_LEVEL1 = 841;
|
||||
|
||||
const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
|
@ -200,10 +198,10 @@ m_txDelay(60U) // 100ms
|
|||
{
|
||||
::memset(m_modState, 0x00U, 20U * sizeof(q15_t));
|
||||
|
||||
m_modFilter.L = DSTAR_RADIO_BIT_LENGTH;
|
||||
m_modFilter.phaseLength = DSTAR_GMSK_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = DSTAR_GMSK_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
m_modFilter.L = DSTAR_RADIO_BIT_LENGTH;
|
||||
m_modFilter.phaseLength = GAUSSIAN_0_35_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = GAUSSIAN_0_35_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
}
|
||||
|
||||
void CDStarTX::process()
|
||||
|
|
17
Debug.h
17
Debug.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -20,9 +20,6 @@
|
|||
#define DEBUG_H
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#if defined(WANT_DEBUG)
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
#define DEBUG1(a) serial.writeDebug((a))
|
||||
|
@ -30,18 +27,6 @@
|
|||
#define DEBUG3(a,b,c) serial.writeDebug((a),(b),(c))
|
||||
#define DEBUG4(a,b,c,d) serial.writeDebug((a),(b),(c),(d))
|
||||
#define DEBUG5(a,b,c,d,e) serial.writeDebug((a),(b),(c),(d),(e))
|
||||
#define ASSERT(a) serial.writeAssert((a),#a,__FILE__,__LINE__)
|
||||
|
||||
#else
|
||||
|
||||
#define DEBUG1(a)
|
||||
#define DEBUG2(a,b)
|
||||
#define DEBUG3(a,b,c)
|
||||
#define DEBUG4(a,b,c,d)
|
||||
#define DEBUG5(a,b,c,d,e)
|
||||
#define ASSERT(a)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
78
IO.cpp
78
IO.cpp
|
@ -18,32 +18,23 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "IO.h"
|
||||
|
||||
#if defined(WIDE_C4FSK_FILTERS_RX)
|
||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
||||
static q15_t C4FSK_FILTER[] = {688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688, 0};
|
||||
const uint16_t C4FSK_FILTER_LEN = 22U;
|
||||
#else
|
||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
||||
static q15_t C4FSK_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
||||
static q15_t RRC_0_2_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
||||
-553, -847, -731, -340, 104, 401, 0};
|
||||
const uint16_t C4FSK_FILTER_LEN = 42U;
|
||||
#endif
|
||||
const uint16_t RRC_0_2_FILTER_LEN = 42U;
|
||||
|
||||
// Generated using gaussfir(0.5, 4, 5) in MATLAB
|
||||
static q15_t GMSK_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0};
|
||||
const uint16_t GMSK_FILTER_LEN = 12U;
|
||||
static q15_t GAUSSIAN_0_5_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0};
|
||||
const uint16_t GAUSSIAN_0_5_FILTER_LEN = 12U;
|
||||
|
||||
// One symbol boxcar filter
|
||||
static q15_t P25_FILTER[] = {3000, 3000, 3000, 3000, 3000, 0};
|
||||
const uint16_t P25_FILTER_LEN = 6U;
|
||||
static q15_t BOXCAR_FILTER[] = {3000, 3000, 3000, 3000, 3000, 0};
|
||||
const uint16_t BOXCAR_FILTER_LEN = 6U;
|
||||
|
||||
const uint16_t DC_OFFSET = 2048U;
|
||||
|
||||
|
@ -52,12 +43,12 @@ m_started(false),
|
|||
m_rxBuffer(RX_RINGBUFFER_SIZE),
|
||||
m_txBuffer(TX_RINGBUFFER_SIZE),
|
||||
m_rssiBuffer(RX_RINGBUFFER_SIZE),
|
||||
m_C4FSKFilter(),
|
||||
m_GMSKFilter(),
|
||||
m_P25Filter(),
|
||||
m_C4FSKState(),
|
||||
m_GMSKState(),
|
||||
m_P25State(),
|
||||
m_rrcFilter(),
|
||||
m_gaussianFilter(),
|
||||
m_boxcarFilter(),
|
||||
m_rrcState(),
|
||||
m_gaussianState(),
|
||||
m_boxcarState(),
|
||||
m_pttInvert(false),
|
||||
m_rxLevel(128 * 128),
|
||||
m_cwIdTXLevel(128 * 128),
|
||||
|
@ -73,21 +64,21 @@ m_dacOverflow(0U),
|
|||
m_watchdog(0U),
|
||||
m_lockout(false)
|
||||
{
|
||||
::memset(m_C4FSKState, 0x00U, 70U * sizeof(q15_t));
|
||||
::memset(m_GMSKState, 0x00U, 40U * sizeof(q15_t));
|
||||
::memset(m_P25State, 0x00U, 30U * sizeof(q15_t));
|
||||
::memset(m_rrcState, 0x00U, 70U * sizeof(q15_t));
|
||||
::memset(m_gaussianState, 0x00U, 40U * sizeof(q15_t));
|
||||
::memset(m_boxcarState, 0x00U, 30U * sizeof(q15_t));
|
||||
|
||||
m_C4FSKFilter.numTaps = C4FSK_FILTER_LEN;
|
||||
m_C4FSKFilter.pState = m_C4FSKState;
|
||||
m_C4FSKFilter.pCoeffs = C4FSK_FILTER;
|
||||
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
|
||||
m_rrcFilter.pState = m_rrcState;
|
||||
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
|
||||
|
||||
m_GMSKFilter.numTaps = GMSK_FILTER_LEN;
|
||||
m_GMSKFilter.pState = m_GMSKState;
|
||||
m_GMSKFilter.pCoeffs = GMSK_FILTER;
|
||||
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
|
||||
m_gaussianFilter.pState = m_gaussianState;
|
||||
m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER;
|
||||
|
||||
m_P25Filter.numTaps = P25_FILTER_LEN;
|
||||
m_P25Filter.pState = m_P25State;
|
||||
m_P25Filter.pCoeffs = P25_FILTER;
|
||||
m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN;
|
||||
m_boxcarFilter.pState = m_boxcarState;
|
||||
m_boxcarFilter.pCoeffs = BOXCAR_FILTER;
|
||||
|
||||
initInt();
|
||||
}
|
||||
|
@ -169,21 +160,21 @@ void CIO::process()
|
|||
if (m_modemState == STATE_IDLE) {
|
||||
if (m_dstarEnable) {
|
||||
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
|
||||
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (m_p25Enable) {
|
||||
q15_t P25Vals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||
|
||||
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
if (m_dmrEnable || m_ysfEnable) {
|
||||
q15_t C4FSKVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
|
||||
|
||||
if (m_dmrEnable) {
|
||||
if (m_duplex)
|
||||
|
@ -198,14 +189,14 @@ void CIO::process()
|
|||
} else if (m_modemState == STATE_DSTAR) {
|
||||
if (m_dstarEnable) {
|
||||
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
|
||||
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
} else if (m_modemState == STATE_DMR) {
|
||||
if (m_dmrEnable) {
|
||||
q15_t C4FSKVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
|
||||
|
||||
if (m_duplex) {
|
||||
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
|
||||
|
@ -220,20 +211,20 @@ void CIO::process()
|
|||
} else if (m_modemState == STATE_YSF) {
|
||||
if (m_ysfEnable) {
|
||||
q15_t C4FSKVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_rrcFilter, samples, C4FSKVals, RX_BLOCK_SIZE);
|
||||
|
||||
ysfRX.samples(C4FSKVals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
} else if (m_modemState == STATE_P25) {
|
||||
if (m_p25Enable) {
|
||||
q15_t P25Vals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_P25Filter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
|
||||
|
||||
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
|
||||
}
|
||||
} else if (m_modemState == STATE_DSTARCAL) {
|
||||
q15_t GMSKVals[RX_BLOCK_SIZE];
|
||||
::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
|
||||
|
||||
calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE);
|
||||
} else if (m_modemState == STATE_RSSICAL) {
|
||||
|
@ -346,11 +337,6 @@ void CIO::getOverflow(bool& adcOverflow, bool& dacOverflow)
|
|||
adcOverflow = m_adcOverflow > 0U;
|
||||
dacOverflow = m_dacOverflow > 0U;
|
||||
|
||||
#if defined(WANT_DEBUG)
|
||||
if (m_adcOverflow > 0U || m_dacOverflow > 0U)
|
||||
DEBUG3("IO: adc/dac", m_adcOverflow, m_dacOverflow);
|
||||
#endif
|
||||
|
||||
m_adcOverflow = 0U;
|
||||
m_dacOverflow = 0U;
|
||||
}
|
||||
|
|
12
IO.h
12
IO.h
|
@ -60,12 +60,12 @@ private:
|
|||
CSampleRB m_txBuffer;
|
||||
CRSSIRB m_rssiBuffer;
|
||||
|
||||
arm_fir_instance_q15 m_C4FSKFilter;
|
||||
arm_fir_instance_q15 m_GMSKFilter;
|
||||
arm_fir_instance_q15 m_P25Filter;
|
||||
q15_t m_C4FSKState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
||||
q15_t m_GMSKState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
|
||||
q15_t m_P25State[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare
|
||||
arm_fir_instance_q15 m_rrcFilter;
|
||||
arm_fir_instance_q15 m_gaussianFilter;
|
||||
arm_fir_instance_q15 m_boxcarFilter;
|
||||
q15_t m_rrcState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
|
||||
q15_t m_gaussianState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
|
||||
q15_t m_boxcarState[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare
|
||||
|
||||
bool m_pttInvert;
|
||||
q15_t m_rxLevel;
|
||||
|
|
|
@ -46,8 +46,8 @@ TX PA4 analog output (DAC_OUT1)
|
|||
|
||||
EXT_CLK PA15 input (AF: TIM2_CH1_ETR)
|
||||
|
||||
USART2_TXD PA2 output (AF)
|
||||
USART2_RXD PA3 input (AF)
|
||||
USART1_TXD PA9 output (AF)
|
||||
USART1_RXD PA10 input (AF)
|
||||
|
||||
*/
|
||||
|
||||
|
@ -91,10 +91,10 @@ USART2_RXD PA3 input (AF)
|
|||
#define SRC_EXT_CLK 15
|
||||
#define PORT_EXT_CLK GPIOA
|
||||
|
||||
#define PIN_USART2_TXD 2
|
||||
#define PORT_USART2_TXD GPIOA
|
||||
#define PIN_USART2_RXD 3
|
||||
#define PORT_USART2_RXD GPIOA
|
||||
#define PIN_USART1_TXD 9
|
||||
#define PORT_USART1_TXD GPIOA
|
||||
#define PIN_USART1_RXD 10
|
||||
#define PORT_USART1_RXD GPIOA
|
||||
|
||||
#else // defined(STM32F1_POG)
|
||||
#error "Either STM32F1_POG, or sth need to be defined"
|
||||
|
@ -143,6 +143,46 @@ void GPIOConfigPin(GPIO_TypeDef *port_ptr, uint32_t pin, uint32_t mode_cnf_value
|
|||
*cr_ptr = cr_value; // save localized value to CRL / CRL
|
||||
}
|
||||
|
||||
#if defined(STM32F1_POG)
|
||||
void FancyLEDEffect()
|
||||
{
|
||||
bitband_t foo[] = {&BB_LED, &BB_COSLED, &BB_PTT, &BB_DMR, &BB_DSTAR, &BB_YSF, &BB_P25};
|
||||
|
||||
for(int i=0; i<7; i++){
|
||||
*foo[i] = 0x01;
|
||||
}
|
||||
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1);
|
||||
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
|
||||
delay(SystemCoreClock/1000*100);
|
||||
for(int i=0; i<7; i++){
|
||||
*foo[i] = 0x00;
|
||||
}
|
||||
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
|
||||
delay(SystemCoreClock/1000*20);
|
||||
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
|
||||
delay(SystemCoreClock/1000*10);
|
||||
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
|
||||
|
||||
*foo[0] = 0x01;
|
||||
for(int i=1; i<7; i++){
|
||||
delay(SystemCoreClock/1000*10);
|
||||
*foo[i-1] = 0x00;
|
||||
*foo[i] = 0x01;
|
||||
}
|
||||
for(int i=5; i>=0; i--){
|
||||
delay(SystemCoreClock/1000*10);
|
||||
*foo[i+1] = 0x00;
|
||||
*foo[i] = 0x01;
|
||||
}
|
||||
delay(SystemCoreClock/1000*10);
|
||||
*foo[5+1-6] = 0x00;
|
||||
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
|
||||
delay(SystemCoreClock/1000*10);
|
||||
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
|
||||
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
|
||||
delay(SystemCoreClock/1000*50);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void GPIOInit()
|
||||
{
|
||||
|
@ -188,8 +228,8 @@ static inline void GPIOInit()
|
|||
#endif
|
||||
#endif
|
||||
|
||||
GPIOConfigPin(PORT_USART2_TXD, PIN_USART2_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
|
||||
GPIOConfigPin(PORT_USART2_RXD, PIN_USART2_RXD, GPIO_CRL_CNF0_0);
|
||||
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1|GPIO_CRL_CNF0_1);
|
||||
GPIOConfigPin(PORT_USART1_RXD, PIN_USART1_RXD, GPIO_CRL_CNF0_0);
|
||||
|
||||
AFIO->MAPR = (AFIO->MAPR & ~AFIO_MAPR_SWJ_CFG) | AFIO_MAPR_SWJ_CFG_1;
|
||||
}
|
||||
|
@ -295,6 +335,9 @@ void CIO::initInt()
|
|||
GPIOInit();
|
||||
ADCInit();
|
||||
DACInit();
|
||||
#if defined(STM32F1_POG)
|
||||
FancyLEDEffect();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CIO::startInt()
|
||||
|
|
12
Makefile
12
Makefile
|
@ -85,11 +85,11 @@ MCFLAGS=-mcpu=cortex-m4 -mthumb -mlittle-endian \
|
|||
|
||||
# COMPILE FLAGS
|
||||
# STM32F4 Discovery board:
|
||||
DEFS_DIS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_DISCOVERY -DHSE_VALUE=$(OSC)
|
||||
DEFS_DIS=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F40_41xxx -DSTM32F4_DISCOVERY -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||
# Pi board:
|
||||
DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DARDUINO_MODE_PINS -DSEND_RSSI_DATA -DSERIAL_REPEATER -DHSE_VALUE=$(OSC)
|
||||
DEFS_PI=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_PI -DARDUINO_MODE_PINS -DSEND_RSSI_DATA -DSERIAL_REPEATER -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||
# STM32F4 Nucleo 446 board:
|
||||
DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -DHSE_VALUE=$(OSC)
|
||||
DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
|
||||
|
||||
CFLAGS=-c $(MCFLAGS) $(INCLUDES)
|
||||
CXXFLAGS=-c $(MCFLAGS) $(INCLUDES)
|
||||
|
@ -188,8 +188,14 @@ endif
|
|||
|
||||
# Export the current git version if the index file exists, else 000...
|
||||
GitVersion.h:
|
||||
ifdef SYSTEMROOT
|
||||
echo #define GITVERSION "0000000" > $@
|
||||
else ifdef SystemRoot
|
||||
echo #define GITVERSION "0000000" > $@
|
||||
else
|
||||
ifneq ("$(wildcard .git/index)","")
|
||||
echo "#define GITVERSION \"$(shell git rev-parse --short HEAD)\"" > $@
|
||||
else
|
||||
echo "#define GITVERSION \"0000000\"" > $@
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
#!/usr/bin/make
|
||||
# makefile for the arduino due (works with arduino IDE 1.6.11)
|
||||
#
|
||||
# The original file can be found at https://github.com/pauldreik/arduino-due-makefile
|
||||
#
|
||||
# USAGE: put this file in the same dir as your .ino file is.
|
||||
# configure the PORT variable and ADIR at the top of the file
|
||||
# to match your local configuration.
|
||||
# Type make upload to compile and upload.
|
||||
#
|
||||
|
||||
#user specific settings:
|
||||
#where to find the IDE
|
||||
ADIR:=$(HOME)/.arduino15
|
||||
#which serial port to use (add a file with SUBSYSTEMS=="usb",
|
||||
#ATTRS{product}=="Arduino Due Prog. Port", ATTRS{idProduct}=="003d",
|
||||
#ATTRS{idVendor}=="2341", SYMLINK+="arduino_due" in /etc/udev/rules.d/
|
||||
#to get this working). Do not prefix the port with /dev/, just take
|
||||
#the basename.
|
||||
PORT:=ttyACM0
|
||||
#if you want to verify the bossac upload, define this to -v
|
||||
VERIFY:=-v
|
||||
|
||||
|
||||
#end of user configuration.
|
||||
|
||||
|
||||
#then some general settings. They should not be necessary to modify.
|
||||
#CXX:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-g++
|
||||
CXX:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-g++
|
||||
#CC:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-gcc
|
||||
CC:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-gcc
|
||||
OBJCOPY:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-objcopy
|
||||
|
||||
C:=$(CC)
|
||||
#SAM:=arduino/sam/
|
||||
SAM:=$(ADIR)/packages/arduino/hardware/sam/1.6.11
|
||||
#CMSIS:=arduino/sam/system/CMSIS/
|
||||
#LIBSAM:=arduino/sam/system/libsam
|
||||
TMPDIR:=$(PWD)/build
|
||||
AR:=$(ADIR)/tools/g++_arm_none_eabi/bin/arm-none-eabi-ar
|
||||
AR:=$(ADIR)/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-ar
|
||||
|
||||
|
||||
#all these values are hard coded and should maybe be configured somehow else,
|
||||
#like olikraus does in his makefile.
|
||||
DEFINES:=-Dprintf=iprintf -DF_CPU=84000000 -DARDUINO=10611 -D__SAM3X8E__ -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON \
|
||||
-DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM '-DUSB_MANUFACTURER="Arduino LLC"' '-DUSB_PRODUCT="Arduino Due"' \
|
||||
-DMADEBYMAKEFILE
|
||||
|
||||
INCLUDES:=-I$(SAM)/system/libsam -I$(SAM)/system/CMSIS/CMSIS/Include/ \
|
||||
-I$(SAM)/system/CMSIS/Device/ATMEL/ -I$(SAM)/cores/arduino \
|
||||
-I$(SAM)/variants/arduino_due_x
|
||||
|
||||
#also include the current dir for convenience
|
||||
INCLUDES += -I.
|
||||
|
||||
#compilation flags common to both c and c++
|
||||
COMMON_FLAGS:=-g -Os -w -ffunction-sections -fdata-sections -nostdlib \
|
||||
--param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb \
|
||||
-fno-threadsafe-statics
|
||||
#for compiling c (do not warn, this is not our code)
|
||||
CFLAGS:=$(COMMON_FLAGS) -std=gnu11
|
||||
#for compiling c++
|
||||
CXXFLAGS:=$(COMMON_FLAGS) -fno-rtti -fno-exceptions -std=gnu++11 -Wall -Wextra
|
||||
|
||||
#let the results be named after the project
|
||||
PROJNAME:=$(shell basename *.ino .ino)
|
||||
|
||||
#we will make a new mainfile from the ino file.
|
||||
NEWMAINFILE:=$(TMPDIR)/$(PROJNAME).ino.cpp
|
||||
|
||||
#our own sourcefiles is the (converted) ino file and any local cpp files
|
||||
MYSRCFILES:=$(NEWMAINFILE) $(shell ls *.cpp 2>/dev/null)
|
||||
MYOBJFILES:=$(addsuffix .o,$(addprefix $(TMPDIR)/,$(notdir $(MYSRCFILES))))
|
||||
|
||||
#These source files are the ones forming core.a
|
||||
CORESRCXX:=$(shell ls ${SAM}/cores/arduino/*.cpp ${SAM}/cores/arduino/USB/*.cpp ${SAM}/variants/arduino_due_x/variant.cpp)
|
||||
CORESRC:=$(shell ls ${SAM}/cores/arduino/*.c)
|
||||
|
||||
#hey this one is needed too: $(SAM)/cores/arduino/wiring_pulse_asm.S" add -x assembler-with-cpp
|
||||
#and this one: /1.6.11/cores/arduino/avr/dtostrf.c but it seems to work
|
||||
#anyway, probably because I do not use that functionality.
|
||||
|
||||
#convert the core source files to object files. assume no clashes.
|
||||
COREOBJSXX:=$(addprefix $(TMPDIR)/core/,$(notdir $(CORESRCXX)) )
|
||||
COREOBJSXX:=$(addsuffix .o,$(COREOBJSXX))
|
||||
COREOBJS:=$(addprefix $(TMPDIR)/core/,$(notdir $(CORESRC)) )
|
||||
COREOBJS:=$(addsuffix .o,$(COREOBJS))
|
||||
|
||||
default:
|
||||
@echo default rule, does nothing. Try make compile or make upload.
|
||||
|
||||
#This rule is good to just make sure stuff compiles, without having to wait
|
||||
#for bossac.
|
||||
compile: GitVersion.h
|
||||
compile: $(TMPDIR)/$(PROJNAME).elf
|
||||
|
||||
#This is a make rule template to create object files from the source files.
|
||||
# arg 1=src file
|
||||
# arg 2=object file
|
||||
# arg 3= XX if c++, empty if c
|
||||
define OBJ_template
|
||||
$(2): $(1)
|
||||
$(C$(3)) -MD -c $(C$(3)FLAGS) $(DEFINES) $(INCLUDES) $(1) -o $(2)
|
||||
endef
|
||||
#now invoke the template both for c++ sources
|
||||
$(foreach src,$(CORESRCXX), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/core/,$(notdir $(src)))),XX) ) )
|
||||
#...and for c sources:
|
||||
$(foreach src,$(CORESRC), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/core/,$(notdir $(src)))),) ) )
|
||||
|
||||
#and our own c++ sources
|
||||
$(foreach src,$(MYSRCFILES), $(eval $(call OBJ_template,$(src),$(addsuffix .o,$(addprefix $(TMPDIR)/,$(notdir $(src)))),XX) ) )
|
||||
|
||||
|
||||
clean:
|
||||
test ! -d $(TMPDIR) || rm -rf $(TMPDIR)
|
||||
$(RM) GitVersion.h
|
||||
|
||||
.PHONY: .FORCE upload default
|
||||
|
||||
$(TMPDIR):
|
||||
mkdir -p $(TMPDIR)
|
||||
|
||||
$(TMPDIR)/core:
|
||||
mkdir -p $(TMPDIR)/core
|
||||
|
||||
#creates the cpp file from the .ino file
|
||||
$(NEWMAINFILE): $(PROJNAME).ino
|
||||
cat $(SAM)/cores/arduino/main.cpp > $(NEWMAINFILE)
|
||||
cat $(PROJNAME).ino >> $(NEWMAINFILE)
|
||||
echo 'extern "C" void __cxa_pure_virtual() {while (true);}' >> $(NEWMAINFILE)
|
||||
|
||||
#include the dependencies for our own files
|
||||
-include $(MYOBJFILES:.o=.d)
|
||||
|
||||
#create the core library from the core objects. Do this EXACTLY as the
|
||||
#arduino IDE does it, seems *really* picky about this.
|
||||
#Sorry for the hard coding.
|
||||
$(TMPDIR)/core.a: $(TMPDIR)/core $(COREOBJS) $(COREOBJSXX)
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_shift.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_analog.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/itoa.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/cortex_handlers.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/hooks.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WInterrupts.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/syscalls_sam3.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/iar_calls_sam3.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_digital.c.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Print.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/USARTClass.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WString.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/PluggableUSB.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/USBCore.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/CDC.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/wiring_pulse.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/UARTClass.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/main.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/new.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/watchdog.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Stream.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/RingBuffer.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/IPAddress.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/Reset.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/WMath.cpp.o
|
||||
$(AR) rcs $(TMPDIR)/core.a $(TMPDIR)/core/variant.cpp.o
|
||||
|
||||
#link our own object files with core to form the elf file
|
||||
$(TMPDIR)/$(PROJNAME).elf: $(TMPDIR)/core.a $(TMPDIR)/core/syscalls_sam3.c.o $(MYOBJFILES)
|
||||
$(CC) -mcpu=cortex-m3 -mthumb -Os -Wl,--gc-sections -T$(SAM)/variants/arduino_due_x/linker_scripts/gcc/flash.ld -Wl,-Map,$(NEWMAINFILE).map -o $@ -L$(TMPDIR) -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid $(MYOBJFILES) $(TMPDIR)/core/variant.cpp.o $(SAM)/variants/arduino_due_x/libsam_sam3x8e_gcc_rel.a $(SAM)/system/CMSIS/CMSIS/Lib/GCC/libarm_cortexM3l_math.a $(TMPDIR)/core.a -Wl,--end-group -lm -gcc
|
||||
|
||||
#copy from the hex to our bin file (why?)
|
||||
$(TMPDIR)/$(PROJNAME).bin: $(TMPDIR)/$(PROJNAME).elf
|
||||
$(OBJCOPY) -O binary $< $@
|
||||
|
||||
#upload to the arduino by first resetting it (stty) and the running bossac
|
||||
upload: GitVersion.h $(TMPDIR)/$(PROJNAME).bin
|
||||
stty -F /dev/$(PORT) cs8 1200 hupcl
|
||||
$(ADIR)/packages/arduino/tools/bossac/1.6.1-arduino/bossac -i --port=$(PORT) -U false -e -w $(VERIFY) -b $(TMPDIR)/$(PROJNAME).bin -R
|
||||
|
||||
# Export the current git version if the index file exists, else 000...
|
||||
GitVersion.h: .FORCE
|
||||
ifneq ("$(wildcard .git/index)","")
|
||||
echo "#define GITVERSION \"$(shell git rev-parse --short HEAD)\"" > $@
|
||||
else
|
||||
echo "#define GITVERSION \"0000000\"" > $@
|
||||
endif
|
||||
|
||||
.FORCE:
|
|
@ -39,7 +39,7 @@ OBJDIR:=obj
|
|||
BINDIR:=bin
|
||||
|
||||
# Port definition for programming via bootloader (using stm32flash)
|
||||
BL_PORT:=/dev/ttyUSB0
|
||||
BL_PORT:=ttyUSB0
|
||||
|
||||
|
||||
|
||||
|
@ -102,7 +102,7 @@ program: $(HEX) $(ELF)
|
|||
|
||||
.PHONY: program_bl
|
||||
program_bl: $(HEX) $(ELF)
|
||||
stm32flash -w $(HEX) -v $(BL_PORT)
|
||||
stm32flash -w $(HEX) -v /dev/$(BL_PORT)
|
||||
$(SIZE) $(ELF)
|
||||
|
||||
.PHONY: run
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "P25RX.h"
|
||||
|
|
44
P25TX.cpp
44
P25TX.cpp
|
@ -17,40 +17,30 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "P25TX.h"
|
||||
|
||||
#include "P25Defines.h"
|
||||
|
||||
#if defined(WIDE_C4FSK_FILTERS_TX)
|
||||
// Generated using rcosdesign(0.2, 4, 5, 'normal') in MATLAB
|
||||
// numTaps = 20, L = 5
|
||||
static q15_t P25_C4FSK_FILTER[] = {-1392, -2602, -3043, -2238, 0, 3460, 7543, 11400, 14153, 15152, 14153, 11400, 7543, 3460, 0, -2238, -3043, -2602, -1392, 0};
|
||||
const uint16_t P25_C4FSK_FILTER_PHASE_LEN = 4U; // phaseLength = numTaps/L
|
||||
#else
|
||||
// Generated using rcosdesign(0.2, 8, 5, 'normal') in MATLAB
|
||||
// numTaps = 40, L = 5
|
||||
static q15_t P25_C4FSK_FILTER[] = {-413, -751, -845, -587, 0, 740, 1348, 1520, 1063, 0, -1383, -2583, -3021, -2222, 0, 3435, 7488, 11318, 14053, 15044, 14053,
|
||||
11318, 7488, 3435, 0, -2222, -3021, -2583, -1383, 0, 1063, 1520, 1348, 740, 0, -587, -845, -751, -413, 0};
|
||||
const uint16_t P25_C4FSK_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L
|
||||
#endif
|
||||
static q15_t RC_0_2_FILTER[] = {-897, -1636, -1840, -1278, 0, 1613, 2936, 3310, 2315, 0, -3011, -5627, -6580, -4839,
|
||||
0, 7482, 16311, 24651, 30607, 32767, 30607, 24651, 16311, 7482, 0, -4839, -6580, -5627,
|
||||
-3011, 0, 2315, 3310, 2936, 1613, 0, -1278, -1840, -1636, -897, 0}; // numTaps = 40, L = 5
|
||||
const uint16_t RC_0_2_FILTER_PHASE_LEN = 8U; // phaseLength = numTaps/L
|
||||
|
||||
// Generated in MATLAB using the following commands, and then normalised for unity gain
|
||||
// shape2 = 'Inverse-sinc Lowpass';
|
||||
// d2 = fdesign.interpolator(2, shape2);
|
||||
// d2 = fdesign.interpolator(1, shape2);
|
||||
// h2 = design(d2, 'SystemObject', true);
|
||||
static q15_t P25_LP_FILTER[] = {170, 401, 340, -203, -715, -478, 281, 419, -440, -1002, -103, 1114, 528, -1389, -1520, 1108, 2674, -388, -4662,
|
||||
-2132, 9168, 20241, 20241, 9168, -2132, -4662, -388, 2674, 1108, -1520, -1389, 528, 1114, -103, -1002, -440, 419,
|
||||
281, -478, -715, -203, 340, 401, 170};
|
||||
const uint16_t P25_LP_FILTER_LEN = 44U;
|
||||
static q15_t LOWPASS_FILTER[] = {1294, -2251, 4312, -8402, 20999, 20999, -8402, 4312, -2251, 1294};
|
||||
const uint16_t LOWPASS_FILTER_LEN = 10U;
|
||||
|
||||
const q15_t P25_LEVELA = 1698;
|
||||
const q15_t P25_LEVELB = 566;
|
||||
const q15_t P25_LEVELC = -566;
|
||||
const q15_t P25_LEVELD = -1698;
|
||||
const q15_t P25_LEVELA = 1260;
|
||||
const q15_t P25_LEVELB = 420;
|
||||
const q15_t P25_LEVELC = -420;
|
||||
const q15_t P25_LEVELD = -1260;
|
||||
|
||||
const uint8_t P25_START_SYNC = 0x77U;
|
||||
|
||||
|
@ -68,14 +58,14 @@ m_txDelay(240U) // 200ms
|
|||
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||
::memset(m_lpState, 0x00U, 70U * sizeof(q15_t));
|
||||
|
||||
m_modFilter.L = P25_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = P25_C4FSK_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = P25_C4FSK_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
m_modFilter.L = P25_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = RC_0_2_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = RC_0_2_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
|
||||
m_lpFilter.numTaps = P25_LP_FILTER_LEN;
|
||||
m_lpFilter.numTaps = LOWPASS_FILTER_LEN;
|
||||
m_lpFilter.pState = m_lpState;
|
||||
m_lpFilter.pCoeffs = P25_LP_FILTER;
|
||||
m_lpFilter.pCoeffs = LOWPASS_FILTER;
|
||||
}
|
||||
|
||||
void CP25TX::process()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -54,6 +54,20 @@ int CSerialPort::availableInt(uint8_t n)
|
|||
}
|
||||
}
|
||||
|
||||
int CSerialPort::availableForWriteInt(uint8_t n)
|
||||
{
|
||||
switch (n) {
|
||||
case 1U:
|
||||
return Serial.availableForWrite();
|
||||
case 2U:
|
||||
return Serial2.availableForWrite();
|
||||
case 3U:
|
||||
return Serial3.availableForWrite();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t CSerialPort::readInt(uint8_t n)
|
||||
{
|
||||
switch (n) {
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#if defined(STM32F4XX) || defined(STM32F4)
|
||||
#if defined(MADEBYMAKEFILE)
|
||||
#include "GitVersion.h"
|
||||
#endif
|
||||
|
||||
|
@ -75,13 +73,13 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U;
|
|||
|
||||
|
||||
#if defined(EXTERNAL_OSC)
|
||||
#define DESCRIPTION "MMDVM 20170406 TCXO (D-Star/DMR/System Fusion/P25/RSSI/CW Id)"
|
||||
#define DESCRIPTION "MMDVM 20170501 TCXO (D-Star/DMR/System Fusion/P25/RSSI/CW Id)"
|
||||
#else
|
||||
#define DESCRIPTION "MMDVM 20170406 (D-Star/DMR/System Fusion/P25/RSSI/CW Id)"
|
||||
#define DESCRIPTION "MMDVM 20170501 (D-Star/DMR/System Fusion/P25/RSSI/CW Id)"
|
||||
#endif
|
||||
|
||||
#if defined(GITVERSION)
|
||||
#define concat(a, b) a " GitID #"b""
|
||||
#define concat(a, b) a " GitID #" b ""
|
||||
const char HARDWARE[] = concat(DESCRIPTION, GITVERSION);
|
||||
#else
|
||||
#define concat(a, b, c) a " (Build: " b " " c ")"
|
||||
|
@ -94,7 +92,9 @@ const uint8_t PROTOCOL_VERSION = 1U;
|
|||
CSerialPort::CSerialPort() :
|
||||
m_buffer(),
|
||||
m_ptr(0U),
|
||||
m_len(0U)
|
||||
m_len(0U),
|
||||
m_debug(false),
|
||||
m_repeat()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -230,6 +230,8 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
|
|||
bool ysfLoDev = (data[0U] & 0x08U) == 0x08U;
|
||||
bool simplex = (data[0U] & 0x80U) == 0x80U;
|
||||
|
||||
m_debug = (data[0U] & 0x10U) == 0x10U;
|
||||
|
||||
bool dstarEnable = (data[1U] & 0x01U) == 0x01U;
|
||||
bool dmrEnable = (data[1U] & 0x02U) == 0x02U;
|
||||
bool ysfEnable = (data[1U] & 0x04U) == 0x04U;
|
||||
|
@ -282,7 +284,6 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
|
|||
dmrTX.setColorCode(colorCode);
|
||||
dmrRX.setColorCode(colorCode);
|
||||
dmrRX.setDelay(dmrDelay);
|
||||
dmrDMOTX.setColorCode(colorCode);
|
||||
dmrDMORX.setColorCode(colorCode);
|
||||
dmrIdleRX.setColorCode(colorCode);
|
||||
|
||||
|
@ -643,8 +644,10 @@ void CSerialPort::process()
|
|||
break;
|
||||
|
||||
#if defined(SERIAL_REPEATER)
|
||||
case MMDVM_SERIAL:
|
||||
writeInt(3U, m_buffer + 3U, m_len - 3U);
|
||||
case MMDVM_SERIAL: {
|
||||
for (uint8_t i = 3U; i < m_len; i++)
|
||||
m_repeat.put(m_buffer[i]);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -661,9 +664,22 @@ void CSerialPort::process()
|
|||
}
|
||||
|
||||
#if defined(SERIAL_REPEATER)
|
||||
// Drain any incoming serial data
|
||||
while (availableInt(3U))
|
||||
readInt(3U);
|
||||
// Write any outgoing serial data
|
||||
uint16_t space = m_repeat.getData();
|
||||
if (space > 0U) {
|
||||
int avail = availableForWriteInt(3U);
|
||||
if (avail < space)
|
||||
space = avail;
|
||||
|
||||
for (uint16_t i = 0U; i < space; i++) {
|
||||
uint8_t c = m_repeat.get();
|
||||
writeInt(3U, &c, 1U);
|
||||
}
|
||||
}
|
||||
|
||||
// Read any incoming serial data
|
||||
while (availableInt(3U))
|
||||
readInt(3U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -931,6 +947,9 @@ void CSerialPort::writeRSSIData(const uint8_t* data, uint8_t length)
|
|||
|
||||
void CSerialPort::writeDebug(const char* text)
|
||||
{
|
||||
if (!m_debug)
|
||||
return;
|
||||
|
||||
uint8_t reply[130U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
|
@ -948,6 +967,9 @@ void CSerialPort::writeDebug(const char* text)
|
|||
|
||||
void CSerialPort::writeDebug(const char* text, int16_t n1)
|
||||
{
|
||||
if (!m_debug)
|
||||
return;
|
||||
|
||||
uint8_t reply[130U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
|
@ -968,6 +990,9 @@ void CSerialPort::writeDebug(const char* text, int16_t n1)
|
|||
|
||||
void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2)
|
||||
{
|
||||
if (!m_debug)
|
||||
return;
|
||||
|
||||
uint8_t reply[130U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
|
@ -991,6 +1016,9 @@ void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2)
|
|||
|
||||
void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3)
|
||||
{
|
||||
if (!m_debug)
|
||||
return;
|
||||
|
||||
uint8_t reply[130U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
|
@ -1017,6 +1045,9 @@ void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n
|
|||
|
||||
void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n3, int16_t n4)
|
||||
{
|
||||
if (!m_debug)
|
||||
return;
|
||||
|
||||
uint8_t reply[130U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
|
@ -1043,32 +1074,3 @@ void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n
|
|||
|
||||
writeInt(1U, reply, count, true);
|
||||
}
|
||||
|
||||
void CSerialPort::writeAssert(bool cond, const char* text, const char* file, long line)
|
||||
{
|
||||
if (cond)
|
||||
return;
|
||||
|
||||
uint8_t reply[200U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
reply[1U] = 0U;
|
||||
reply[2U] = MMDVM_DEBUG2;
|
||||
|
||||
uint8_t count = 3U;
|
||||
for (uint8_t i = 0U; text[i] != '\0'; i++, count++)
|
||||
reply[count] = text[i];
|
||||
|
||||
reply[count++] = ' ';
|
||||
|
||||
for (uint8_t i = 0U; file[i] != '\0'; i++, count++)
|
||||
reply[count] = file[i];
|
||||
|
||||
reply[count++] = (line >> 8) & 0xFF;
|
||||
reply[count++] = (line >> 0) & 0xFF;
|
||||
|
||||
reply[1U] = count;
|
||||
|
||||
writeInt(1U, reply, count, true);
|
||||
}
|
||||
|
||||
|
|
13
SerialPort.h
13
SerialPort.h
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "SerialRB.h"
|
||||
|
||||
|
||||
class CSerialPort {
|
||||
|
@ -55,12 +56,12 @@ public:
|
|||
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, int16_t n4);
|
||||
|
||||
void writeAssert(bool cond, const char* text, const char* file, long line);
|
||||
|
||||
private:
|
||||
uint8_t m_buffer[256U];
|
||||
uint8_t m_ptr;
|
||||
uint8_t m_len;
|
||||
uint8_t m_buffer[256U];
|
||||
uint8_t m_ptr;
|
||||
uint8_t m_len;
|
||||
bool m_debug;
|
||||
CSerialRB m_repeat;
|
||||
|
||||
void sendACK();
|
||||
void sendNAK(uint8_t err);
|
||||
|
@ -73,9 +74,9 @@ private:
|
|||
// Hardware versions
|
||||
void beginInt(uint8_t n, int speed);
|
||||
int availableInt(uint8_t n);
|
||||
int availableForWriteInt(uint8_t n);
|
||||
uint8_t readInt(uint8_t n);
|
||||
void writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush = false);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
||||
* Copyright (C) 2016, 2017 by Andy Uribe CA6JAU
|
||||
* Copyright (c) 2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -207,7 +208,7 @@ void InitUSART1(int speed)
|
|||
RXSerialfifoinit1();
|
||||
}
|
||||
|
||||
uint8_t AvailUSART1(void)
|
||||
uint8_t AvailUSART1()
|
||||
{
|
||||
if (RXSerialfifolevel1() > 0U)
|
||||
return 1U;
|
||||
|
@ -215,7 +216,12 @@ uint8_t AvailUSART1(void)
|
|||
return 0U;
|
||||
}
|
||||
|
||||
uint8_t ReadUSART1(void)
|
||||
int AvailForWriteUSART1()
|
||||
{
|
||||
return TX_SERIAL_FIFO_SIZE - TXSerialfifolevel1();
|
||||
}
|
||||
|
||||
uint8_t ReadUSART1()
|
||||
{
|
||||
uint8_t data_c = RXSerialfifo1[RXSerialfifotail1];
|
||||
|
||||
|
@ -395,7 +401,7 @@ void InitUSART2(int speed)
|
|||
RXSerialfifoinit2();
|
||||
}
|
||||
|
||||
uint8_t AvailUSART2(void)
|
||||
uint8_t AvailUSART2()
|
||||
{
|
||||
if (RXSerialfifolevel2() > 0U)
|
||||
return 1U;
|
||||
|
@ -403,7 +409,12 @@ uint8_t AvailUSART2(void)
|
|||
return 0U;
|
||||
}
|
||||
|
||||
uint8_t ReadUSART2(void)
|
||||
int AvailForWriteUSART2()
|
||||
{
|
||||
return TX_SERIAL_FIFO_SIZE - TXSerialfifolevel2();
|
||||
}
|
||||
|
||||
uint8_t ReadUSART2()
|
||||
{
|
||||
uint8_t data_c = RXSerialfifo2[RXSerialfifotail2];
|
||||
|
||||
|
@ -583,7 +594,7 @@ void InitUSART3(int speed)
|
|||
RXSerialfifoinit3();
|
||||
}
|
||||
|
||||
uint8_t AvailUSART3(void)
|
||||
uint8_t AvailUSART3()
|
||||
{
|
||||
if (RXSerialfifolevel3() > 0U)
|
||||
return 1U;
|
||||
|
@ -591,7 +602,12 @@ uint8_t AvailUSART3(void)
|
|||
return 0U;
|
||||
}
|
||||
|
||||
uint8_t ReadUSART3(void)
|
||||
int AvailForWriteUSART3()
|
||||
{
|
||||
return TX_SERIAL_FIFO_SIZE - TXSerialfifolevel3();
|
||||
}
|
||||
|
||||
uint8_t ReadUSART3()
|
||||
{
|
||||
uint8_t data_c = RXSerialfifo3[RXSerialfifotail3];
|
||||
|
||||
|
@ -775,7 +791,7 @@ void InitUART5(int speed)
|
|||
RXSerialfifoinit5();
|
||||
}
|
||||
|
||||
uint8_t AvailUART5(void)
|
||||
uint8_t AvailUART5()
|
||||
{
|
||||
if (RXSerialfifolevel5() > 0U)
|
||||
return 1U;
|
||||
|
@ -783,7 +799,12 @@ uint8_t AvailUART5(void)
|
|||
return 0U;
|
||||
}
|
||||
|
||||
uint8_t ReadUART5(void)
|
||||
int AvailForWriteUART5()
|
||||
{
|
||||
return TX_SERIAL_FIFO_SIZE - TXSerialfifolevel5();
|
||||
}
|
||||
|
||||
uint8_t ReadUART5()
|
||||
{
|
||||
uint8_t data_c = RXSerialfifo5[RXSerialfifotail5];
|
||||
|
||||
|
@ -847,7 +868,29 @@ int CSerialPort::availableInt(uint8_t n)
|
|||
return AvailUART5();
|
||||
#endif
|
||||
default:
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int CSerialPort::availableForWriteInt(uint8_t n)
|
||||
{
|
||||
switch (n) {
|
||||
case 1U:
|
||||
#if defined(STM32F4_DISCOVERY)
|
||||
return AvailForWriteUSART3();
|
||||
#elif defined(STM32F4_PI)
|
||||
return AvailForWriteUSART1();
|
||||
#elif defined(STM32F4_NUCLEO)
|
||||
return AvailForWriteUSART2();
|
||||
#endif
|
||||
case 3U:
|
||||
#if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER)
|
||||
return AvailForWriteUSART1();
|
||||
#else
|
||||
return AvailForWriteUART5();
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,11 @@
|
|||
Pin definitions (configuration in IOSTM_CMSIS.c):
|
||||
|
||||
- Host communication:
|
||||
USART2 - TXD PA2 - RXD PA3
|
||||
USART1 - TXD PA9 - RXD PA10
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#if defined(STM32F1)
|
||||
|
||||
// BaudRate calculator macro
|
||||
|
@ -42,22 +43,22 @@ USART2 - TXD PA2 - RXD PA3
|
|||
#define USART_BUFFER_SIZE 256U
|
||||
DECLARE_RINGBUFFER_TYPE(USARTBuffer, USART_BUFFER_SIZE);
|
||||
|
||||
/* ************* USART2 ***************** */
|
||||
static volatile USARTBuffer_t txBuffer2={.size=USART_BUFFER_SIZE};
|
||||
static volatile USARTBuffer_t rxBuffer2={.size=USART_BUFFER_SIZE};
|
||||
/* ************* USART1 ***************** */
|
||||
static volatile USARTBuffer_t txBuffer1={.size=USART_BUFFER_SIZE};
|
||||
static volatile USARTBuffer_t rxBuffer1={.size=USART_BUFFER_SIZE};
|
||||
|
||||
|
||||
extern "C" {
|
||||
bitband_t txe = (bitband_t)BITBAND_PERIPH(&USART2->SR, USART_SR_TXE_Pos);
|
||||
bitband_t rxne = (bitband_t)BITBAND_PERIPH(&USART2->SR, USART_SR_RXNE_Pos);
|
||||
bitband_t txeie = (bitband_t)BITBAND_PERIPH(&USART2->CR1, USART_CR1_TXEIE_Pos);
|
||||
bitband_t txe = (bitband_t)BITBAND_PERIPH(&USART1->SR, USART_SR_TXE_Pos);
|
||||
bitband_t rxne = (bitband_t)BITBAND_PERIPH(&USART1->SR, USART_SR_RXNE_Pos);
|
||||
bitband_t txeie = (bitband_t)BITBAND_PERIPH(&USART1->CR1, USART_CR1_TXEIE_Pos);
|
||||
|
||||
RAMFUNC void USART2_IRQHandler()
|
||||
RAMFUNC void USART1_IRQHandler()
|
||||
{
|
||||
/* Transmitting data */
|
||||
if(*txe){
|
||||
if(!(RINGBUFF_EMPTY(txBuffer2))){
|
||||
USART2->DR = RINGBUFF_READ(txBuffer2);
|
||||
if(!(RINGBUFF_EMPTY(txBuffer1))){
|
||||
USART1->DR = RINGBUFF_READ(txBuffer1);
|
||||
}else{ /* Buffer empty */
|
||||
*txeie = 0; /* Don't send further data */
|
||||
}
|
||||
|
@ -65,42 +66,42 @@ extern "C" {
|
|||
|
||||
/* Receiving data */
|
||||
if(*rxne){
|
||||
RINGBUFF_WRITE(rxBuffer2, USART2->DR);
|
||||
RINGBUFF_WRITE(rxBuffer1, USART1->DR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void USART2Init(int speed)
|
||||
void USART1Init(int speed)
|
||||
{
|
||||
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
|
||||
|
||||
USART2->BRR = USART_BRR(36000000UL, speed);
|
||||
USART1->BRR = USART_BRR(72000000UL, speed);
|
||||
|
||||
USART2->CR1 = USART_CR1_UE | USART_CR1_TE |
|
||||
USART1->CR1 = USART_CR1_UE | USART_CR1_TE |
|
||||
USART_CR1_RE | USART_CR1_RXNEIE; // Enable USART and RX interrupt
|
||||
NVIC_EnableIRQ(USART2_IRQn);
|
||||
NVIC_EnableIRQ(USART1_IRQn);
|
||||
}
|
||||
|
||||
RAMFUNC void USART2TxData(const uint8_t* data, uint16_t length)
|
||||
RAMFUNC void USART1TxData(const uint8_t* data, uint16_t length)
|
||||
{
|
||||
NVIC_DisableIRQ(USART2_IRQn);
|
||||
NVIC_DisableIRQ(USART1_IRQn);
|
||||
|
||||
/* Check remaining space in buffer */
|
||||
if(RINGBUFF_COUNT(txBuffer2) + length > RINGBUFF_SIZE(txBuffer2)){
|
||||
NVIC_EnableIRQ(USART2_IRQn);
|
||||
if(RINGBUFF_COUNT(txBuffer1) + length > RINGBUFF_SIZE(txBuffer1)){
|
||||
NVIC_EnableIRQ(USART1_IRQn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Append data to buffer */
|
||||
while(length--){
|
||||
RINGBUFF_WRITE(txBuffer2, *(data++));
|
||||
RINGBUFF_WRITE(txBuffer1, *(data++));
|
||||
}
|
||||
|
||||
/* Start sending data */
|
||||
USART2->CR1 |= USART_CR1_TXEIE;
|
||||
USART1->CR1 |= USART_CR1_TXEIE;
|
||||
|
||||
NVIC_EnableIRQ(USART2_IRQn);
|
||||
NVIC_EnableIRQ(USART1_IRQn);
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,7 +111,7 @@ void CSerialPort::beginInt(uint8_t n, int speed)
|
|||
{
|
||||
switch (n) {
|
||||
case 1U:
|
||||
USART2Init(speed);
|
||||
USART1Init(speed);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -121,7 +122,7 @@ int CSerialPort::availableInt(uint8_t n)
|
|||
{
|
||||
switch (n) {
|
||||
case 1U:
|
||||
return !RINGBUFF_EMPTY(rxBuffer2);
|
||||
return !RINGBUFF_EMPTY(rxBuffer1);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -131,7 +132,7 @@ uint8_t CSerialPort::readInt(uint8_t n)
|
|||
{
|
||||
switch (n) {
|
||||
case 1U:
|
||||
return RINGBUFF_READ(rxBuffer2);
|
||||
return RINGBUFF_READ(rxBuffer1);
|
||||
default:
|
||||
return 0U;
|
||||
}
|
||||
|
@ -139,15 +140,15 @@ uint8_t CSerialPort::readInt(uint8_t n)
|
|||
|
||||
void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush)
|
||||
{
|
||||
bitband_t tc = (bitband_t)BITBAND_PERIPH(&USART2->SR, USART_SR_TC_Pos);
|
||||
bitband_t tc = (bitband_t)BITBAND_PERIPH(&USART1->SR, USART_SR_TC_Pos);
|
||||
|
||||
switch (n) {
|
||||
case 1U:
|
||||
USART2TxData(data, length);
|
||||
USART1TxData(data, length);
|
||||
*tc = 0;
|
||||
|
||||
if (flush) {
|
||||
while (!RINGBUFF_EMPTY(txBuffer2) || !tc)
|
||||
while (!RINGBUFF_EMPTY(txBuffer1) || !tc)
|
||||
;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "YSFRX.h"
|
||||
|
|
41
YSFTX.cpp
41
YSFTX.cpp
|
@ -17,36 +17,27 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
// #define WANT_DEBUG
|
||||
|
||||
#include "Config.h"
|
||||
#include "Globals.h"
|
||||
#include "YSFTX.h"
|
||||
|
||||
#include "YSFDefines.h"
|
||||
|
||||
#if defined(WIDE_C4FSK_FILTERS_TX)
|
||||
// Generated using rcosdesign(0.2, 4, 5, 'sqrt') in MATLAB
|
||||
static q15_t YSF_C4FSK_FILTER[] = {0, 0, 0, 0, 688, -680, -2158, -3060, -2724, -775, 2684, 7041, 11310, 14425, 15565, 14425,
|
||||
11310, 7041, 2684, -775, -2724, -3060, -2158, -680, 688}; // numTaps = 25, L = 5
|
||||
const uint16_t YSF_C4FSK_FILTER_PHASE_LEN = 5U; // phaseLength = numTaps/L
|
||||
#else
|
||||
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
|
||||
static q15_t YSF_C4FSK_FILTER[] = {0, 0, 0, 0, 401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
|
||||
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
|
||||
-553, -847, -731, -340, 104, 401}; // numTaps = 45, L = 5
|
||||
const uint16_t YSF_C4FSK_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||
#endif
|
||||
static q15_t RRC_0_2_FILTER[] = {0, 0, 0, 0, 850, 219, -720, -1548, -1795, -1172, 237, 1927, 3120, 3073, 1447, -1431, -4544, -6442,
|
||||
-5735, -1633, 5651, 14822, 23810, 30367, 32767, 30367, 23810, 14822, 5651, -1633, -5735, -6442,
|
||||
-4544, -1431, 1447, 3073, 3120, 1927, 237, -1172, -1795, -1548, -720, 219, 850}; // numTaps = 45, L = 5
|
||||
const uint16_t RRC_0_2_FILTER_PHASE_LEN = 9U; // phaseLength = numTaps/L
|
||||
|
||||
const q15_t YSF_LEVELA_HI = 3900;
|
||||
const q15_t YSF_LEVELB_HI = 1300;
|
||||
const q15_t YSF_LEVELC_HI = -1300;
|
||||
const q15_t YSF_LEVELD_HI = -3900;
|
||||
const q15_t YSF_LEVELA_HI = 1893;
|
||||
const q15_t YSF_LEVELB_HI = 631;
|
||||
const q15_t YSF_LEVELC_HI = -631;
|
||||
const q15_t YSF_LEVELD_HI = -1893;
|
||||
|
||||
const q15_t YSF_LEVELA_LO = 1950;
|
||||
const q15_t YSF_LEVELB_LO = 650;
|
||||
const q15_t YSF_LEVELC_LO = -650;
|
||||
const q15_t YSF_LEVELD_LO = -1950;
|
||||
const q15_t YSF_LEVELA_LO = 948;
|
||||
const q15_t YSF_LEVELB_LO = 316;
|
||||
const q15_t YSF_LEVELC_LO = -316;
|
||||
const q15_t YSF_LEVELD_LO = -948;
|
||||
|
||||
const uint8_t YSF_START_SYNC = 0x77U;
|
||||
const uint8_t YSF_END_SYNC = 0xFFU;
|
||||
|
@ -63,10 +54,10 @@ m_loDev(false)
|
|||
{
|
||||
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
|
||||
|
||||
m_modFilter.L = YSF_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = YSF_C4FSK_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = YSF_C4FSK_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
m_modFilter.L = YSF_RADIO_SYMBOL_LENGTH;
|
||||
m_modFilter.phaseLength = RRC_0_2_FILTER_PHASE_LEN;
|
||||
m_modFilter.pCoeffs = RRC_0_2_FILTER;
|
||||
m_modFilter.pState = m_modState;
|
||||
}
|
||||
|
||||
void CYSFTX::process()
|
||||
|
|
Loading…
Reference in New Issue