Add POSAG

This commit is contained in:
Luca Marchesano 2018-07-24 09:33:57 +02:00 committed by GitHub
parent bd4c0c087c
commit 5690d4326c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1666 additions and 81 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,2018 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
@ -39,7 +39,7 @@
// #define USE_COS_AS_LOCKOUT
// Use pins to output the current mode
// #define ARDUINO_MODE_PINS
// #define MODE_PINS
// For the original Arduino Due pin layout
// #define ARDUINO_DUE_PAPA
@ -60,6 +60,9 @@
// Use separate mode pins to switch external filters/bandwidth for example
// #define STM32F4_NUCLEO_MODE_PINS
// For the VK6MST Pi3 Shield communicating over i2c. i2c address & speed defined in i2cTeensy.cpp
// #define VK6MST_TEENSY_PI3_SHIELD_I2C
// Pass RSSI information to the host
#define SEND_RSSI_DATA
@ -73,7 +76,13 @@
// Do not use if employing an external hardware watchdog
// #define CONSTANT_SRV_LED
//Select BOXCAR Filter into D-Star
// Use the YSF and P25 LEDs for NXDN
// #define USE_ALTERNATE_NXDN_LEDS
// Use the D-Star and DMR LEDs for POCSAG
// #define USE_ALTERNATE_POCSAG_LEDS
// Select BOXCAR Filter into D-Star
// #define DSTARBOXCAR
#endif

View File

@ -49,6 +49,7 @@ enum MMDVM_STATE {
STATE_YSF = 3,
STATE_P25 = 4,
STATE_NXDN = 5,
STATE_POCSAG = 6,
// Dummy states start at 90
STATE_NXDNCAL1K = 91,
@ -76,6 +77,7 @@ enum MMDVM_STATE {
#include "P25TX.h"
#include "NXDNRX.h"
#include "NXDNTX.h"
#include "POCSAGTX.h"
#include "CalDStarRX.h"
#include "CalDStarTX.h"
#include "CalDMR.h"
@ -102,6 +104,7 @@ extern bool m_dmrEnable;
extern bool m_ysfEnable;
extern bool m_p25Enable;
extern bool m_nxdnEnable;
extern bool m_pocsagEnable;
extern bool m_duplex;
@ -130,6 +133,8 @@ extern CP25TX p25TX;
extern CNXDNRX nxdnRX;
extern CNXDNTX nxdnTX;
extern CPOCSAGTX pocsagTX;
extern CCalDStarRX calDStarRX;
extern CCalDStarTX calDStarTX;
extern CCalDMR calDMR;

144
Globals.h.bak Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright (C) 2015,2016,2017,2018 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(GLOBALS_H)
#define GLOBALS_H
#if defined(STM32F4XX)
#include "stm32f4xx.h"
#elif defined(STM32F7XX)
#include "stm32f7xx.h"
#elif defined(STM32F105xC)
#include "stm32f1xx.h"
#include "STM32Utils.h"
#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>
enum MMDVM_STATE {
STATE_IDLE = 0,
STATE_DSTAR = 1,
STATE_DMR = 2,
STATE_YSF = 3,
STATE_P25 = 4,
STATE_NXDN = 5,
STATE_POCSAG = 6,
// Dummy states start at 90
STATE_NXDNCAL1K = 91,
STATE_DMRDMO1K = 92,
STATE_P25CAL1K = 93,
STATE_DMRCAL1K = 94,
STATE_LFCAL = 95,
STATE_RSSICAL = 96,
STATE_CWID = 97,
STATE_DMRCAL = 98,
STATE_DSTARCAL = 99
};
#include "SerialPort.h"
#include "DMRIdleRX.h"
#include "DMRDMORX.h"
#include "DMRDMOTX.h"
#include "DStarRX.h"
#include "DStarTX.h"
#include "DMRRX.h"
#include "DMRTX.h"
#include "YSFRX.h"
#include "YSFTX.h"
#include "P25RX.h"
#include "P25TX.h"
#include "NXDNRX.h"
#include "NXDNTX.h"
#include "CalDStarRX.h"
#include "CalDStarTX.h"
#include "CalDMR.h"
#include "CalP25.h"
#include "CalNXDN.h"
#include "CalRSSI.h"
#include "CWIdTX.h"
#include "Debug.h"
#include "IO.h"
const uint8_t MARK_SLOT1 = 0x08U;
const uint8_t MARK_SLOT2 = 0x04U;
const uint8_t MARK_NONE = 0x00U;
const uint16_t RX_BLOCK_SIZE = 2U;
const uint16_t TX_RINGBUFFER_SIZE = 1000U;
const uint16_t RX_RINGBUFFER_SIZE = 1200U;
extern MMDVM_STATE m_modemState;
extern bool m_dstarEnable;
extern bool m_dmrEnable;
extern bool m_ysfEnable;
extern bool m_p25Enable;
extern bool m_nxdnEnable;
extern bool m_duplex;
extern bool m_tx;
extern bool m_dcd;
extern CSerialPort serial;
extern CIO io;
extern CDStarRX dstarRX;
extern CDStarTX dstarTX;
extern CDMRIdleRX dmrIdleRX;
extern CDMRRX dmrRX;
extern CDMRTX dmrTX;
extern CDMRDMORX dmrDMORX;
extern CDMRDMOTX dmrDMOTX;
extern CYSFRX ysfRX;
extern CYSFTX ysfTX;
extern CP25RX p25RX;
extern CP25TX p25TX;
extern CNXDNRX nxdnRX;
extern CNXDNTX nxdnTX;
extern CCalDStarRX calDStarRX;
extern CCalDStarTX calDStarTX;
extern CCalDMR calDMR;
extern CCalP25 calP25;
extern CCalNXDN calNXDN;
extern CCalRSSI calRSSI;
extern CCWIdTX cwIdTX;
#endif

235
I2CTeensy.cpp Normal file
View File

@ -0,0 +1,235 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 28-4-2017 Created for MMDVM Pi shield for Teensy by Chris Huitema
*/
#include "Config.h"
#include "Globals.h"
#if defined(VK6MST_TEENSY_PI3_SHIELD_I2C)
#include <i2c_t3.h> //available here https://github.com/nox771/i2c_t3 or maybe the normal wire will work #include <wire.h> justs need to test i guess
#define I2C_ADDRESS 0x22
#define I2C_SPEED 100000
// Function prototypes
void receiveEvent(size_t count);
void requestEvent(void);
#define TX_FIFO_SIZE 512U
#define RX_FIFO_SIZE 512U
volatile uint8_t TXfifo[TX_FIFO_SIZE];
volatile uint8_t RXfifo[RX_FIFO_SIZE];
volatile uint16_t TXfifohead, TXfifotail;
volatile uint16_t RXfifohead, RXfifotail;
// Init queues
void TXfifoinit(void)
{
TXfifohead = 0U;
TXfifotail = 0U;
}
void RXfifoinit()
{
RXfifohead = 0U;
RXfifotail = 0U;
}
// How full is queue
uint16_t TXfifolevel(void)
{
uint32_t tail = TXfifotail;
uint32_t head = TXfifohead;
if (tail > head)
return TX_FIFO_SIZE + head - tail;
else
return head - tail;
}
uint16_t RXfifolevel(void)
{
uint32_t tail = RXfifotail;
uint32_t head = RXfifohead;
if (tail > head)
return RX_FIFO_SIZE + head - tail;
else
return head - tail;
}
uint8_t TXfifoput(uint8_t next)
{
if (TXfifolevel() < TX_FIFO_SIZE) {
TXfifo[TXfifohead] = next;
TXfifohead++;
if (TXfifohead >= TX_FIFO_SIZE)
TXfifohead = 0U;
return 1U;
} else {
return 0U; // signal an overflow occurred by returning a zero count
}
}
void I2Cbegin(void)
{
// Setup for Slave mode, address 0x22, pins 18/19, external pullups, speed in hz
Wire.begin(I2C_SLAVE, I2C_ADDRESS, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_SPEED);
// register events
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
// initialize the fifos
TXfifoinit();
RXfifoinit();
}
int I2Cavailable(void)
{
if (RXfifolevel() > 0U)
return 1U;
else
return 0U;
}
uint8_t I2Cread(void)
{
uint8_t data_c = RXfifo[RXfifotail];
RXfifotail++;
if (RXfifotail >= RX_FIFO_SIZE)
RXfifotail = 0U;
return data_c;
}
void I2Cwrite(const uint8_t* data, uint16_t length)
{
for (uint16_t i = 0U; i < length; i++)
TXfifoput(data[i]); //puts it in the fifo
}
//
// handle Rx Event (incoming I2C data)
//
void receiveEvent(size_t count)
{
for (uint16_t i = 0U; i < count; i++)
{
if (RXfifolevel() < RX_FIFO_SIZE) {
RXfifo[RXfifohead] = Wire.readByte();
if (RXfifo[RXfifohead] != -1){
RXfifohead++;
if (RXfifohead >= RX_FIFO_SIZE) RXfifohead = 0U;
}
} else {
Wire.readByte(); // drop data if mem full.
}
}
}
//
// handle Tx Event (outgoing I2C data)
//
void requestEvent(void)
{
if (TXfifolevel() > 0) {
if (Wire.write(TXfifo[TXfifotail])){ //write to i2c
TXfifotail++;
if (TXfifotail >= TX_FIFO_SIZE) TXfifotail = 0U;
}
}
}
/************************************/
void CSerialPort::beginInt(uint8_t n, int speed)
{
switch (n) {
case 1U:
return I2Cbegin();
case 3U:
Serial3.begin(speed);
break;
default:
break;
}
}
int CSerialPort::availableInt(uint8_t n)
{
switch (n) {
case 1U:
return I2Cavailable();
case 3U:
return Serial3.available();
default:
return false;
}
}
int CSerialPort::availableForWriteInt(uint8_t n)
{
switch (n) {
case 3U:
return Serial3.availableForWrite();
default:
return false;
}
}
uint8_t CSerialPort::readInt(uint8_t n)
{
switch (n) {
case 1U:
return I2Cread();
case 3U:
return Serial3.read();
default:
return 0U;
}
}
void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush)
{
switch (n) {
case 1U:
I2Cwrite(data, length);
break;
case 3U:
Serial3.write(data, length);
if (flush)
Serial3.flush();
break;
default:
break;
}
}
#endif

68
IO.cpp
View File

@ -89,6 +89,7 @@ m_dmrTXLevel(128 * 128),
m_ysfTXLevel(128 * 128),
m_p25TXLevel(128 * 128),
m_nxdnTXLevel(128 * 128),
m_pocsagTXLevel(128 * 128),
m_rxDCOffset(DC_OFFSET),
m_txDCOffset(DC_OFFSET),
m_ledCount(0U),
@ -148,22 +149,24 @@ void CIO::selfTest()
// We exclude PTT to avoid trigger the transmitter
setLEDInt(ledValue);
setCOSInt(ledValue);
#if defined(ARDUINO_MODE_PINS)
#if defined(MODE_PINS)
setDStarInt(ledValue);
setDMRInt(ledValue);
setYSFInt(ledValue);
setP25Int(ledValue);
setNXDNInt(ledValue);
setPOCSAGInt(ledValue);
#endif
delayInt(250);
}
#if defined(ARDUINO_MODE_PINS)
#if defined(MODE_PINS)
setDStarInt(true);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -172,6 +175,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -180,6 +184,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -188,6 +193,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -196,6 +202,25 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
setPOCSAGInt(true);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
setPOCSAGInt(false);
delayInt(250);
@ -204,6 +229,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -212,6 +238,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -220,6 +247,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -228,6 +256,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@ -236,6 +265,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
#endif
}
@ -503,6 +533,9 @@ void CIO::write(MMDVM_STATE mode, q15_t* samples, uint16_t length, const uint8_t
case STATE_NXDN:
txLevel = m_nxdnTXLevel;
break;
case STATE_POCSAG:
txLevel = m_pocsagTXLevel;
break;
default:
txLevel = m_cwIdTXLevel;
break;
@ -544,26 +577,28 @@ void CIO::setADCDetection(bool detect)
void CIO::setMode()
{
#if defined(ARDUINO_MODE_PINS)
#if defined(MODE_PINS)
setDStarInt(m_modemState == STATE_DSTAR);
setDMRInt(m_modemState == STATE_DMR);
setYSFInt(m_modemState == STATE_YSF);
setP25Int(m_modemState == STATE_P25);
setNXDNInt(m_modemState == STATE_NXDN);
setPOCSAGInt(m_modemState == STATE_POCSAG);
#endif
}
void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, int16_t txDCOffset, int16_t rxDCOffset)
void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, int16_t txDCOffset, int16_t rxDCOffset)
{
m_pttInvert = pttInvert;
m_rxLevel = q15_t(rxLevel * 128);
m_cwIdTXLevel = q15_t(cwIdTXLevel * 128);
m_dstarTXLevel = q15_t(dstarTXLevel * 128);
m_dmrTXLevel = q15_t(dmrTXLevel * 128);
m_ysfTXLevel = q15_t(ysfTXLevel * 128);
m_p25TXLevel = q15_t(p25TXLevel * 128);
m_nxdnTXLevel = q15_t(nxdnTXLevel * 128);
m_rxLevel = q15_t(rxLevel * 128);
m_cwIdTXLevel = q15_t(cwIdTXLevel * 128);
m_dstarTXLevel = q15_t(dstarTXLevel * 128);
m_dmrTXLevel = q15_t(dmrTXLevel * 128);
m_ysfTXLevel = q15_t(ysfTXLevel * 128);
m_p25TXLevel = q15_t(p25TXLevel * 128);
m_nxdnTXLevel = q15_t(nxdnTXLevel * 128);
m_pocsagTXLevel = q15_t(pocsagTXLevel * 128);
m_rxDCOffset = DC_OFFSET + rxDCOffset;
m_txDCOffset = DC_OFFSET + txDCOffset;
@ -572,11 +607,12 @@ void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rx
m_rxLevel = -m_rxLevel;
if (txInvert) {
m_dstarTXLevel = -m_dstarTXLevel;
m_dmrTXLevel = -m_dmrTXLevel;
m_ysfTXLevel = -m_ysfTXLevel;
m_p25TXLevel = -m_p25TXLevel;
m_nxdnTXLevel = -m_nxdnTXLevel;
m_dstarTXLevel = -m_dstarTXLevel;
m_dmrTXLevel = -m_dmrTXLevel;
m_ysfTXLevel = -m_ysfTXLevel;
m_p25TXLevel = -m_p25TXLevel;
m_nxdnTXLevel = -m_nxdnTXLevel;
m_pocsagTXLevel = -m_pocsagTXLevel;
}
}

