Compare commits

...
74 Commits
Author SHA1 Message Date
phl0 1be760ad56 Free already used pin 2018-07-24 21:04:53 +02:00
phl0 4c81f4ca7a Implement MODE pins for F7Hat 2018-07-24 20:46:41 +02:00
phl0 0d7d903e21 Add POCSAG mode pin 2018-07-24 20:36:17 +02:00
Florian (DF2ET) 5405395e1a Merge pull request #186 from N4IRS/master
Add POCSAG Pin for STM32-DVM
2018-07-24 12:05:24 +02:00
Steve N4IRS 3c95d1f604 Add POCSAG Pin for STM32-DVM 2018-07-24 05:58:58 -04:00
Jonathan Naylor da8023eabf Bump the version date. 2018-07-23 21:53:36 +01:00
phl0 0d55ba317d Correct POCSAG LED for F7Hat 2018-07-23 11:39:16 +02:00
Andy CA6JAU 404dc3d99d Additional check to transmit all POCSAG buffer 2018-07-20 20:31:38 -04:00
Andy CA6JAU 4821d0e959 Fix for missing POCSAG start tone 2018-07-20 14:17:33 -04:00
Jonathan Naylor db3649827f Merge pull request #184 from Hootie81/VK6MST_Shield
Add support VK6MST_Shield Serial pass-thru
2018-07-20 12:17:01 +01:00
Hootie81 5bec0d0780 Add support VK6MST_Shield Serial pass-thru 2018-07-20 21:00:09 +10:00
Andy CA6JAU 110062bf65 Reduce the size of serial ring buffer 2018-07-20 00:50:53 -04:00
Jonathan Naylor f3c621307a Restore the original configuration file. 2018-07-19 18:21:17 +01:00
Jonathan Naylor 03177a05e7 Merge pull request #183 from Hootie81/VK6MST_Shield
Add support for VK6MST_Shield
2018-07-19 18:15:57 +01:00
Hootie81 e93b08380d Add support for VK6MST_Shield 2018-07-19 13:01:20 +00:00
phl0 012b366143 Add POCSAG Pin for F7hat 2018-07-18 22:35:13 +02:00
phl0 fd8bc07b61 Merge branch 'master' into F7hat 2018-07-18 22:30:34 +02:00
phl0 68106058d6 Add missing ifdefines for F7Hat 2018-07-18 21:32:56 +02:00
phl0 d62c945887 Add POCSAG pin defs for f767 target 2018-07-12 07:36:44 +02:00
phl0 0aea9aef38 Correct typo in Makefile 2018-07-12 07:16:40 +02:00
Andy 88409dccd2 Add temporary POCSAG pin definitions for F446 and F722 2018-07-12 00:59:08 -04:00
Jonathan Naylor f705656178 Bump the version date. 2018-07-05 18:44:31 +01:00
Jonathan Naylor 5c61ee6be8 Add an mode output pin on the STM32-F7M board as suggested by Tom BG4TGO. 2018-07-05 18:29:18 +01:00
Jonathan Naylor a4af04fae2 Allow for alternative LEDs for NXDN and POCSAG. 2018-07-04 18:40:54 +01:00
phl0 6b28efc011 Flash F7Hat via GPIO 2018-07-01 01:45:42 +02:00
phl0 8c6289802f Add support for MMDVM-F7-Hat 2018-07-01 01:41:33 +02:00
Jonathan Naylor 78d79d4124 Update the README file. 2018-06-26 18:18:43 +01:00
Jonathan Naylor 76d2058075 Recalculate the TX delay for POCSAG. 2018-06-26 18:16:13 +01:00
Jonathan Naylor dcd8142c51 Add a smoothing filter to the POCSAG TX waveform. 2018-06-25 18:00:11 +01:00
Jonathan Naylor 88c530d9e6 Merge branch 'master' into pocsag 2018-06-25 17:47:24 +01:00
phl0 61d5dd6eb3 Add submodules for F4/F7 libs 2018-06-23 22:40:13 +02:00
Jonathan Naylor 9eb6bc1a60 Add the POCSAG mode pin for the Arduino Due, Teensy 3.2/3.6 and the
STM32F105.
2018-06-19 18:17:05 +01:00
Jonathan Naylor 2098146af8 Rename ARDUINO_MODE_PINS to MODE_PINS. 2018-06-19 18:01:24 +01:00
Jonathan Naylor ef32988827 More tweaking of the POCSAG deviation. 2018-06-18 22:12:13 +01:00
Jonathan Naylor ce05dec2e6 Fix crash caused by the larger version string. 2018-06-18 21:32:08 +01:00
Jonathan Naylor 895bed1f70 Fix getStatus length. 2018-06-18 19:18:47 +01:00
phl0 dbea23f171 Merge branch 'master' into pocsag 2018-06-14 19:34:16 +02:00
Florian (DF2ET) ead9747f95 Merge pull request #179 from EA3HKB/patch-1
Add description for non TCXO systems
2018-06-14 19:31:08 +02:00
Florian (DF2ET) 5fe665a6d3 Merge branch 'master' into patch-1 2018-06-14 19:30:52 +02:00
Florian (DF2ET) 3515b16222 Merge pull request #178 from EA3HKB/patch-2
Define new TCXO frequency names for add NO TCXO option
2018-06-14 19:29:39 +02:00
EA3HKB a5c162a75e Define new TCXO frequency names for add NO TCXO option 2018-06-14 19:05:48 +02:00
EA3HKB b5a56487b1 Add description for non TCXO systems
Fixes compiler error
2018-06-14 18:27:48 +02:00
Jonathan Naylor d151c100db Fix length of the getConfig reply. 2018-06-14 07:25:09 +01:00
Jonathan Naylor 56ced0d939 Decrease the deviation. 2018-06-12 21:42:15 +01:00
Jonathan Naylor b6cb23d876 Invert the transmit frequencies. 2018-06-12 20:59:39 +01:00
Jonathan Naylor 20a0a875f3 Add the POCSAG transmitter. 2018-06-06 20:27:46 +01:00
Jonathan Naylor d6c1bea80a Merge pull request #177 from phl0/tcxo
Add TCXO frequency to modem description
2018-06-06 13:34:38 +01:00
Jonathan Naylor 6d4ec5d8a1 Merge pull request #176 from phl0/gitignore
Add F7 lib to .gitignore
2018-06-06 13:33:59 +01:00
phl0 474dce0141 Add F7 lib to .gitignore 2018-06-06 14:06:42 +02:00
phl0 5adbe6d0d5 Add TCXO frequency to modem description 2018-06-06 14:05:36 +02:00
Jonathan Naylor 28adbef81b Add YSF TX hang. 2018-06-04 20:50:43 +01:00
Andy CA6JAU c86d53d9d4 Change 1.2 kHz fill tone by a pseudo random fill (DMR DMO) 2018-06-01 14:39:02 -04:00
Andy CA6JAU eb33bdde5a Merge pull request #171 from g0wfv/constant_srv_led
Constant Service LED
2018-05-23 12:26:30 -04:00
g0wfv 0a89469ffc Constant Service LED 2018-05-23 17:12:53 +01:00
Andy CA6JAU bdd4f395ad Merge pull request #170 from gatekeep/master
Correctly use the CORRELATION_COUNTDOWN constant vs magic number of 5U.
2018-05-15 12:34:23 -04:00
Bryan Biedenkapp 4ae2999e95 Correctly use the CORRELATION_COUNTDOWN constant vs magic number of 5U. 2018-05-15 12:30:15 -04:00
Andy CA6JAU 077bb3b366 Merge pull request #169 from N4IRS/master
Fix comments for STM32-DVM Rev 3
2018-05-15 08:09:14 -04:00
Steve N4IRS b0ca829cf6 Fix comments for STM32-DVM Rev 3 2018-05-15 07:54:39 -04:00
Andy CA6JAU c11ff6bf20 Increasing ring buffer lengths 2018-05-14 22:41:26 -04:00
Jonathan Naylor e1b99f6ee4 Merge pull request #168 from gatekeep/master
Add support to decode P25 DUIDs and non-LDU packets in during processHdr.
2018-05-14 18:45:26 +01:00
Bryan Biedenkapp 4c792ff668 Fix commit with bad line endings. 2018-05-14 10:11:58 -04:00
Bryan Biedenkapp 260dca9664 Add support to decode DUIDs in during processHdr; Add support to process non-LDU packets during processHdr. 2018-05-14 09:09:43 -04:00
Andy CA6JAU 91a15a5782 Merge pull request #167 from N4IRS/master
Add support for the STM32-DVM Rev 3
2018-05-13 08:42:44 -04:00
Steve N4IRS 03f15d8689 Add support for the STM32-DVM Rev 3 2018-05-13 07:39:12 -04:00
Jonathan Naylor 86bf20b06b Update the README. 2018-04-30 17:58:50 +01:00
Jonathan Naylor 41ffe6d2eb Fix Nucleo compiler issues. 2018-04-17 22:32:39 +01:00
Jonathan Naylor 41946ff0aa Bump the version date. 2018-03-27 21:35:38 +01:00
Jonathan Naylor 0ca06e2219 Add new transparent data bypass. 2018-03-21 22:01:35 +00:00
Jonathan Naylor 59ed3f07c8 Change the pin for the NXDN LED on the Teensy. 2018-03-07 20:04:23 +00:00
Andy CA6JAU e20630a425 Support for MMDVM-F7M Pi-Hat board (F0DEI) 2018-03-03 17:05:23 -03:00
Andy CA6JAU ec8a2bc9ff Change NXDN LED pin to PA3 in Arduino header (Nucleo64 F446) 2018-03-01 00:49:14 -03:00
Jonathan Naylor b21c1f21a4 Make the DC blocker optional to reduce CPU load. 2018-02-26 19:55:14 +00:00
Jonathan Naylor 01b3dcc689 Reduce CPU load on idle. 2018-02-26 19:37:15 +00:00
Andy CA6JAU 23f27cf496 Bump the version date 2018-02-23 16:14:26 -03:00
38 changed files with 1344 additions and 179 deletions
-1
View File
@@ -1,6 +1,5 @@
*.o
obj/
bin/
STM32F4XX_Lib/
GitVersion.h
build/
+6
View File
@@ -0,0 +1,6 @@
[submodule "STM32F4XX_Lib"]
path = STM32F4XX_Lib
url = https://github.com/juribeparada/STM32F4XX_Lib.git
[submodule "STM32F7XX_Lib"]
path = STM32F7XX_Lib
url = https://github.com/juribeparada/STM32F7XX_Lib.git
+19 -2
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,10 +60,27 @@
// 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
// Use the modem as a serial repeater for Nextion displays
// #define SERIAL_REPEATER
// To reduce CPU load, you can remove the DC blocker by commenting out the next line
#define USE_DCBLOCKER
// Constant Service LED once repeater is running
// Do not use if employing an external hardware watchdog
// #define CONSTANT_SRV_LED
// 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
#endif
+11 -4
View File
@@ -38,6 +38,13 @@ const uint8_t BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
// PR FILL pattern
const uint8_t PR_FILL[] =
{0x63U, 0xEAU, 0x00U, 0x76U, 0x6CU, 0x76U, 0xC4U, 0x52U, 0xC8U, 0x78U,
0x09U, 0x2DU, 0xB8U, 0x79U, 0x27U, 0x57U, 0x9BU, 0x31U, 0xBCU, 0x3EU,
0xEAU, 0x45U, 0xC3U, 0x30U, 0x49U, 0x17U, 0x93U, 0xAEU, 0x8BU, 0x6DU,
0xA4U, 0xA5U, 0xADU, 0xA2U, 0xF1U, 0x35U, 0xB5U, 0x3CU, 0x1EU};
const uint8_t DMR_SYNC = 0x5FU;
CDMRDMOTX::CDMRDMOTX() :
@@ -66,11 +73,11 @@ void CDMRDMOTX::process()
m_poLen = m_txDelay;
} else {
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 + 39U] = m_fifo.get();
m_poBuffer[i] = m_fifo.get();
for (unsigned int i = 0U; i < 39U; i++)
m_poBuffer[i + DMR_FRAME_LENGTH_BYTES] = PR_FILL[i];
m_poLen = 72U;
}
Executable → Regular
View File
Executable → Regular
View File
+5
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;
+235
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
+111 -55
View File
@@ -61,18 +61,16 @@ m_txBuffer(TX_RINGBUFFER_SIZE),
m_rssiBuffer(RX_RINGBUFFER_SIZE),
m_dcFilter(),
m_dcState(),
m_dmrFilter(),
m_rrcFilter(),
m_gaussianFilter(),
m_boxcarFilter(),
m_nxdnFilter(),
m_nxdnISincFilter(),
m_ysfFilter(),
m_dmrState(),
m_rrcState(),
m_gaussianState(),
m_boxcarState(),
m_nxdnState(),
m_nxdnISincState(),
m_ysfState(),
m_pttInvert(false),
m_rxLevel(128 * 128),
m_cwIdTXLevel(128 * 128),
@@ -81,6 +79,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),
@@ -91,12 +90,11 @@ m_dacOverflow(0U),
m_watchdog(0U),
m_lockout(false)
{
::memset(m_dmrState, 0x00U, 70U * 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));
::memset(m_nxdnState, 0x00U, 110U * sizeof(q15_t));
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
::memset(m_ysfState, 0x00U, 70U * sizeof(q15_t));
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
m_dcFilter.numStages = DC_FILTER_STAGES;
@@ -104,9 +102,9 @@ m_lockout(false)
m_dcFilter.pCoeffs = DC_FILTER;
m_dcFilter.postShift = 0;
m_dmrFilter.numTaps = RRC_0_2_FILTER_LEN;
m_dmrFilter.pState = m_dmrState;
m_dmrFilter.pCoeffs = RRC_0_2_FILTER;
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
m_rrcFilter.pState = m_rrcState;
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
m_gaussianFilter.pState = m_gaussianState;
@@ -124,10 +122,6 @@ m_lockout(false)
m_nxdnISincFilter.pState = m_nxdnISincState;
m_nxdnISincFilter.pCoeffs = NXDN_ISINC_FILTER;
m_ysfFilter.numTaps = RRC_0_2_FILTER_LEN;
m_ysfFilter.pState = m_ysfState;
m_ysfFilter.pCoeffs = RRC_0_2_FILTER;
initInt();
selfTest();
@@ -143,22 +137,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);
@@ -167,6 +163,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@@ -175,6 +172,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@@ -183,6 +181,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@@ -191,6 +190,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);
@@ -199,6 +217,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(true);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@@ -207,6 +226,7 @@ void CIO::selfTest()
setYSFInt(true);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@@ -215,6 +235,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@@ -223,6 +244,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
delayInt(250);
@@ -231,6 +253,7 @@ void CIO::selfTest()
setYSFInt(false);
setP25Int(false);
setNXDNInt(false);
setPOCSAGInt(false);
#endif
}
@@ -252,7 +275,7 @@ void CIO::process()
if (m_started) {
// Two seconds timeout
if (m_watchdog >= 48000U) {
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_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF || m_modemState == STATE_P25 || m_modemState == STATE_NXDN || m_modemState == STATE_POCSAG) {
if (m_modemState == STATE_DMR && m_tx)
dmrTX.setStart(false);
m_modemState = STATE_IDLE;
@@ -262,11 +285,15 @@ void CIO::process()
m_watchdog = 0U;
}
#if defined(CONSTANT_SRV_LED)
setLEDInt(true);
#else
if (m_ledCount >= 24000U) {
m_ledCount = 0U;
m_ledValue = !m_ledValue;
setLEDInt(m_ledValue);
}
#endif
} else {
if (m_ledCount >= 240000U) {
m_ledCount = 0U;
@@ -308,13 +335,14 @@ void CIO::process()
if (m_lockout)
return;
q31_t dcLevel = 0;
q31_t dcValues[RX_BLOCK_SIZE];
#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;
@@ -324,58 +352,70 @@ void CIO::process()
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)
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#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 NXDNVals[RX_BLOCK_SIZE];
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_ysfEnable) {
q15_t YSFVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_ysfFilter, dcSamples, YSFVals, 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);
ysfRX.samples(YSFVals, rssi, RX_BLOCK_SIZE);
}
if (m_ysfEnable)
ysfRX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
if (m_dmrEnable) {
q15_t DMRVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_dmrFilter, samples, DMRVals, RX_BLOCK_SIZE);
if (m_duplex)
dmrIdleRX.samples(DMRVals, RX_BLOCK_SIZE);
else
dmrDMORX.samples(DMRVals, 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)
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#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_dmrFilter, samples, 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
@@ -390,22 +430,32 @@ void CIO::process()
} else if (m_modemState == STATE_YSF) {
if (m_ysfEnable) {
q15_t YSFVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_ysfFilter, dcSamples, 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 NXDNVals[RX_BLOCK_SIZE];
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);
@@ -452,6 +502,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;
@@ -493,26 +546,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;
@@ -521,11 +576,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;
}
}
+5 -5
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);
@@ -66,18 +66,16 @@ private:
arm_biquad_casd_df1_inst_q31 m_dcFilter;
q31_t m_dcState[4];
arm_fir_instance_q15 m_dmrFilter;
arm_fir_instance_q15 m_rrcFilter;
arm_fir_instance_q15 m_gaussianFilter;
arm_fir_instance_q15 m_boxcarFilter;
arm_fir_instance_q15 m_nxdnFilter;
arm_fir_instance_q15 m_nxdnISincFilter;
arm_fir_instance_q15 m_ysfFilter;
q15_t m_dmrState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
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
q15_t m_nxdnState[110U]; // NoTaps + BlockSize - 1, 82 + 20 - 1 plus some spare
q15_t m_nxdnISincState[60U]; // NoTaps + BlockSize - 1, 32 + 20 - 1 plus some spare
q15_t m_ysfState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
bool m_pttInvert;
q15_t m_rxLevel;
@@ -87,6 +85,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;
@@ -118,6 +117,7 @@ private:
void setYSFInt(bool on);
void setP25Int(bool on);
void setNXDNInt(bool on);
void setPOCSAGInt(bool on);
void delayInt(unsigned int dly);
};
+24 -1
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)
+367 -12
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
@@ -324,6 +339,199 @@ EXT_CLK PA15 input
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#elif defined(STM32F722_F7M)
/*
Pin definitions for MMDVM-F7M Pi-Hat F0DEI board:
PTT PB13 output
COSLED PB14 output
LED PB15 output
COS PC0 input
DSTAR PC7 output
DMR PC8 output
YSF PA8 output
P25 PC9 output
NXDN PB1 output
POCSAG PB12 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_13
#define PORT_PTT GPIOB
#define RCC_Per_PTT RCC_AHB1Periph_GPIOB
#define PIN_COSLED GPIO_Pin_14
#define PORT_COSLED GPIOB
#define RCC_Per_COSLED RCC_AHB1Periph_GPIOB
#define PIN_LED GPIO_Pin_15
#define PORT_LED GPIOB
#define RCC_Per_LED RCC_AHB1Periph_GPIOB
#define PIN_P25 GPIO_Pin_9
#define PORT_P25 GPIOC
#define RCC_Per_P25 RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_1
#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
#define PIN_DMR GPIO_Pin_8
#define PORT_DMR GPIOC
#define RCC_Per_DMR RCC_AHB1Periph_GPIOC
#define PIN_YSF GPIO_Pin_8
#define PORT_YSF GPIOA
#define RCC_Per_YSF RCC_AHB1Periph_GPIOA
#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(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
POCSAG PA8 output
MDSTAR PC10 output
MDMR PC4 output
MYSF PC13 output
MP25 PC14 output
MNXDN PC15 output
MPOCSAG PC11 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_8
#define PORT_POCSAG GPIOA
#define RCC_Per_POCSAG RCC_AHB1Periph_GPIOA
#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
#if defined(STM32F4_NUCLEO_MODE_PINS)
#define PIN_MP25 GPIO_Pin_14
#define PORT_MP25 GPIOC
#define RCC_Per_MP25 RCC_AHB1Periph_GPIOC
#define PIN_MNXDN GPIO_Pin_15
#define PORT_MNXDN GPIOC
#define RCC_Per_MNXDN RCC_AHB1Periph_GPIOC
#define PIN_MDSTAR GPIO_Pin_10
#define PORT_MDSTAR GPIOC
#define RCC_Per_MDSTAR RCC_AHB1Periph_GPIOC
#define PIN_MDMR GPIO_Pin_4
#define PORT_MDMR GPIOC
#define RCC_Per_MDMR RCC_AHB1Periph_GPIOC
#define PIN_MYSF GPIO_Pin_13
#define PORT_MYSF GPIOC
#define RCC_Per_MYSF RCC_AHB1Periph_GPIOC
#define PIN_MPOCSAG GPIO_Pin_11
#define PORT_MPOCSAG GPIOC
#define RCC_Per_MPOCSAG RCC_AHB1Periph_GPIOC
#endif
#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)
@@ -340,12 +548,14 @@ 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
MYSF PC2 output CN7 Pin35
MP25 PC3 output CN7 Pin37
MNXDN PC6 output CN10 Pin4
MPOCSAG PC7 output CN10 Pin19
RX PA0 analog input CN7 Pin28
RSSI PA1 analog input CN7 Pin30
@@ -378,6 +588,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
@@ -410,6 +624,10 @@ EXT_CLK PA15 input CN7 Pin17
#define PIN_MYSF GPIO_Pin_2
#define PORT_MYSF GPIOC
#define RCC_Per_MYSF RCC_AHB1Periph_GPIOC
#define PIN_MPOCSAG GPIO_Pin_7
#define PORT_MPOCSAG GPIOC
#define RCC_Per_MPOCSAG RCC_AHB1Periph_GPIOC
#endif
#define PIN_EXT_CLK GPIO_Pin_15
@@ -442,7 +660,8 @@ DSTAR PA1 output CN8 Pin2
DMR PA4 output CN8 Pin3
YSF PB0 output CN8 Pin4
P25 PC1 output CN8 Pin5
NXDN PC0 output CN8 Pin6
NXDN PA3 output CN9 Pin1
POCSAG PB12 output
RX PA0 analog input CN8 Pin1
RSSI PC0 analog input CN8 Pin6
@@ -471,9 +690,13 @@ EXT_CLK PB8 input CN5 Pin10
#define PORT_P25 GPIOC
#define RCC_Per_P25 RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_0
#define PORT_NXDN GPIOC
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOC
#define PIN_NXDN GPIO_Pin_3
#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
@@ -522,6 +745,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
@@ -560,6 +784,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
@@ -611,8 +839,89 @@ EXT_CLK PA15 input CN11 Pin17
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#elif defined(STM32F4_DVM)
/*
Pin definitions for STM32F4 STM32-DVM rev 3 Board:
COS PB13 input
PTT PB12 output
COSLED PB4 output
LED PB3 output
P25 PB8 output
NXDN PB9 output
DSTAR PB6 output
DMR PB5 output
YSF PB7 output
POCSAG PC10 output
RX PB0 analog input
RSSI PB1 analog input
TX PA4 analog output
EXT_CLK PA15 input
*/
#define PIN_COS GPIO_Pin_13
#define PORT_COS GPIOB
#define RCC_Per_COS RCC_AHB1Periph_GPIOB
#define PIN_PTT GPIO_Pin_12
#define PORT_PTT GPIOB
#define RCC_Per_PTT RCC_AHB1Periph_GPIOB
#define PIN_COSLED GPIO_Pin_4
#define PORT_COSLED GPIOB
#define RCC_Per_COSLED RCC_AHB1Periph_GPIOB
#define PIN_LED GPIO_Pin_3
#define PORT_LED GPIOB
#define RCC_Per_LED RCC_AHB1Periph_GPIOB
#define PIN_P25 GPIO_Pin_8
#define PORT_P25 GPIOB
#define RCC_Per_P25 RCC_AHB1Periph_GPIOB
#define PIN_NXDN GPIO_Pin_9
#define PORT_NXDN GPIOB
#define RCC_Per_NXDN RCC_AHB1Periph_GPIOB
#define PIN_DSTAR GPIO_Pin_6
#define PORT_DSTAR GPIOB
#define RCC_Per_DSTAR RCC_AHB1Periph_GPIOB
#define PIN_DMR GPIO_Pin_5
#define PORT_DMR GPIOB
#define RCC_Per_DMR RCC_AHB1Periph_GPIOB
#define PIN_YSF GPIO_Pin_7
#define PORT_YSF GPIOB
#define RCC_Per_YSF RCC_AHB1Periph_GPIOB
#define PIN_POCSAG GPIO_Pin_10
#define PORT_POCSAG GPIOC
#define RCC_Per_POCSAG 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_8
#define PORT_RX GPIOB
#define RCC_Per_RX RCC_AHB1Periph_GPIOB
#define PIN_RSSI GPIO_Pin_1
#define PIN_RSSI_CH ADC_Channel_9
#define PORT_RSSI GPIOB
#define RCC_Per_RSSI RCC_AHB1Periph_GPIOB
#define PIN_TX GPIO_Pin_4
#define PIN_TX_CH DAC_Channel_1
#else
#error "Either STM32F4_DISCOVERY, STM32F4_PI, STM32F722_PI, STM32F4_F4M, STM32F4_NUCLEO or STM32F7_NUCLEO need to be defined"
#error "Either STM32F4_DISCOVERY, STM32F4_PI, STM32F722_PI, STM32F4_F4M, STM32F722_F7M, STM32F4_DVM, STM32F4_NUCLEO or STM32F7_NUCLEO need to be defined"
#endif
const uint16_t DC_OFFSET = 2048U;
@@ -661,7 +970,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;
@@ -686,6 +995,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;
@@ -693,7 +1003,16 @@ void CIO::initInt()
GPIO_Init(PORT_NXDN, &GPIO_InitStruct);
#endif
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
#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) || defined(STM32F722_F7HAT))
// DSTAR mode pin
RCC_AHB1PeriphClockCmd(RCC_Per_MDSTAR, ENABLE);
GPIO_InitStruct.GPIO_Pin = PIN_MDSTAR;
@@ -718,12 +1037,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()
@@ -933,7 +1262,7 @@ void CIO::setCOSInt(bool on)
void CIO::setDStarInt(bool on)
{
GPIO_WriteBit(PORT_DSTAR, PIN_DSTAR, on ? Bit_SET : Bit_RESET);
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_F7HAT))
GPIO_WriteBit(PORT_MDSTAR, PIN_MDSTAR, on ? Bit_SET : Bit_RESET);
#endif
}
@@ -941,7 +1270,7 @@ void CIO::setDStarInt(bool on)
void CIO::setDMRInt(bool on)
{
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)
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_F7HAT))
GPIO_WriteBit(PORT_MDMR, PIN_MDMR, on ? Bit_SET : Bit_RESET);
#endif
}
@@ -949,7 +1278,7 @@ void CIO::setDMRInt(bool on)
void CIO::setYSFInt(bool on)
{
GPIO_WriteBit(PORT_YSF, PIN_YSF, on ? Bit_SET : Bit_RESET);
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && defined(STM32F4_NUCLEO)
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_F7HAT))
GPIO_WriteBit(PORT_MYSF, PIN_MYSF, on ? Bit_SET : Bit_RESET);
#endif
}
@@ -957,17 +1286,43 @@ void CIO::setYSFInt(bool on)
void CIO::setP25Int(bool on)
{
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)
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_F7HAT))
GPIO_WriteBit(PORT_MP25, PIN_MP25, on ? Bit_SET : Bit_RESET);
#endif
}
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) || defined(STM32F722_F7HAT))
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)
#if defined(STM32F4_NUCLEO_MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_F7HAT))
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) || defined(STM32F722_F7HAT))
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) || defined(STM32F722_F7HAT))
GPIO_WriteBit(PORT_MPOCSAG, PIN_MPOCSAG, on ? Bit_SET : Bit_RESET);
#endif
#endif
}
// Simple delay function for STM32
+33 -9
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,17 +213,22 @@ 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_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_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);
#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)
GPIOConfigPin(PORT_RSSI, PIN_RSSI, 0);
@@ -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)
+29 -3
View File
@@ -34,7 +34,13 @@
#define PIN_DMR 10
#define PIN_YSF 11
#define PIN_P25 12
#define PIN_NXDN 8
#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
@@ -58,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()
@@ -212,9 +223,24 @@ void CIO::setP25Int(bool on)
digitalWrite(PIN_P25, on ? HIGH : LOW);
}
void CIO::setNXDNInt(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)
+11 -5
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();
+11 -5
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();
+1 -1
View File
@@ -97,7 +97,7 @@
<Define name="STM32F446xx"/>
<Define name="HSE_VALUE=12000000"/>
<Define name="STM32F4_PI"/>
<Define name="ARDUINO_MODE_PINS"/>
<Define name="MODE_PINS"/>
</DefinedSymbols>
</Compile>
<Link useDefault="0">
+30 -2
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2016,2017 by Andy Uribe CA6JAU
# Copyright (C) 2016,2017,2018 by Andy Uribe CA6JAU
# Copyright (C) 2016 by Jim McLaughlin KI6ZUM
# This program is free software; you can redistribute it and/or modify
@@ -126,6 +126,12 @@ DEFS_NUCLEO=-DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DSTM32F446xx -DSTM32F4_NUCLEO -D
DEFS_NUCLEO_F767=-DUSE_HAL_DRIVER -DSTM32F767xx -DSTM32F7XX -DSTM32F7_NUCLEO -DHSE_VALUE=$(OSC) -DMADEBYMAKEFILE
# MMDVM-Pi F722 board:
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
# Build compiler flags
CFLAGS_F4=-c $(MCFLAGS_F4) $(INCLUDES_F4)
@@ -144,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 clean
.PHONY: all release dis pi pi-f722 f4m nucleo f767 dvm clean
# Default target: Nucleo-64 F446RE board
all: nucleo
@@ -167,6 +173,18 @@ f4m: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_F4M)
f4m: LDFLAGS+=$(LDFLAGS_F4)
f4m: release_f4
f7m: GitVersion.h
f7m: CFLAGS+=$(CFLAGS_F7) $(DEFS_F7M)
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)
@@ -185,6 +203,12 @@ f767: CXXFLAGS+=$(CXXFLAGS_F7) $(DEFS_NUCLEO_F767)
f767: LDFLAGS+=$(LDFLAGS_F767)
f767: release_f7
dvm: GitVersion.h
dvm: CFLAGS+=$(CFLAGS_F4) $(DEFS_DVM)
dvm: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DVM)
dvm: LDFLAGS+=$(LDFLAGS_F4)
dvm: release_f4
release_f4: $(BINDIR)
release_f4: $(OBJDIR_F4)
release_f4: $(BINDIR)/$(BINHEX_F4)
@@ -305,6 +329,7 @@ ifneq ($(wildcard /usr/bin/stm32flash),)
endif
deploy-f4m: deploy-pi
deploy-dvm: deploy-pi
deploy-pi-f7:
ifneq ($(wildcard /usr/local/bin/stm32flash),)
@@ -319,6 +344,9 @@ 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-f7hat: deploy-pi-f7
# Export the current git version if the index file exists, else 000...
GitVersion.h:
ifdef SYSTEMROOT
+1 -1
View File
@@ -45,7 +45,7 @@ const uint8_t NXDN_PREAMBLE[] = {0x57U, 0x75U, 0xFDU};
const uint8_t NXDN_SYNC = 0x5FU;
CNXDNTX::CNXDNTX() :
m_buffer(2000U),
m_buffer(4000U),
m_modFilter(),
m_sincFilter(),
m_modState(),
+18 -3
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2018 by Bryan Biedenkapp <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,14 +42,20 @@ const unsigned int P25_TERM_FRAME_LENGTH_BITS = P25_TERM_FRAME_LENGTH_BYTES
const unsigned int P25_TERM_FRAME_LENGTH_SYMBOLS = P25_TERM_FRAME_LENGTH_BYTES * 4U;
const unsigned int P25_TERM_FRAME_LENGTH_SAMPLES = P25_TERM_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
const unsigned int P25_TSDU_FRAME_LENGTH_BYTES = 45U;
const unsigned int P25_TSDU_FRAME_LENGTH_BITS = P25_TSDU_FRAME_LENGTH_BYTES * 8U;
const unsigned int P25_TSDU_FRAME_LENGTH_SYMBOLS = P25_TSDU_FRAME_LENGTH_BYTES * 4U;
const unsigned int P25_TSDU_FRAME_LENGTH_SAMPLES = P25_TSDU_FRAME_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
const unsigned int P25_SYNC_LENGTH_BYTES = 6U;
const unsigned int P25_SYNC_LENGTH_BITS = P25_SYNC_LENGTH_BYTES * 8U;
const unsigned int P25_SYNC_LENGTH_SYMBOLS = P25_SYNC_LENGTH_BYTES * 4U;
const unsigned int P25_SYNC_LENGTH_SAMPLES = P25_SYNC_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
const unsigned int P25_NID_LENGTH_BITS = 64U;
const unsigned int P25_NID_LENGTH_SYMBOLS = 32U;
const unsigned int P25_NID_LENGTH_SAMPLESS = P25_NID_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
const unsigned int P25_NID_LENGTH_BYTES = 8U;
const unsigned int P25_NID_LENGTH_BITS = P25_NID_LENGTH_BYTES * 8U;
const unsigned int P25_NID_LENGTH_SYMBOLS = P25_NID_LENGTH_BYTES * 4U;
const unsigned int P25_NID_LENGTH_SAMPLES = P25_NID_LENGTH_SYMBOLS * P25_RADIO_SYMBOL_LENGTH;
const uint8_t P25_SYNC_BYTES[] = {0x55U, 0x75U, 0xF5U, 0xFFU, 0x77U, 0xFFU};
const uint8_t P25_SYNC_BYTES_LENGTH = 6U;
@@ -65,5 +72,13 @@ const int8_t P25_SYNC_SYMBOLS_VALUES[] = {+3, +3, +3, +3, +3, -3, +3, +3, -3, -3
const uint32_t P25_SYNC_SYMBOLS = 0x00FB30A0U;
const uint32_t P25_SYNC_SYMBOLS_MASK = 0x00FFFFFFU;
const uint8_t P25_DUID_HDU = 0x00U; // Header Data Unit
const uint8_t P25_DUID_TDU = 0x03U; // Simple Terminator Data Unit
const uint8_t P25_DUID_LDU1 = 0x05U; // Logical Link Data Unit 1
const uint8_t P25_DUID_TSDU = 0x07U; // Trunking System Data Unit
const uint8_t P25_DUID_LDU2 = 0x0AU; // Logical Link Data Unit 2
const uint8_t P25_DUID_PDU = 0x0CU; // Packet Data Unit
const uint8_t P25_DUID_TDULC = 0x0FU; // Terminator Data Unit with Link Control
#endif
+69 -10
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2018 by Bryan Biedenkapp <[email protected]>
*
* 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
@@ -23,6 +24,8 @@
const q15_t SCALING_FACTOR = 18750; // Q15(0.57)
const uint8_t CORRELATION_COUNTDOWN = 10U;//5U;
const uint8_t MAX_SYNC_BIT_START_ERRS = 2U;
const uint8_t MAX_SYNC_BIT_RUN_ERRS = 4U;
@@ -60,7 +63,8 @@ m_threshold(),
m_thresholdVal(0),
m_averagePtr(NOAVEPTR),
m_rssiAccum(0U),
m_rssiCount(0U)
m_rssiCount(0U),
m_duid(0U)
{
}
@@ -84,6 +88,7 @@ void CP25RX::reset()
m_countdown = 0U;
m_rssiAccum = 0U;
m_rssiCount = 0U;
m_duid = 0U;
}
void CP25RX::samples(const q15_t* samples, uint16_t* rssi, uint8_t length)
@@ -113,8 +118,10 @@ void CP25RX::samples(const q15_t* samples, uint16_t* rssi, uint8_t length)
}
m_dataPtr++;
if (m_dataPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
if (m_dataPtr >= P25_LDU_FRAME_LENGTH_SAMPLES) {
m_dataPtr = 0U;
m_duid = 0U;
}
m_bitPtr++;
if (m_bitPtr >= P25_RADIO_SYMBOL_LENGTH)
@@ -136,7 +143,7 @@ void CP25RX::processNone(q15_t sample)
m_averagePtr = NOAVEPTR;
m_countdown = 5U;
m_countdown = CORRELATION_COUNTDOWN;
}
}
@@ -169,16 +176,67 @@ void CP25RX::processHdr(q15_t sample)
}
if (m_dataPtr == m_maxSyncPtr) {
if (m_hdrSyncPtr != m_lduSyncPtr) {
calculateLevels(m_hdrStartPtr, P25_HDR_FRAME_LENGTH_SYMBOLS);
uint16_t nidStartPtr = m_hdrStartPtr + P25_SYNC_LENGTH_SAMPLES;
if (nidStartPtr >= P25_LDU_FRAME_LENGTH_SAMPLES)
nidStartPtr -= P25_LDU_FRAME_LENGTH_SAMPLES;
DEBUG4("P25RX: sync found in Hdr pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
uint8_t nid[2U];
samplesToBits(nidStartPtr, (2U * 4U), nid, 0U, m_centreVal, m_thresholdVal);
// DEBUG3("P25RX: nid (b0 - b1)", nid[0U], nid[1U]);
uint8_t frame[P25_HDR_FRAME_LENGTH_BYTES + 1U];
samplesToBits(m_hdrStartPtr, P25_HDR_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
m_duid = nid[1U] & 0x0F;
frame[0U] = 0x01U;
serial.writeP25Hdr(frame, P25_HDR_FRAME_LENGTH_BYTES + 1U);
switch (m_duid) {
case P25_DUID_HDU: {
calculateLevels(m_hdrStartPtr, P25_HDR_FRAME_LENGTH_SYMBOLS);
DEBUG4("P25RX: sync found in Hdr pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
uint8_t frame[P25_HDR_FRAME_LENGTH_BYTES + 1U];
samplesToBits(m_hdrStartPtr, P25_HDR_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
frame[0U] = 0x01U;
serial.writeP25Hdr(frame, P25_HDR_FRAME_LENGTH_BYTES + 1U);
}
break;
case P25_DUID_TSDU: {
calculateLevels(m_hdrStartPtr, P25_TSDU_FRAME_LENGTH_SYMBOLS);
DEBUG4("P25RX: sync found in TSDU pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
uint8_t frame[P25_TSDU_FRAME_LENGTH_BYTES + 1U];
samplesToBits(m_hdrStartPtr, P25_TSDU_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
frame[0U] = 0x01U;
serial.writeP25Hdr(frame, P25_TSDU_FRAME_LENGTH_BYTES + 1U);
}
break;
case P25_DUID_TDU: {
calculateLevels(m_hdrStartPtr, P25_TERM_FRAME_LENGTH_SYMBOLS);
DEBUG4("P25RX: sync found in TDU pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
uint8_t frame[P25_TERM_FRAME_LENGTH_BYTES + 1U];
samplesToBits(m_hdrStartPtr, P25_TERM_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
frame[0U] = 0x01U;
serial.writeP25Hdr(frame, P25_TERM_FRAME_LENGTH_BYTES + 1U);
}
break;
case P25_DUID_TDULC: {
calculateLevels(m_hdrStartPtr, P25_TERMLC_FRAME_LENGTH_SYMBOLS);
DEBUG4("P25RX: sync found in TDULC pos/centre/threshold", m_hdrSyncPtr, m_centreVal, m_thresholdVal);
uint8_t frame[P25_TERMLC_FRAME_LENGTH_BYTES + 1U];
samplesToBits(m_hdrStartPtr, P25_TERMLC_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal);
frame[0U] = 0x01U;
serial.writeP25Hdr(frame, P25_TERMLC_FRAME_LENGTH_BYTES + 1U);
}
break;
default:
break;
}
m_minSyncPtr = m_lduSyncPtr + P25_LDU_FRAME_LENGTH_SAMPLES - 1U;
@@ -238,6 +296,7 @@ void CP25RX::processLdu(q15_t sample)
m_averagePtr = NOAVEPTR;
m_countdown = 0U;
m_maxCorr = 0;
m_duid = 0U;
} else {
frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U;
writeRSSILdu(frame);
+2
View File
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2018 by Bryan Biedenkapp <[email protected]>
*
* 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
@@ -59,6 +60,7 @@ private:
uint8_t m_averagePtr;
uint32_t m_rssiAccum;
uint16_t m_rssiCount;
uint8_t m_duid;
void processNone(q15_t sample);
void processHdr(q15_t sample);
+1 -1
View File
@@ -43,7 +43,7 @@ const q15_t P25_LEVELD = -1260;
const uint8_t P25_START_SYNC = 0x77U;
CP25TX::CP25TX() :
m_buffer(1500U),
m_buffer(4000U),
m_modFilter(),
m_lpFilter(),
m_modState(),
+149
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 = 20U;
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};
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};
static q15_t SHAPING_FILTER[] = {5461, 5461, 5461, 5461, 5461, 5461};
const uint16_t SHAPING_FILTER_LEN = 6U;
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, 170U * 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
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[170U]; // NoTaps + BlockSize - 1, 6 + 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
+3 -3
View File
@@ -1,7 +1,7 @@
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion and P25 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.
-2
View File
@@ -22,7 +22,6 @@ Boston, MA 02110-1301, USA.
CRSSIRB::CRSSIRB(uint16_t length) :
m_length(length),
m_rssi(NULL),
m_head(0U),
m_tail(0U),
m_full(false),
@@ -101,4 +100,3 @@ bool CRSSIRB::hasOverflowed()
return overflow;
}
Submodule
+1
Submodule STM32F4XX_Lib added at bcd346f530
Submodule
+1
Submodule STM32F7XX_Lib added at 2d5f4236fa
-2
View File
@@ -22,8 +22,6 @@ Boston, MA 02110-1301, USA.
CSampleRB::CSampleRB(uint16_t length) :
m_length(length),
m_samples(NULL),
m_control(NULL),
m_head(0U),
m_tail(0U),
m_full(false),
+4 -1
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)
{
+87 -29
View File
@@ -63,30 +63,41 @@ 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;
const uint8_t MMDVM_SERIAL = 0x80U;
const uint8_t MMDVM_TRANSPARENT = 0x90U;
const uint8_t MMDVM_DEBUG1 = 0xF1U;
const uint8_t MMDVM_DEBUG2 = 0xF2U;
const uint8_t MMDVM_DEBUG3 = 0xF3U;
const uint8_t MMDVM_DEBUG4 = 0xF4U;
const uint8_t MMDVM_DEBUG5 = 0xF5U;
#if defined(EXTERNAL_OSC)
#define DESCRIPTION "MMDVM 20170501 TCXO (D-Star/DMR/System Fusion/P25/NXDN/RSSI/CW Id)"
#if EXTERNAL_OSC == 12000000
#define TCXO "12.0000 MHz"
#elif EXTERNAL_OSC == 12288000
#define TCXO "12.2880 MHz"
#elif EXTERNAL_OSC == 14400000
#define TCXO "14.4000 MHz"
#elif EXTERNAL_OSC == 19200000
#define TCXO "19.2000 Mhz"
#else
#define DESCRIPTION "MMDVM 20170501 (D-Star/DMR/System Fusion/P25/NXDN/RSSI/CW Id)"
#define TCXO "NO TCXO"
#endif
#define DESCRIPTION "MMDVM 20180723 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG)"
#if defined(GITVERSION)
#define concat(a, b) a " GitID #" b ""
const char HARDWARE[] = concat(DESCRIPTION, GITVERSION);
#define concat(a, b, c) a " " b " GitID #" c ""
const char HARDWARE[] = concat(DESCRIPTION, TCXO, GITVERSION);
#else
#define concat(a, b, c) a " (Build: " b " " c ")"
const char HARDWARE[] = concat(DESCRIPTION, __TIME__, __DATE__);
#define concat(a, b, c, d) a " " b " (Build: " c " " d ")"
const char HARDWARE[] = concat(DESCRIPTION, TCXO, __TIME__, __DATE__);
#endif
const uint8_t PROTOCOL_VERSION = 1U;
@@ -130,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] = 11U;
reply[1U] = 13U;
reply[2U] = MMDVM_GET_STATUS;
reply[3U] = 0x00U;
@@ -148,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);
@@ -207,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;
@@ -231,7 +249,7 @@ void CSerialPort::getVersion()
uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
{
if (length < 16U)
if (length < 18U)
return 4U;
bool rxInvert = (data[0U] & 0x01U) == 0x01U;
@@ -242,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)
@@ -254,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;
@@ -266,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];
@@ -284,22 +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 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);
@@ -307,9 +334,9 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
dmrDMORX.setColorCode(colorCode);
dmrIdleRX.setColorCode(colorCode);
ysfTX.setLoDev(ysfLoDev);
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();
@@ -326,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;
@@ -338,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);
@@ -395,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();
@@ -759,6 +799,24 @@ 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;
#if defined(SERIAL_REPEATER)
case MMDVM_SERIAL: {
for (uint8_t i = 3U; i < m_len; i++)
-1
View File
@@ -22,7 +22,6 @@ Boston, MA 02110-1301, USA.
CSerialRB::CSerialRB(uint16_t length) :
m_length(length),
m_buffer(NULL),
m_head(0U),
m_tail(0U),
m_full(false)
+1 -1
View File
@@ -32,7 +32,7 @@ Boston, MA 02110-1301, USA.
#include <Arduino.h>
#endif
const uint16_t SERIAL_RINGBUFFER_SIZE = 370U;
const uint16_t SERIAL_RINGBUFFER_SIZE = 1000U;
class CSerialRB {
public:
+9 -9
View File
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
* Copyright (C) 2016, 2017 by Andy Uribe CA6JAU
* Copyright (C) 2016,2017,2018 by Andy Uribe CA6JAU
* Copyright (c) 2017 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
@@ -27,14 +27,14 @@
Pin definitions:
- Host communication:
USART1 - TXD PA9 - RXD PA10 (MMDVM-Pi board, MMDVM-Pi F722 board, MMDVM-F4M board)
USART1 - TXD PA9 - RXD PA10 (MMDVM-Pi board, MMDVM-Pi F722 board, MMDVM-F4M board, STM32F722-F7M board, STM32F4-DVM board)
USART2 - TXD PA2 - RXD PA3 (Nucleo64 F446RE board, Morpho or Arduino header)
USART3 - TXD PC10 - RXD PC11 (Discovery board)
USART3 - TXD PD8 - RXD PD9 (Nucleo144 F767ZI board)
- Serial repeater:
USART1 - TXD PA9 - RXD PA10 (Nucleo with Arduino header)
UART5 - TXD PC12 - RXD PD2 (Discovery, MMDVM-Pi, MMDVM-Pi F722 board, MMDVM-F4M board, Nucleo64 with Morpho header and Nucleo144 F767ZI)
UART5 - TXD PC12 - RXD PD2 (Discovery, MMDVM-Pi, MMDVM-Pi F722 board, MMDVM-F4M board, STM32F722-F7M board, STM32F4-DVM board, Nucleo64 with Morpho header and Nucleo144 F767ZI)
*/
#if defined(STM32F4XX) || defined(STM32F7XX)
@@ -50,7 +50,7 @@ extern "C" {
}
/* ************* USART1 ***************** */
#if defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || (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)
#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)
#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)
#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)
#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)
#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();
+42 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2009-2017 by Jonathan Naylor G4KLX
* Copyright (C) 2009-2018 by Jonathan Naylor G4KLX
* Copyright (C) 2017 by Andy Uribe CA6JAU
*
* This program is free software; you can redistribute it and/or modify
@@ -41,16 +41,19 @@ const q15_t YSF_LEVELD_LO = -948;
const uint8_t YSF_START_SYNC = 0x77U;
const uint8_t YSF_END_SYNC = 0xFFU;
const uint8_t YSF_HANG = 0x00U;
CYSFTX::CYSFTX() :
m_buffer(1500U),
m_buffer(4000U),
m_modFilter(),
m_modState(),
m_poBuffer(),
m_poLen(0U),
m_poPtr(0U),
m_txDelay(240U), // 200ms
m_loDev(false)
m_loDev(false),
m_txHang(4800U), // 4s
m_txCount(0U)
{
::memset(m_modState, 0x00U, 16U * sizeof(q15_t));
@@ -60,12 +63,14 @@ m_loDev(false)
m_modFilter.pState = m_modState;
}
void CYSFTX::process()
{
if (m_buffer.getData() == 0U && m_poLen == 0U)
if (m_buffer.getData() == 0U && m_poLen == 0U && m_txCount == 0U)
return;
if (m_poLen == 0U) {
// If we have YSF data to transmit, do so.
if (m_poLen == 0U && m_buffer.getData() > 0U) {
if (!m_tx) {
for (uint16_t i = 0U; i < m_txDelay; i++)
m_poBuffer[m_poLen++] = YSF_START_SYNC;
@@ -80,20 +85,37 @@ void CYSFTX::process()
}
if (m_poLen > 0U) {
// Transmit YSF data.
uint16_t space = io.getSpace();
while (space > (4U * YSF_RADIO_SYMBOL_LENGTH)) {
uint8_t c = m_poBuffer[m_poPtr++];
writeByte(c);
// Reduce space and reset the hang timer.
space -= 4U * YSF_RADIO_SYMBOL_LENGTH;
if (m_duplex)
m_txCount = m_txHang;
if (m_poPtr >= m_poLen) {
m_poPtr = 0U;
m_poLen = 0U;
return;
}
}
} else if (m_txCount > 0U) {
// Transmit silence until the hang timer has expired.
uint16_t space = io.getSpace();
while (space > (4U * YSF_RADIO_SYMBOL_LENGTH)) {
writeSilence();
space -= 4U * YSF_RADIO_SYMBOL_LENGTH;
m_txCount--;
if (m_txCount == 0U)
return;
}
}
}
@@ -141,6 +163,16 @@ void CYSFTX::writeByte(uint8_t c)
io.write(STATE_YSF, outBuffer, YSF_RADIO_SYMBOL_LENGTH * 4U);
}
void CYSFTX::writeSilence()
{
q15_t inBuffer[4U] = {0x00U, 0x00U, 0x00U, 0x00U};
q15_t outBuffer[YSF_RADIO_SYMBOL_LENGTH * 4U];
::arm_fir_interpolate_q15(&m_modFilter, inBuffer, outBuffer, 4U);
io.write(STATE_YSF, outBuffer, YSF_RADIO_SYMBOL_LENGTH * 4U);
}
void CYSFTX::setTXDelay(uint8_t delay)
{
m_txDelay = 600U + uint16_t(delay) * 12U; // 500ms + tx delay
@@ -154,8 +186,9 @@ uint8_t CYSFTX::getSpace() const
return m_buffer.getSpace() / YSF_FRAME_LENGTH_BYTES;
}
void CYSFTX::setLoDev(bool on)
void CYSFTX::setParams(bool on, uint8_t txHang)
{
m_loDev = on;
m_loDev = on;
m_txHang = txHang * 1200U;
}
+4 -1
View File
@@ -35,7 +35,7 @@ public:
uint8_t getSpace() const;
void setLoDev(bool on);
void setParams(bool on, uint8_t txHang);
private:
CSerialRB m_buffer;
@@ -46,8 +46,11 @@ private:
uint16_t m_poPtr;
uint16_t m_txDelay;
bool m_loDev;
uint32_t m_txHang;
uint32_t m_txCount;
void writeByte(uint8_t c);
void writeSilence();
};
#endif
+1 -1
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";;