652
IO.cpp.bak Normal file
View File

@ -0,0 +1,652 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015 by Jim Mclaughlin KI6ZUM
* Copyright (C) 2016 by Colin Durbridge G4EML
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Config.h"
#include "Globals.h"
#include "IO.h"
// Generated using [b, a] = butter(1, 0.0005) in MATLAB
static q31_t DC_FILTER[] = {1685306, 0, 1685306, 0, 2144113034, 0}; // {b0, 0, b1, b2, -a1, -a2}
const uint32_t DC_FILTER_STAGES = 1U; // One Biquad stage
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
static q15_t RRC_0_2_FILTER[] = {284, 198, 73, -78, -240, -393, -517, -590, -599, -533, -391, -181, 79, 364, 643, 880, 1041, 1097, 1026, 819,
483, 39, -477, -1016, -1516, -1915, -2150, -2164, -1914, -1375, -545, 557, 1886, 3376, 4946, 6502, 7946, 9184,
10134, 10731, 10935, 10731, 10134, 9184, 7946, 6502, 4946, 3376, 1886, 557, -545, -1375, -1914, -2164, -2150,
-1915, -1516, -1016, -477, 39, 483, 819, 1026, 1097, 1041, 880, 643, 364, 79, -181, -391, -533, -599, -590,
-517, -393, -240, -78, 73, 198, 284, 0};
const uint16_t RRC_0_2_FILTER_LEN = 82U;
// Generated using rcosdesign(0.2, 8, 20, 'sqrt') in MATLAB
static q15_t NXDN_0_2_FILTER[] = {201, 174, 140, 99, 52, 0, -55, -112, -170, -226, -278, -325, -365, -397, -417, -427, -424, -407, -377, -333, -277, -208,
-128, -40, 56, 156, 258, 358, 455, 544, 622, 687, 736, 766, 775, 762, 725, 664, 579, 471, 342, 193, 27, -151, -338, -528,
-718, -901, -1072, -1225, -1354, -1454, -1520, -1547, -1530, -1466, -1353, -1189, -972, -704, -385, -18, 394, 846, 1333,
1850, 2388, 2940, 3498, 4053, 4598, 5122, 5619, 6079, 6494, 6859, 7166, 7410, 7588, 7696, 7732, 7696, 7588, 7410, 7166,
6859, 6494, 6079, 5619, 5122, 4598, 4053, 3498, 2940, 2388, 1850, 1333, 846, 394, -18, -385, -704, -972, -1189, -1353,
-1466, -1530, -1547, -1520, -1454, -1354, -1225, -1072, -901, -718, -528, -338, -151, 27, 193, 342, 471, 579, 664, 725,
762, 775, 766, 736, 687, 622, 544, 455, 358, 258, 156, 56, -40, -128, -208, -277, -333, -377, -407, -424, -427, -417, -397,
-365, -325, -278, -226, -170, -112, -55, 0, 52, 99, 140, 174, 201, 0};
const uint16_t NXDN_0_2_FILTER_LEN = 162U;
static q15_t NXDN_ISINC_FILTER[] = {7616, -1333, -1856, -2611, -3399, -4006, -4230, -3918, -2988, -1458, 561, 2867, 5200, 7276, 8832, 9665,
9665, 8832, 7276, 5200, 2867, 561, -1458, -2988, -3918, -4230, -4006, -3399, -2611, -1856, -1333, 7616};
const uint16_t NXDN_ISINC_FILTER_LEN = 32U;
#if !defined (DSTARBOXCAR)
// Generated using gaussfir(0.5, 4, 10) in MATLAB
static q15_t GAUSSIAN_0_5_FILTER[] = {1, 4, 15, 52, 151, 380, 832, 1579, 2599, 3710, 4594, 4933, 4594, 3710, 2599, 1579, 832, 380, 151, 52, 15, 4, 1, 0};
const uint16_t GAUSSIAN_0_5_FILTER_LEN = 24U;
#endif
// One symbol boxcar filter
static q15_t BOXCAR_FILTER[] = {6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 0, 0};
const uint16_t BOXCAR_FILTER_LEN = 12U;
const uint16_t DC_OFFSET = 2048U;
CIO::CIO() :
m_started(false),
m_rxBuffer(RX_RINGBUFFER_SIZE),
m_txBuffer(TX_RINGBUFFER_SIZE),
m_rssiBuffer(RX_RINGBUFFER_SIZE),
m_dcFilter(),
m_dcState(),
m_rrcFilter(),
#if !defined (DSTARBOXCAR)
m_gaussianFilter(),
#endif
m_boxcarFilter(),
m_nxdnFilter(),
m_nxdnISincFilter(),
m_rrcState(),
#if !defined (DSTARBOXCAR)
m_gaussianState(),
#endif
m_boxcarState(),
m_nxdnState(),
m_nxdnISincState(),
m_pttInvert(false),
m_rxLevel(128 * 128),
m_cwIdTXLevel(128 * 128),
m_dstarTXLevel(128 * 128),
m_dmrTXLevel(128 * 128),
m_ysfTXLevel(128 * 128),
m_p25TXLevel(128 * 128),
m_nxdnTXLevel(128 * 128),
m_pocsagTXLevel(128 * 128),
m_rxDCOffset(DC_OFFSET),
m_txDCOffset(DC_OFFSET),
m_ledCount(0U),
m_ledValue(true),
m_detect(false),
m_adcOverflow(0U),
m_dacOverflow(0U),
m_watchdog(0U),
m_lockout(false)
{
::memset(m_rrcState, 0x00U, 140U * sizeof(q15_t));
#if !defined (DSTARBOXCAR)
::memset(m_gaussianState, 0x00U, 80U * sizeof(q15_t));
#endif
::memset(m_boxcarState, 0x00U, 60U * sizeof(q15_t));
::memset(m_nxdnState, 0x00U, 220U * sizeof(q15_t));
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
m_dcFilter.numStages = DC_FILTER_STAGES;
m_dcFilter.pState = m_dcState;
m_dcFilter.pCoeffs = DC_FILTER;
m_dcFilter.postShift = 0;
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
m_rrcFilter.pState = m_rrcState;
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
#if !defined (DSTARBOXCAR)
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
m_gaussianFilter.pState = m_gaussianState;
m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER;
#endif
m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN;
m_boxcarFilter.pState = m_boxcarState;
m_boxcarFilter.pCoeffs = BOXCAR_FILTER;
m_nxdnFilter.numTaps = NXDN_0_2_FILTER_LEN;
m_nxdnFilter.pState = m_nxdnState;
m_nxdnFilter.pCoeffs = NXDN_0_2_FILTER;
m_nxdnISincFilter.numTaps = NXDN_ISINC_FILTER_LEN;
m_nxdnISincFilter.pState = m_nxdnISincState;
m_nxdnISincFilter.pCoeffs = NXDN_ISINC_FILTER;
initInt();
selfTest();
}
void CIO::selfTest()
{
bool ledValue = false;
for (uint8_t i = 0; i < 6; i++) {
ledValue = !ledValue;
// We exclude PTT to avoid trigger the transmitter
setLEDInt(ledValue);
setCOSInt(ledValue);
#if defined(MODE_PINS)
setDStarInt(ledValue);
setDMRInt(ledValue);
setYSFInt(ledValue);
setP25Int(ledValue);
setNXDNInt(ledValue);
setPOCSAGInt(ledValue);
#endif
delayInt(250);
}
#if defined(MODE_PINS)
setDStarInt(true);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
setPOCSAGInt(true);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(true);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(true);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(true);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
setDStarInt(false);
setDMRInt(false);
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
#endif
}
void CIO::start()
{
if (m_started)
return;
startInt();
m_started = true;
setMode();
}
void CIO::process()
{
m_ledCount++;
if (m_started) {
// Two seconds timeout
if (m_watchdog >= 96000U) {
if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF || m_modemState == STATE_P25 || m_modemState == STATE_NXDN) {
if (m_modemState == STATE_DMR && m_tx)
dmrTX.setStart(false);
m_modemState = STATE_IDLE;
setMode();
}
m_watchdog = 0U;
}
#if defined(CONSTANT_SRV_LED)
setLEDInt(true);
#else
if (m_ledCount >= 48000U) {
m_ledCount = 0U;
m_ledValue = !m_ledValue;
setLEDInt(m_ledValue);
}
#endif
} else {
if (m_ledCount >= 480000U) {
m_ledCount = 0U;
m_ledValue = !m_ledValue;
setLEDInt(m_ledValue);
}
return;
}
#if defined(USE_COS_AS_LOCKOUT)
m_lockout = getCOSInt();
#endif
// Switch off the transmitter if needed
if (m_txBuffer.getData() == 0U && m_tx) {
m_tx = false;
setPTTInt(m_pttInvert ? true : false);
}
if (m_rxBuffer.getData() >= RX_BLOCK_SIZE) {
q15_t samples[RX_BLOCK_SIZE];
uint8_t control[RX_BLOCK_SIZE];
uint16_t rssi[RX_BLOCK_SIZE];
for (uint16_t i = 0U; i < RX_BLOCK_SIZE; i++) {
uint16_t sample;
m_rxBuffer.get(sample, control[i]);
m_rssiBuffer.get(rssi[i]);
// Detect ADC overflow
if (m_detect && (sample == 0U || sample == 4095U))
m_adcOverflow++;
q15_t res1 = q15_t(sample) - m_rxDCOffset;
q31_t res2 = res1 * m_rxLevel;
samples[i] = q15_t(__SSAT((res2 >> 15), 16));
}
if (m_lockout)
return;
#if defined(USE_DCBLOCKER)
q31_t q31Samples[RX_BLOCK_SIZE];
::arm_q15_to_q31(samples, q31Samples, RX_BLOCK_SIZE);
q31_t dcValues[RX_BLOCK_SIZE];
::arm_biquad_cascade_df1_q31(&m_dcFilter, q31Samples, dcValues, RX_BLOCK_SIZE);
q31_t dcLevel = 0;
for (uint8_t i = 0U; i < RX_BLOCK_SIZE; i++)
dcLevel += dcValues[i];
dcLevel /= RX_BLOCK_SIZE;
q15_t offset = q15_t(__SSAT((dcLevel >> 16), 16));;
q15_t dcSamples[RX_BLOCK_SIZE];
for (uint8_t i = 0U; i < RX_BLOCK_SIZE; i++)
dcSamples[i] = samples[i] - offset;
#endif
if (m_modemState == STATE_IDLE) {
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#endif
#else
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
#endif
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
if (m_p25Enable) {
q15_t P25Vals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
#endif
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
if (m_nxdnEnable) {
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
#endif
q15_t NXDNVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
}
if (m_dmrEnable || m_ysfEnable) {
q15_t RRCVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_rrcFilter, samples, RRCVals, RX_BLOCK_SIZE);
if (m_ysfEnable)
ysfRX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
if (m_dmrEnable) {
if (m_duplex)
dmrIdleRX.samples(RRCVals, RX_BLOCK_SIZE);
else
dmrDMORX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
}
}
} else if (m_modemState == STATE_DSTAR) {
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#endif
#else
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
#endif
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DMR) {
if (m_dmrEnable) {
q15_t DMRVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_rrcFilter, samples, DMRVals, RX_BLOCK_SIZE);
if (m_duplex) {
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
if (m_tx)
dmrRX.samples(DMRVals, rssi, control, RX_BLOCK_SIZE);
else
dmrIdleRX.samples(DMRVals, RX_BLOCK_SIZE);
} else {
dmrDMORX.samples(DMRVals, rssi, RX_BLOCK_SIZE);
}
}
} else if (m_modemState == STATE_YSF) {
if (m_ysfEnable) {
q15_t YSFVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_rrcFilter, dcSamples, YSFVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_rrcFilter, samples, YSFVals, RX_BLOCK_SIZE);
#endif
ysfRX.samples(YSFVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_P25) {
if (m_p25Enable) {
q15_t P25Vals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
#endif
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_NXDN) {
if (m_nxdnEnable) {
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
#endif
q15_t NXDNVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DSTARCAL) {
q15_t GMSKVals[RX_BLOCK_SIZE];
#if !defined (DSTARBOXCAR)
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE);
} else if (m_modemState == STATE_RSSICAL) {
calRSSI.samples(rssi, RX_BLOCK_SIZE);
}
}
}
void CIO::write(MMDVM_STATE mode, q15_t* samples, uint16_t length, const uint8_t* control)
{
if (!m_started)
return;
if (m_lockout)
return;
// Switch the transmitter on if needed
if (!m_tx) {
m_tx = true;
setPTTInt(m_pttInvert ? false : true);
}
q15_t txLevel = 0;
switch (mode) {
case STATE_DSTAR:
txLevel = m_dstarTXLevel;
break;
case STATE_DMR:
txLevel = m_dmrTXLevel;
break;
case STATE_YSF:
txLevel = m_ysfTXLevel;
break;
case STATE_P25:
txLevel = m_p25TXLevel;
break;
case STATE_NXDN:
txLevel = m_nxdnTXLevel;
break;
case STATE_POCSAG:
txLevel = m_pocsagTXLevel;
break;
default:
txLevel = m_cwIdTXLevel;
break;
}
for (uint16_t i = 0U; i < length; i++) {
q31_t res1 = samples[i] * txLevel;
q15_t res2 = q15_t(__SSAT((res1 >> 15), 16));
uint16_t res3 = uint16_t(res2 + m_txDCOffset);
// Detect DAC overflow
if (res3 > 4095U)
m_dacOverflow++;
if (control == NULL)
m_txBuffer.put(res3, MARK_NONE);
else
m_txBuffer.put(res3, control[i]);
}
}
uint16_t CIO::getSpace() const
{
return m_txBuffer.getSpace();
}
void CIO::setDecode(bool dcd)
{
if (dcd != m_dcd)
setCOSInt(dcd ? true : false);
m_dcd = dcd;
}
void CIO::setADCDetection(bool detect)
{
m_detect = detect;
}
void CIO::setMode()
{
#if defined(MODE_PINS)
setDStarInt(m_modemState == STATE_DSTAR);
setDMRInt(m_modemState == STATE_DMR);
setYSFInt(m_modemState == STATE_YSF);
setP25Int(m_modemState == STATE_P25);
setNXDNInt(m_modemState == STATE_NXDN);
setPOCSAGInt(m_modemState == STATE_POCSAG);
#endif
}
void CIO::setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, int16_t txDCOffset, int16_t rxDCOffset)
{
m_pttInvert = pttInvert;
m_rxLevel = q15_t(rxLevel * 128);
m_cwIdTXLevel = q15_t(cwIdTXLevel * 128);
m_dstarTXLevel = q15_t(dstarTXLevel * 128);
m_dmrTXLevel = q15_t(dmrTXLevel * 128);
m_ysfTXLevel = q15_t(ysfTXLevel * 128);
m_p25TXLevel = q15_t(p25TXLevel * 128);
m_nxdnTXLevel = q15_t(nxdnTXLevel * 128);
m_pocsagTXLevel = q15_t(pocsagTXLevel * 128);
m_rxDCOffset = DC_OFFSET + rxDCOffset;
m_txDCOffset = DC_OFFSET + txDCOffset;
if (rxInvert)
m_rxLevel = -m_rxLevel;
if (txInvert) {
m_dstarTXLevel = -m_dstarTXLevel;
m_dmrTXLevel = -m_dmrTXLevel;
m_ysfTXLevel = -m_ysfTXLevel;
m_p25TXLevel = -m_p25TXLevel;
m_nxdnTXLevel = -m_nxdnTXLevel;
m_pocsagTXLevel = -m_pocsagTXLevel;
}
}
void CIO::getOverflow(bool& adcOverflow, bool& dacOverflow)
{
adcOverflow = m_adcOverflow > 0U;
dacOverflow = m_dacOverflow > 0U;
m_adcOverflow = 0U;
m_dacOverflow = 0U;
}
bool CIO::hasTXOverflow()
{
return m_txBuffer.hasOverflowed();
}
bool CIO::hasRXOverflow()
{
return m_rxBuffer.hasOverflowed();
}
void CIO::resetWatchdog()
{
m_watchdog = 0U;
}
uint32_t CIO::getWatchdog()
{
return m_watchdog;
}
bool CIO::hasLockout() const
{
return m_lockout;
}

4
IO.h
View File

@ -42,7 +42,7 @@ public:
void interrupt();
void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnLevel, int16_t txDCOffset, int16_t rxDCOffset);
void setParameters(bool rxInvert, bool txInvert, bool pttInvert, uint8_t rxLevel, uint8_t cwIdTXLevel, uint8_t dstarTXLevel, uint8_t dmrTXLevel, uint8_t ysfTXLevel, uint8_t p25TXLevel, uint8_t nxdnTXLevel, uint8_t pocsagTXLevel, int16_t txDCOffset, int16_t rxDCOffset);
void getOverflow(bool& adcOverflow, bool& dacOverflow);
@ -89,6 +89,7 @@ private:
q15_t m_ysfTXLevel;
q15_t m_p25TXLevel;
q15_t m_nxdnTXLevel;
q15_t m_pocsagTXLevel;
uint16_t m_rxDCOffset;
uint16_t m_txDCOffset;
@ -120,6 +121,7 @@ private:
void setYSFInt(bool on);
void setP25Int(bool on);
void setNXDNInt(bool on);
void setPOCSAGInt(bool on);
void delayInt(unsigned int dly);
};

View File

@ -34,6 +34,7 @@
#define PIN_YSF 18
#define PIN_P25 19
#define PIN_NXDN 20
#define PIN_POCSAG 4
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
#define ADC_CDR_Chan 7
@ -48,6 +49,7 @@
#define PIN_YSF 7
#define PIN_P25 6
#define PIN_NXDN 5
#define PIN_POCSAG 4
#define ADC_CHER_Chan (1<<13) // ADC on Due pin A11 - Due AD13 - (1 << 13)
#define ADC_ISR_EOC_Chan ADC_ISR_EOC13
#define ADC_CDR_Chan 13
@ -64,6 +66,7 @@
#define PIN_YSF 7
#define PIN_P25 6
#define PIN_NXDN 5
#define PIN_POCSAG 4
#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7)
#define ADC_ISR_EOC_Chan ADC_ISR_EOC7
#define ADC_CDR_Chan 7
@ -92,14 +95,19 @@ void CIO::initInt()
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_COS, INPUT);
#if defined(ARDUINO_MODE_PINS)
#if defined(MODE_PINS)
// Set up the mode output pins
pinMode(PIN_DSTAR, OUTPUT);
pinMode(PIN_DMR, OUTPUT);
pinMode(PIN_YSF, OUTPUT);
pinMode(PIN_P25, OUTPUT);
#if !defined(USE_ALTERNATE_NXDN_LEDS)
pinMode(PIN_NXDN, OUTPUT);
#endif
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
pinMode(PIN_POCSAG, OUTPUT);
#endif
#endif
}
void CIO::startInt()
@ -232,7 +240,22 @@ void CIO::setP25Int(bool on)
void CIO::setNXDNInt(bool on)
{
#if defined(USE_ALTERNATE_NXDN_LEDS)
digitalWrite(PIN_YSF, on ? HIGH : LOW);
digitalWrite(PIN_P25, on ? HIGH : LOW);
#else
digitalWrite(PIN_NXDN, on ? HIGH : LOW);
#endif
}
void CIO::setPOCSAGInt(bool on)
{
#if defined(USE_ALTERNATE_POCSAG_LEDS)
digitalWrite(PIN_DSTAR, on ? HIGH : LOW);
digitalWrite(PIN_DMR, on ? HIGH : LOW);
#else
digitalWrite(PIN_POCSAG, on ? HIGH : LOW);
#endif
}
void CIO::delayInt(unsigned int dly)

162
IOSTM.cpp
View File

@ -113,6 +113,7 @@ DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
POCSAG PB12 output
RX PA0 analog input
RSSI PA7 analog input
@ -145,6 +146,10 @@ EXT_CLK PA15 input
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_7
#define PORT_DSTAR GPIOC
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOC
@ -188,6 +193,7 @@ DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
POCSAG PB12 output
RX PA0 analog input
RSSI PA7 analog input
@ -220,6 +226,10 @@ EXT_CLK PA15 input
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_7
#define PORT_DSTAR GPIOC
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOC
@ -263,6 +273,7 @@ DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
POCSAG PB12 output
RX PA0 analog input
RSSI PA7 analog input
@ -295,6 +306,10 @@ EXT_CLK PA15 input
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_7
#define PORT_DSTAR GPIOC
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOC
@ -338,6 +353,7 @@ DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
POCSAG PB12 output
RX PA0 analog input
RSSI PA7 analog input
@ -370,6 +386,10 @@ EXT_CLK PA15 input
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_7
#define PORT_DSTAR GPIOC
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOC
@ -399,6 +419,85 @@ EXT_CLK PA15 input
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#elif defined(STM32F722_F7HAT)
/*
Pin definitions for MMDVM-F7Hat Pi-Hat F0DEI DB9MAT DF2ET board:
PTT PB14 output
COSLED PB13 output
LED PB12 output
COS PC0 input
DSTAR PB15 output
DMR PC6 output
YSF PC7 output
P25 PC8 output
NXDN PC9 output
RX PA0 analog input
RSSI PA7 analog input
TX PA4 analog output
EXT_CLK PA15 input
*/
#define PIN_COS GPIO_Pin_0
#define PORT_COS GPIOC
#define RCC_Per_COS RCC_AHB1Periph_GPIOC
#define PIN_PTT GPIO_Pin_14
#define PORT_PTT GPIOB
#define RCC_Per_PTT RCC_AHB1Periph_GPIOB
#define PIN_COSLED GPIO_Pin_13
#define PORT_COSLED GPIOB
#define RCC_Per_COSLED RCC_AHB1Periph_GPIOB
#define PIN_LED GPIO_Pin_12
#define PORT_LED GPIOB
#define RCC_Per_LED RCC_AHB1Periph_GPIOB
#define PIN_P25 GPIO_Pin_8
#define PORT_P25 GPIOC
#define RCC_Per_P25 RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_9
#define PORT_NXDN GPIOC
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOC
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_15
#define PORT_DSTAR GPIOB
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOB
#define PIN_DMR GPIO_Pin_6
#define PORT_DMR GPIOC
#define RCC_Per_DMR RCC_AHB1Periph_GPIOC
#define PIN_YSF GPIO_Pin_7
#define PORT_YSF GPIOC
#define RCC_Per_YSF RCC_AHB1Periph_GPIOC
#define PIN_EXT_CLK GPIO_Pin_15
#define SRC_EXT_CLK GPIO_PinSource15
#define PORT_EXT_CLK GPIOA
#define PIN_RX GPIO_Pin_0
#define PIN_RX_CH ADC_Channel_0
#define PORT_RX GPIOA
#define RCC_Per_RX RCC_AHB1Periph_GPIOA
#define PIN_RSSI GPIO_Pin_7
#define PIN_RSSI_CH ADC_Channel_7
#define PORT_RSSI GPIOA
#define RCC_Per_RSSI RCC_AHB1Periph_GPIOA
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#elif defined(STM32F4_NUCLEO)
#if defined(STM32F4_NUCLEO_MORPHO_HEADER)
@ -415,6 +514,7 @@ DMR PB4 output CN10 Pin27
YSF PB5 output CN10 Pin29
P25 PB3 output CN10 Pin31
NXDN PA10 output CN10 Pin33
POCSAG PB12 output
MDSTAR PC4 output CN10 Pin34
MDMR PC5 output CN10 Pin6
@ -453,6 +553,10 @@ EXT_CLK PA15 input CN7 Pin17
#define PORT_NXDN GPIOA
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOA
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_10
#define PORT_DSTAR GPIOB
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOB
@ -518,6 +622,7 @@ DMR PA4 output CN8 Pin3
YSF PB0 output CN8 Pin4
P25 PC1 output CN8 Pin5
NXDN PA3 output CN9 Pin1
POCSAG PB12 output
RX PA0 analog input CN8 Pin1
RSSI PC0 analog input CN8 Pin6
@ -550,6 +655,10 @@ EXT_CLK PB8 input CN5 Pin10
#define PORT_NXDN GPIOA
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOA
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_1
#define PORT_DSTAR GPIOA
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOA
@ -597,6 +706,7 @@ DMR PB4 output CN12 Pin27
YSF PB5 output CN12 Pin29
P25 PB3 output CN12 Pin31
NXDN PA10 output CN12 Pin33
POCSAG PB12 output CN12 Pin16
MDSTAR PC4 output CN12 Pin34
MDMR PC5 output CN12 Pin6
@ -635,6 +745,10 @@ EXT_CLK PA15 input CN11 Pin17
#define PORT_NXDN GPIOA
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOA
#define PIN_POCSAG GPIO_Pin_12
#define PORT_POCSAG GPIOB
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_10
#define PORT_DSTAR GPIOB
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOB
@ -812,7 +926,7 @@ void CIO::initInt()
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(PORT_COS, &GPIO_InitStruct);
#if defined(ARDUINO_MODE_PINS)
#if defined(MODE_PINS)
// DSTAR pin
RCC_AHB1PeriphClockCmd(RCC_Per_DSTAR, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_DSTAR;
@ -837,6 +951,7 @@ void CIO::initInt()
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_P25, &GPIO_InitStruct);
#if !defined(USE_ALTERNATE_NXDN_LEDS)
// NXDN pin
RCC_AHB1PeriphClockCmd(RCC_Per_NXDN, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_NXDN;
@ -844,6 +959,15 @@ void CIO::initInt()
GPIO_Init(PORT_NXDN, &GPIO_InitStruct);
#endif
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
// POCSAG pin
RCC_AHB1PeriphClockCmd(RCC_Per_POCSAG, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_POCSAG;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_POCSAG, &GPIO_InitStruct);
#endif
#endif
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
// DSTAR mode pin
RCC_AHB1PeriphClockCmd(RCC_Per_MDSTAR, ENABLE);
@ -869,12 +993,22 @@ void CIO::initInt()
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_MP25, &GPIO_InitStruct);
#if !defined(USE_ALTERNATE_NXDN_LEDS)
// NXDN mode pin
RCC_AHB1PeriphClockCmd(RCC_Per_MNXDN, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_MNXDN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_MNXDN, &GPIO_InitStruct);
#endif
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
// POCSAG mode pin
RCC_AHB1PeriphClockCmd(RCC_Per_MPOCSAG, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_MPOCSAG;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Init(PORT_MPOCSAG, &GPIO_InitStruct);
#endif
#endif
}
void CIO::startInt()
@ -1115,10 +1249,36 @@ void CIO::setP25Int(bool on)
void CIO::setNXDNInt(bool on)
{
#if defined(USE_ALTERNATE_NXDN_LEDS)
GPIO_WriteBit(PORT_YSF, PIN_YSF, on ? Bit_SET : Bit_RESET);
GPIO_WriteBit(PORT_P25, PIN_P25, on ? Bit_SET : Bit_RESET);
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
GPIO_WriteBit(PORT_MYSF, PIN_MYSF, on ? Bit_SET : Bit_RESET);
GPIO_WriteBit(PORT_MP25, PIN_MP25, on ? Bit_SET : Bit_RESET);
#endif
#else
GPIO_WriteBit(PORT_NXDN, PIN_NXDN, on ? Bit_SET : Bit_RESET);
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
GPIO_WriteBit(PORT_MNXDN, PIN_MNXDN, on ? Bit_SET : Bit_RESET);
#endif
#endif
}
void CIO::setPOCSAGInt(bool on)
{
#if defined(USE_ALTERNATE_POCSAG_LEDS)
GPIO_WriteBit(PORT_DSTAR, PIN_DSTAR, on ? Bit_SET : Bit_RESET);
GPIO_WriteBit(PORT_DMR, PIN_DMR, on ? Bit_SET : Bit_RESET);
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
GPIO_WriteBit(PORT_MDSTAR, PIN_MDSTAR, on ? Bit_SET : Bit_RESET);
GPIO_WriteBit(PORT_MDMR, PIN_MDMR, on ? Bit_SET : Bit_RESET);
#endif
#else
GPIO_WriteBit(PORT_POCSAG, PIN_POCSAG, on ? Bit_SET : Bit_RESET);
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
GPIO_WriteBit(PORT_MPOCSAG, PIN_MPOCSAG, on ? Bit_SET : Bit_RESET);
#endif
#endif
}
// Simple delay function for STM32

View File

@ -40,6 +40,7 @@ DMR PB6 output
YSF PB8 output
P25 PB9 output
NXDN PB10 output
POCSAG PB11 output
RX PB0 analog input (ADC1_8)
RSSI PB1 analog input (ADC2_9)
@ -80,6 +81,9 @@ USART1_RXD PA10 input (AF)
#define PIN_NXDN 10
#define PORT_NXDN GPIOB
#define BB_NXDN *((bitband_t)BITBAND_PERIPH(&PORT_NXDN->ODR, PIN_NXDN))
#define PIN_POCSAG 11
#define PORT_POCSAG GPIOB
#define BB_POCSAG *((bitband_t)BITBAND_PERIPH(&PORT_POCSAG->ODR, PIN_POCSAG))
#define PIN_RX 0
#define PIN_RX_ADC_CH 8
@ -209,16 +213,21 @@ static inline void GPIOInit()
GPIOD->ODR = 0;
// configure ports
GPIOConfigPin(PORT_PTT, PIN_PTT, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_PTT, PIN_PTT, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_COSLED, PIN_COSLED, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_LED, PIN_LED, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_COS, PIN_COS, GPIO_CRL_CNF0_1);
GPIOConfigPin(PORT_LED, PIN_LED, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_COS, PIN_COS, GPIO_CRL_CNF0_1);
GPIOConfigPin(PORT_DSTAR, PIN_DSTAR, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_DMR, PIN_DMR, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_YSF, PIN_YSF, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_P25, PIN_P25, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_NXDN, PIN_NXDN, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_DSTAR, PIN_DSTAR, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_DMR, PIN_DMR, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_YSF, PIN_YSF, GPIO_CRL_MODE0_1);
GPIOConfigPin(PORT_P25, PIN_P25, GPIO_CRL_MODE0_1);
#if !defined(USE_ALTERNATE_NXDN_LEDS)
GPIOConfigPin(PORT_NXDN, PIN_NXDN, GPIO_CRL_MODE0_1);
#endif
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
GPIOConfigPin(PORT_POCSAG, PIN_POCSAG, GPIO_CRL_MODE0_1);
#endif
GPIOConfigPin(PORT_RX, PIN_RX, 0);
#if defined(SEND_RSSI_DATA)
@ -431,7 +440,22 @@ void CIO::setP25Int(bool on)
void CIO::setNXDNInt(bool on)
{
#if defined(USE_ALTERNATE_NXDN_LEDS)
BB_YSF = !!on;
BB_P25 = !!on;
#else
BB_NXDN = !!on;
#endif
}
void CIO::setPOCSAGInt(bool on)
{
#if defined(USE_ALTERNATE_POCSAG_LEDS)
BB_DSTAR = !!on;
BB_DMR = !!on;
#else
BB_POCSAG = !!on;
#endif
}
void CIO::delayInt(unsigned int dly)

View File

@ -36,8 +36,10 @@
#define PIN_P25 12
#if defined(__MK20DX256__)
#define PIN_NXDN 2
#define PIN_POCSAG 3
#else
#define PIN_NXDN 24
#define PIN_POCSAG 25
#endif
#define PIN_ADC 5 // A0, Pin 14
#define PIN_RSSI 4 // Teensy 3.5/3.6, A16, Pin 35. Teensy 3.1/3.2, A17, Pin 28
@ -62,14 +64,19 @@ void CIO::initInt()
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_COS, INPUT);
#if defined(ARDUINO_MODE_PINS)
#if defined(MODE_PINS)
// Set up the mode output pins
pinMode(PIN_DSTAR, OUTPUT);
pinMode(PIN_DMR, OUTPUT);
pinMode(PIN_YSF, OUTPUT);
pinMode(PIN_P25, OUTPUT);
#if !defined(USE_ALTERNATE_NXDN_LEDS)
pinMode(PIN_NXDN, OUTPUT);
#endif
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
pinMode(PIN_POCSAG, OUTPUT);
#endif
#endif
}
void CIO::startInt()
@ -218,7 +225,22 @@ void CIO::setP25Int(bool on)
void CIO::setNXDNInt(bool on)
{
#if defined(USE_ALTERNATE_NXDN_LEDS)
digitalWrite(PIN_YSF, on ? HIGH : LOW);
digitalWrite(PIN_P25, on ? HIGH : LOW);
#else
digitalWrite(PIN_NXDN, on ? HIGH : LOW);
#endif
}
void CIO::setPOCSAGInt(bool on)
{
#if defined(USE_ALTERNATE_POCSAG_LEDS)
digitalWrite(PIN_DSTAR, on ? HIGH : LOW);
digitalWrite(PIN_DMR, on ? HIGH : LOW);
#else
digitalWrite(PIN_POCSAG, on ? HIGH : LOW);
#endif
}
void CIO::delayInt(unsigned int dly)

View File

@ -26,11 +26,12 @@
// Global variables
MMDVM_STATE m_modemState = STATE_IDLE;
bool m_dstarEnable = true;
bool m_dmrEnable = true;
bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_dstarEnable = true;
bool m_dmrEnable = true;
bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_pocsagEnable = true;
bool m_duplex = true;
@ -56,6 +57,8 @@ CP25TX p25TX;
CNXDNRX nxdnRX;
CNXDNTX nxdnTX;
CPOCSAGTX pocsagTX;
CCalDStarRX calDStarRX;
CCalDStarTX calDStarTX;
CCalDMR calDMR;
@ -99,6 +102,9 @@ void loop()
if (m_nxdnEnable && m_modemState == STATE_NXDN)
nxdnTX.process();
if (m_pocsagEnable && (m_modemState == STATE_POCSAG || pocsagTX.busy()))
pocsagTX.process();
if (m_modemState == STATE_DSTARCAL)
calDStarTX.process();

View File

@ -23,11 +23,12 @@
// Global variables
MMDVM_STATE m_modemState = STATE_IDLE;
bool m_dstarEnable = true;
bool m_dmrEnable = true;
bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_dstarEnable = true;
bool m_dmrEnable = true;
bool m_ysfEnable = true;
bool m_p25Enable = true;
bool m_nxdnEnable = true;
bool m_pocsagEnable = true;
bool m_duplex = true;
@ -53,6 +54,8 @@ CP25TX p25TX;
CNXDNRX nxdnRX;
CNXDNTX nxdnTX;
CPOCSAGTX pocsagTX;
CCalDStarRX calDStarRX;
CCalDStarTX calDStarTX;
CCalDMR calDMR;
@ -96,6 +99,9 @@ void loop()
if (m_nxdnEnable && m_modemState == STATE_NXDN)
nxdnTX.process();
if (m_pocsagEnable && (m_modemState == STATE_POCSAG || pocsagTX.busy()))
pocsagTX.process();
if (m_modemState == STATE_DSTARCAL)
calDStarTX.process();

View File

@ -247,9 +247,10 @@
<File name="CalNXDN.cpp" path="CalNXDN.cpp" type="1"/>
<File name="NXDNTX.cpp" path="NXDNTX.cpp" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" path="STM32F4XX_Lib/CMSIS/Include/core_cm4.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" type="1"/>
<File name="I2CTeensy.cpp" path="I2CTeensy.cpp" type="1"/>
<File name="YSFRX.h" path="YSFRX.h" type="1"/>
<File name="DMRSlotRX.h" path="DMRSlotRX.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source/stm32f4xx_tim.c" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include" path="" type="2"/>
<File name="NXDNRX.cpp" path="NXDNRX.cpp" type="1"/>
<File name="DMRDMORX.cpp" path="DMRDMORX.cpp" type="1"/>
@ -271,18 +272,21 @@
<File name="DMRRX.h" path="DMRRX.h" type="1"/>
<File name="MMDVM.cpp" path="MMDVM.cpp" type="1"/>
<File name="IOTeensy.cpp" path="IOTeensy.cpp" type="1"/>
<File name="POCSAGTX.cpp" path="POCSAGTX.cpp" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmSimd.h" type="1"/>
<File name="DMRDMORX.h" path="DMRDMORX.h" type="1"/>
<File name="GitVersion.h" path="GitVersion.h" type="1"/>
<File name="SerialPort.h" path="SerialPort.h" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" path="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/include/stm32f4xx_dac.h" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" type="1"/>
<File name="STM32F4XX_Lib/Device/system_stm32f4xx.h" path="STM32F4XX_Lib/Device/system_stm32f4xx.h" type="1"/>
<File name="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" path="STM32F4XX_Lib/CMSIS/Include/core_cmFunc.h" type="1"/>
<File name="CWIdTX.h" path="CWIdTX.h" type="1"/>
<File name="CalDStarTX.cpp" path="CalDStarTX.cpp" type="1"/>
<File name="STM32F4XX_Lib/STM32F4xx_StdPeriph_Driver/source" path="" type="2"/>
<File name="DMRDMOTX.h" path="DMRDMOTX.h" type="1"/>
<File name="IODue.cpp" path="IODue.cpp" type="1"/>
<File name="CalDMR.h" path="CalDMR.h" type="1"/>
<File name="POCSAGTX.h" path="POCSAGTX.h" type="1"/>
<File name="IODue.cpp" path="IODue.cpp" type="1"/>
<File name="DMRTX.cpp" path="DMRTX.cpp" type="1"/>
<File name="P25RX.cpp" path="P25RX.cpp" type="1"/>
<File name="CalRSSI.h" path="CalRSSI.h" type="1"/>

View File

@ -128,6 +128,8 @@ DEFS_NUCLEO_F767=-DUSE_HAL_DRIVER -DSTM32F767xx -DSTM32F7XX -DSTM32F7_NUCLEO -DH
DEFS_PI_F722=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_PI -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM-F7M F0DEI board:
DEFS_F7M=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_F7M -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM-F7-Hat F0DEI, DB9MAT, DF2ET board:
DEFS_F7HAT=-DUSE_HAL_DRIVER -DSTM32F722xx -DSTM32F7XX -DSTM32F722_F7HAT -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# STM32F4 DVM board:
DEFS_DVM=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_DVM -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
@ -148,7 +150,7 @@ CXXFLAGS=-Os -fno-exceptions -ffunction-sections -fdata-sections -fno-builtin -f
LDFLAGS=-Os --specs=nano.specs
# Build Rules
.PHONY: all release dis pi pi_f722 f4m nucleo f767 dvm clean
.PHONY: all release dis pi pi-f722 f4m nucleo f767 dvm clean
# Default target: Nucleo-64 F446RE board
all: nucleo
@ -177,6 +179,12 @@ f7m: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_F7M)
f7m: LDFLAGS+=$(LDFLAGS_F722)
f7m: release_f7
f7hat: GitVersion.h
f7hat: CFLAGS+=$(CFLAGS_F7) $(DEFS_F7HAT)
f7hat: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_F7HAT)
f7hat: LDFLAGS+=$(LDFLAGS_F722)
f7hat: release_f7
nucleo: GitVersion.h
nucleo: CFLAGS+=$(CFLAGS_F4) $(DEFS_NUCLEO)
nucleo: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_NUCLEO)
@ -336,7 +344,8 @@ ifneq ($(wildcard /usr/bin/stm32flash),)
/usr/bin/stm32flash -v -w bin/$(BINBIN_F7) -g 0x0 -R -c /dev/ttyAMA0
endif
deploy-f7m: deploy-pi-f7
deploy-f7m: deploy-pi-f7
deploy-f7hat: deploy-pi-f7
# Export the current git version if the index file exists, else 000...
GitVersion.h:

149
POCSAGTX.cpp Normal file
View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2009-2018 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Config.h"
#include "Globals.h"
#include "POCSAGTX.h"
const uint16_t POCSAG_FRAME_LENGTH_BYTES = 17U * sizeof(uint32_t);
const uint16_t POCSAG_PREAMBLE_LENGTH_BYTES = 18U * sizeof(uint32_t);
const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 40U; // at 48Khz
const q15_t POCSAG_LEVEL1[] = { 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700};
const q15_t POCSAG_LEVEL0[] = {-1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700, -1700};
static q15_t SHAPING_FILTER[] = {2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730, 2730};
const uint16_t SHAPING_FILTER_LEN = 12U;
const uint8_t POCSAG_SYNC = 0xAAU;
CPOCSAGTX::CPOCSAGTX() :
m_buffer(4000U),
m_modFilter(),
m_modState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(POCSAG_PREAMBLE_LENGTH_BYTES)
{
::memset(m_modState, 0x00U, 180U * sizeof(q15_t));
m_modFilter.numTaps = SHAPING_FILTER_LEN;
m_modFilter.pState = m_modState;
m_modFilter.pCoeffs = SHAPING_FILTER;
}
void CPOCSAGTX::process()
{
if (m_buffer.getData() == 0U && m_poLen == 0U)
return;
if (m_poLen == 0U) {
if (!m_tx) {
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = POCSAG_SYNC;
} else {
for (uint8_t i = 0U; i < POCSAG_FRAME_LENGTH_BYTES; i++) {
uint8_t c = m_buffer.get();
m_poBuffer[m_poLen++] = c;
}
}
m_poPtr = 0U;
}
if (m_poLen > 0U) {
uint16_t space = io.getSpace();
while (space > (8U * POCSAG_RADIO_SYMBOL_LENGTH)) {
uint8_t c = m_poBuffer[m_poPtr++];
writeByte(c);
space -= 8U * POCSAG_RADIO_SYMBOL_LENGTH;
if (m_poPtr >= m_poLen) {
m_poPtr = 0U;
m_poLen = 0U;
return;
}
}
}
}
bool CPOCSAGTX::busy()
{
if (m_poLen > 0U || m_buffer.getData() > 0U)
return true;
else
return false;
}
uint8_t CPOCSAGTX::writeData(const uint8_t* data, uint8_t length)
{
if (length != POCSAG_FRAME_LENGTH_BYTES)
return 4U;
uint16_t space = m_buffer.getSpace();
if (space < POCSAG_FRAME_LENGTH_BYTES)
return 5U;
for (uint8_t i = 0U; i < POCSAG_FRAME_LENGTH_BYTES; i++)
m_buffer.put(data[i]);
return 0U;
}
void CPOCSAGTX::writeByte(uint8_t c)
{
q15_t inBuffer[POCSAG_RADIO_SYMBOL_LENGTH * 8U];
q15_t outBuffer[POCSAG_RADIO_SYMBOL_LENGTH * 8U];
const uint8_t MASK = 0x80U;
uint8_t n = 0U;
for (uint8_t i = 0U; i < 8U; i++, c <<= 1, n += POCSAG_RADIO_SYMBOL_LENGTH) {
switch (c & MASK) {
case 0x80U:
::memcpy(inBuffer + n, POCSAG_LEVEL1, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
break;
default:
::memcpy(inBuffer + n, POCSAG_LEVEL0, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t));
break;
}
}
::arm_fir_fast_q15(&m_modFilter, inBuffer, outBuffer, POCSAG_RADIO_SYMBOL_LENGTH * 8U);
io.write(STATE_POCSAG, outBuffer, POCSAG_RADIO_SYMBOL_LENGTH * 8U);
}
void CPOCSAGTX::setTXDelay(uint8_t delay)
{
m_txDelay = POCSAG_PREAMBLE_LENGTH_BYTES + (delay * 3U) / 2U;
if (m_txDelay > 150U)
m_txDelay = 150U;
}
uint8_t CPOCSAGTX::getSpace() const
{
return m_buffer.getSpace() / POCSAG_FRAME_LENGTH_BYTES;
}

53
POCSAGTX.h Normal file
View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2015,2016,2017,2018 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#if !defined(POCSAGTX_H)
#define POCSAGTX_H
#include "Config.h"
#include "SerialRB.h"
class CPOCSAGTX {
public:
CPOCSAGTX();
uint8_t writeData(const uint8_t* data, uint8_t length);
void process();
void setTXDelay(uint8_t delay);
uint8_t getSpace() const;
bool busy();
private:
CSerialRB m_buffer;
arm_fir_instance_q15 m_modFilter;
q15_t m_modState[180U]; // NoTaps + BlockSize - 1, 12 + 160 - 1 plus some spare
uint8_t m_poBuffer[200U];
uint16_t m_poLen;
uint16_t m_poPtr;
uint16_t m_txDelay;
void writeByte(uint8_t c);
};
#endif

View File

@ -1,7 +1,7 @@
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion, P25, and NXDN modes.
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion, P25, NXDN, and POCSAG modes.
It runs on the Arduino Due, the ST-Micro STM32F407-DISCO and STM32F446-NUCLEO, as well as the Teensy 3.1/3.2/3.5/3.6. What these platforms have in common is the use of an ARM Cortex-M3 or M4 processor with a clock speed greater than 70 MHz, and access to at least one analogue to digital converter and one digital to analogue converter. A Cortex-M7 processor is also probably adequate.
It runs on the Arduino Due, the ST-Micro STM32F1xxx, STM32F4xxx and STM32F7xxx processors, as well as the Teensy 3.1/3.2/3.5/3.6. What these platforms have in common is the use of an ARM Cortex-M3 or M4 processor with a clock speed greater than 70 MHz, and access to at least one analogue to digital converter and one digital to analogue converter.
In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. The STM32 support is being supplied via the Coocox IDE with ARM GCC. The Teensy support is via the latest beta of Teensyduino.
In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. The STM32 support is being supplied via the Coocox IDE with ARM GCC. The Teensy support uses Teensyduino.
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.

View File

@ -21,7 +21,10 @@
#include "SerialPort.h"
#if defined(__SAM3X8E__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#if defined(VK6MST_TEENSY_PI3_SHIELD_I2C)
//it will load I2CTeensy.cpp
#elif defined(__SAM3X8E__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
void CSerialPort::beginInt(uint8_t n, int speed)
{

View File

@ -63,6 +63,8 @@ const uint8_t MMDVM_P25_LOST = 0x32U;
const uint8_t MMDVM_NXDN_DATA = 0x40U;
const uint8_t MMDVM_NXDN_LOST = 0x41U;
const uint8_t MMDVM_POCSAG_DATA = 0x50U;
const uint8_t MMDVM_ACK = 0x70U;
const uint8_t MMDVM_NAK = 0x7FU;
@ -88,7 +90,7 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U;
#define TCXO "NO TCXO"
#endif
#define DESCRIPTION "MMDVM 20180630-48k (D-Star/DMR/System Fusion/P25/NXDN)"
#define DESCRIPTION "MMDVM 20180724-48k (D-Star/DMR/System Fusion/P25/NXDN)"
#if defined(GITVERSION)
#define concat(a, b, c) a " " b " GitID #" c ""
@ -139,11 +141,11 @@ void CSerialPort::getStatus()
{
io.resetWatchdog();
uint8_t reply[15U];
uint8_t reply[20U];
// Send all sorts of interesting internal values
reply[0U] = MMDVM_FRAME_START;
reply[1U] = 12U;
reply[1U] = 13U;
reply[2U] = MMDVM_GET_STATUS;
reply[3U] = 0x00U;
@ -157,6 +159,8 @@ void CSerialPort::getStatus()
reply[3U] |= 0x08U;
if (m_nxdnEnable)
reply[3U] |= 0x10U;
if (m_pocsagEnable)
reply[3U] |= 0x20U;
reply[4U] = uint8_t(m_modemState);
@ -216,12 +220,17 @@ void CSerialPort::getStatus()
else
reply[11U] = 0U;
writeInt(1U, reply, 12);
if (m_pocsagEnable)
reply[12U] = pocsagTX.getSpace();
else
reply[12U] = 0U;
writeInt(1U, reply, 13);
}
void CSerialPort::getVersion()
{
uint8_t reply[100U];
uint8_t reply[150U];
reply[0U] = MMDVM_FRAME_START;
reply[1U] = 0U;
@ -240,7 +249,7 @@ void CSerialPort::getVersion()
uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
{
if (length < 17U)
if (length < 18U)
return 4U;
bool rxInvert = (data[0U] & 0x01U) == 0x01U;
@ -251,11 +260,12 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
m_debug = (data[0U] & 0x10U) == 0x10U;
bool dstarEnable = (data[1U] & 0x01U) == 0x01U;
bool dmrEnable = (data[1U] & 0x02U) == 0x02U;
bool ysfEnable = (data[1U] & 0x04U) == 0x04U;
bool p25Enable = (data[1U] & 0x08U) == 0x08U;
bool nxdnEnable = (data[1U] & 0x10U) == 0x10U;
bool dstarEnable = (data[1U] & 0x01U) == 0x01U;
bool dmrEnable = (data[1U] & 0x02U) == 0x02U;
bool ysfEnable = (data[1U] & 0x04U) == 0x04U;
bool p25Enable = (data[1U] & 0x08U) == 0x08U;
bool nxdnEnable = (data[1U] & 0x10U) == 0x10U;
bool pocsagEnable = (data[1U] & 0x20U) == 0x20U;
uint8_t txDelay = data[2U];
if (txDelay > 50U)
@ -263,7 +273,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
MMDVM_STATE modemState = MMDVM_STATE(data[3U]);
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_NXDN && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL && modemState != STATE_LFCAL && modemState != STATE_DMRCAL1K && modemState != STATE_P25CAL1K && modemState != STATE_DMRDMO1K && modemState != STATE_NXDNCAL1K)
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_NXDN && modemState != STATE_POCSAG && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL && modemState != STATE_LFCAL && modemState != STATE_DMRCAL1K && modemState != STATE_P25CAL1K && modemState != STATE_DMRDMO1K && modemState != STATE_NXDNCAL1K)
return 4U;
if (modemState == STATE_DSTAR && !dstarEnable)
return 4U;
@ -275,6 +285,8 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
return 4U;
if (modemState == STATE_NXDN && !nxdnEnable)
return 4U;
if (modemState == STATE_POCSAG && !pocsagEnable)
return 4U;
uint8_t rxLevel = data[4U];
@ -293,24 +305,28 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
int16_t txDCOffset = int16_t(data[13U]) - 128;
int16_t rxDCOffset = int16_t(data[14U]) - 128;
uint8_t nxdnTXLevel = data[15U];
uint8_t nxdnTXLevel = data[15U];
uint8_t ysfTXHang = data[16U];
uint8_t ysfTXHang = data[16U];
uint8_t pocsagTXLevel = data[17U];
m_modemState = modemState;
m_dstarEnable = dstarEnable;
m_dmrEnable = dmrEnable;
m_ysfEnable = ysfEnable;
m_p25Enable = p25Enable;
m_nxdnEnable = nxdnEnable;
m_duplex = !simplex;
m_dstarEnable = dstarEnable;
m_dmrEnable = dmrEnable;
m_ysfEnable = ysfEnable;
m_p25Enable = p25Enable;
m_nxdnEnable = nxdnEnable;
m_pocsagEnable = pocsagEnable;
m_duplex = !simplex;
dstarTX.setTXDelay(txDelay);
ysfTX.setTXDelay(txDelay);
p25TX.setTXDelay(txDelay);
dmrDMOTX.setTXDelay(txDelay);
nxdnTX.setTXDelay(txDelay);
pocsagTX.setTXDelay(txDelay);
dmrTX.setColorCode(colorCode);
dmrRX.setColorCode(colorCode);
@ -320,7 +336,7 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
ysfTX.setParams(ysfLoDev, ysfTXHang);
io.setParameters(rxInvert, txInvert, pttInvert, rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, txDCOffset, rxDCOffset);
io.setParameters(rxInvert, txInvert, pttInvert, rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, pocsagTXLevel, txDCOffset, rxDCOffset);
io.start();
@ -337,7 +353,7 @@ uint8_t CSerialPort::setMode(const uint8_t* data, uint8_t length)
if (modemState == m_modemState)
return 0U;
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_NXDN && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL && modemState != STATE_LFCAL && modemState != STATE_DMRCAL1K && modemState != STATE_P25CAL1K && modemState != STATE_DMRDMO1K && modemState != STATE_NXDNCAL1K)
if (modemState != STATE_IDLE && modemState != STATE_DSTAR && modemState != STATE_DMR && modemState != STATE_YSF && modemState != STATE_P25 && modemState != STATE_NXDN && modemState != STATE_POCSAG && modemState != STATE_DSTARCAL && modemState != STATE_DMRCAL && modemState != STATE_RSSICAL && modemState != STATE_LFCAL && modemState != STATE_DMRCAL1K && modemState != STATE_P25CAL1K && modemState != STATE_DMRDMO1K && modemState != STATE_NXDNCAL1K)
return 4U;
if (modemState == STATE_DSTAR && !m_dstarEnable)
return 4U;
@ -349,6 +365,8 @@ uint8_t CSerialPort::setMode(const uint8_t* data, uint8_t length)
return 4U;
if (modemState == STATE_NXDN && !m_nxdnEnable)
return 4U;
if (modemState == STATE_POCSAG && !m_pocsagEnable)
return 4U;
setMode(modemState);
@ -406,6 +424,17 @@ void CSerialPort::setMode(MMDVM_STATE modemState)
p25RX.reset();
cwIdTX.reset();
break;
case STATE_POCSAG:
DEBUG1("Mode set to POCSAG");
dmrIdleRX.reset();
dmrDMORX.reset();
dmrRX.reset();
dstarRX.reset();
ysfRX.reset();
p25RX.reset();
nxdnRX.reset();
cwIdTX.reset();
break;
case STATE_DSTARCAL:
DEBUG1("Mode set to D-Star Calibrate");
dmrIdleRX.reset();
@ -770,6 +799,20 @@ void CSerialPort::process()
}
break;
case MMDVM_POCSAG_DATA:
if (m_pocsagEnable) {
if (m_modemState == STATE_IDLE || m_modemState == STATE_POCSAG)
err = pocsagTX.writeData(m_buffer + 3U, m_len - 3U);
}
if (err == 0U) {
if (m_modemState == STATE_IDLE)
setMode(STATE_POCSAG);
} else {
DEBUG2("Received invalid POCSAG data", err);
sendNAK(err);
}
break;
case MMDVM_TRANSPARENT:
// Do nothing on the MMDVM.
break;

View File

@ -50,7 +50,7 @@ extern "C" {
}
/* ************* USART1 ***************** */
#if defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_F7M) || defined(STM32F722_PI) || defined(STM32F4_DVM) || (defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER))
#if defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_F7M) || defined(STM32F722_PI) || defined(STM32F722_F7HAT) || defined(STM32F4_DVM) || (defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER))
volatile uint8_t TXSerialfifo1[TX_SERIAL_FIFO_SIZE];
volatile uint8_t RXSerialfifo1[RX_SERIAL_FIFO_SIZE];
@ -841,7 +841,7 @@ void CSerialPort::beginInt(uint8_t n, int speed)
case 1U:
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
InitUSART3(speed);
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F4_DVM)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_F7HAT) || defined(STM32F4_DVM)
InitUSART1(speed);
#elif defined(STM32F4_NUCLEO)
InitUSART2(speed);
@ -865,7 +865,7 @@ int CSerialPort::availableInt(uint8_t n)
case 1U:
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
return AvailUSART3();
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F4_DVM)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_F7HAT) || defined(STM32F4_DVM)
return AvailUSART1();
#elif defined(STM32F4_NUCLEO)
return AvailUSART2();
@ -887,7 +887,7 @@ int CSerialPort::availableForWriteInt(uint8_t n)
case 1U:
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
return AvailForWriteUSART3();
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F4_DVM)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_F7HAT) || defined(STM32F4_DVM)
return AvailForWriteUSART1();
#elif defined(STM32F4_NUCLEO)
return AvailForWriteUSART2();
@ -909,7 +909,7 @@ uint8_t CSerialPort::readInt(uint8_t n)
case 1U:
#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO)
return ReadUSART3();
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F4_DVM)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_F7HAT) || defined(STM32F4_DVM)
return ReadUSART1();
#elif defined(STM32F4_NUCLEO)
return ReadUSART2();
@ -933,7 +933,7 @@ void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool
WriteUSART3(data, length);
if (flush)
TXSerialFlush3();
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F4_DVM)
#elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_F7HAT) || defined(STM32F4_DVM)
WriteUSART1(data, length);
if (flush)
TXSerialFlush1();

View File

@ -83,7 +83,7 @@ EOF
"3") sed -e 's/\/\/ #define EXTERNAL_OSC 14400000/#define EXTERNAL_OSC 14400000/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "14.400 MHz clock enabled";;
"4") sed -e 's/\/\/ #define EXTERNAL_OSC 19200000/#define EXTERNAL_OSC 19200000/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "19.200 MHz clock enabled";;
"5") sed -e 's/\/\/ #define USE_COS_AS_LOCKOUT /#define USE_COS_AS_LOCKOUT/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "COS as Lockout enabled";;
"6") sed -e 's/\/\/ #define ARDUINO_MODE_PINS/#define ARDUINO_MODE_PINS/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Mode pins enabled";;
"6") sed -e 's/\/\/ #define MODE_PINS/#define MODE_PINS/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Mode pins enabled";;
"7") sed -e 's/\/\/ #define ARDUINO_DUE_PAPA/#define ARDUINO_DUE_PAPA/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Layout for the PAPA board enabled";;
"8") sed -e 's/\/\/ #define ARDUINO_DUE_ZUM_V10/#define ARDUINO_DUE_ZUM_V10/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Layout for ZUM V1.0 and V1.0.1 boards enabled";;
"9") sed -e 's/\/\/ #define ARDUINO_DUE_NTH/#define ARDUINO_DUE_NTH/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Layout for SP8NTH board enabled";;