From 20a0a875f3bbd59643f534ee0e790dec35d0ccee Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 6 Jun 2018 20:27:46 +0100 Subject: [PATCH 01/17] Add the POCSAG transmitter. --- Globals.h | 5 ++ IO.cpp | 64 ++++++++++++++++++------ IO.h | 4 +- IODue.cpp | 4 ++ IOSTM.cpp | 4 ++ IOSTM_CMSIS.cpp | 4 ++ IOTeensy.cpp | 4 ++ MMDVM.cpp | 16 ++++-- MMDVM.ino | 16 ++++-- POCSAGTX.cpp | 128 ++++++++++++++++++++++++++++++++++++++++++++++++ POCSAGTX.h | 49 ++++++++++++++++++ SerialPort.cpp | 81 +++++++++++++++++++++++------- 12 files changed, 335 insertions(+), 44 deletions(-) create mode 100644 POCSAGTX.cpp create mode 100644 POCSAGTX.h diff --git a/Globals.h b/Globals.h index 9ab7d31..d68e2c5 100644 --- a/Globals.h +++ b/Globals.h @@ -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; diff --git a/IO.cpp b/IO.cpp index 1260817..96b0128 100644 --- a/IO.cpp +++ b/IO.cpp @@ -79,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), @@ -142,6 +143,7 @@ void CIO::selfTest() setYSFInt(ledValue); setP25Int(ledValue); setNXDNInt(ledValue); + setPOCSAGInt(ledValue); #endif delayInt(250); } @@ -152,6 +154,7 @@ void CIO::selfTest() setYSFInt(false); setP25Int(false); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -160,6 +163,7 @@ void CIO::selfTest() setYSFInt(false); setP25Int(false); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -168,6 +172,7 @@ void CIO::selfTest() setYSFInt(true); setP25Int(false); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -176,6 +181,7 @@ void CIO::selfTest() setYSFInt(true); setP25Int(true); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -184,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); @@ -192,6 +217,7 @@ void CIO::selfTest() setYSFInt(true); setP25Int(true); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -200,6 +226,7 @@ void CIO::selfTest() setYSFInt(true); setP25Int(false); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -208,6 +235,7 @@ void CIO::selfTest() setYSFInt(false); setP25Int(false); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -216,6 +244,7 @@ void CIO::selfTest() setYSFInt(false); setP25Int(false); setNXDNInt(false); + setPOCSAGInt(false); delayInt(250); @@ -224,6 +253,7 @@ void CIO::selfTest() setYSFInt(false); setP25Int(false); setNXDNInt(false); + setPOCSAGInt(false); #endif } @@ -245,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; @@ -472,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; @@ -519,20 +552,22 @@ void CIO::setMode() 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; @@ -541,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; } } diff --git a/IO.h b/IO.h index 79a2b69..4a7df28 100644 --- a/IO.h +++ b/IO.h @@ -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); @@ -85,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; @@ -116,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); }; diff --git a/IODue.cpp b/IODue.cpp index 7e86ae5..e5fa88b 100644 --- a/IODue.cpp +++ b/IODue.cpp @@ -235,6 +235,10 @@ void CIO::setNXDNInt(bool on) digitalWrite(PIN_NXDN, on ? HIGH : LOW); } +void CIO::setPOCSAGInt(bool on) +{ +} + void CIO::delayInt(unsigned int dly) { delay(dly); diff --git a/IOSTM.cpp b/IOSTM.cpp index 6647ab0..d8d84cc 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -1121,6 +1121,10 @@ void CIO::setNXDNInt(bool on) #endif } +void CIO::setPOCSAGInt(bool on) +{ +} + // Simple delay function for STM32 // Example from: http://thehackerworkshop.com/?p=1209 void CIO::delayInt(unsigned int dly) diff --git a/IOSTM_CMSIS.cpp b/IOSTM_CMSIS.cpp index 997c92b..7bded9c 100644 --- a/IOSTM_CMSIS.cpp +++ b/IOSTM_CMSIS.cpp @@ -434,6 +434,10 @@ void CIO::setNXDNInt(bool on) BB_NXDN = !!on; } +void CIO::setPOCSAGInt(bool on) +{ +} + void CIO::delayInt(unsigned int dly) { delay(dly); diff --git a/IOTeensy.cpp b/IOTeensy.cpp index 2440230..b1091c0 100644 --- a/IOTeensy.cpp +++ b/IOTeensy.cpp @@ -221,6 +221,10 @@ void CIO::setNXDNInt(bool on) digitalWrite(PIN_NXDN, on ? HIGH : LOW); } +void CIO::setPOCSAGInt(bool on) +{ +} + void CIO::delayInt(unsigned int dly) { delay(dly); diff --git a/MMDVM.cpp b/MMDVM.cpp index d4a12a9..639a068 100644 --- a/MMDVM.cpp +++ b/MMDVM.cpp @@ -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.process(); + if (m_modemState == STATE_DSTARCAL) calDStarTX.process(); diff --git a/MMDVM.ino b/MMDVM.ino index 0b0f852..ff317eb 100644 --- a/MMDVM.ino +++ b/MMDVM.ino @@ -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.process(); + if (m_modemState == STATE_DSTARCAL) calDStarTX.process(); diff --git a/POCSAGTX.cpp b/POCSAGTX.cpp new file mode 100644 index 0000000..0f243d1 --- /dev/null +++ b/POCSAGTX.cpp @@ -0,0 +1,128 @@ +/* + * 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_PREAMBLE_LENGTH_BYTES = 576U / 8U; + +const uint16_t POCSAG_FRAME_LENGTH_BYTES = 17U * sizeof(uint32_t); + +const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 20U; + +const q15_t POCSAG_LEVEL0[] = { 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155}; +const q15_t POCSAG_LEVEL1[] = {-3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155}; + +const uint8_t POCSAG_SYNC = 0xAAU; + +CPOCSAGTX::CPOCSAGTX() : +m_buffer(4000U), +m_poBuffer(), +m_poLen(0U), +m_poPtr(0U), +m_txDelay(POCSAG_PREAMBLE_LENGTH_BYTES) +{ +} + +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; + } + } + } +} + +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 buffer[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(buffer + n, POCSAG_LEVEL1, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t)); + break; + default: + ::memcpy(buffer + n, POCSAG_LEVEL0, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t)); + break; + } + } + + io.write(STATE_POCSAG, buffer, POCSAG_RADIO_SYMBOL_LENGTH * 8U); +} + +void CPOCSAGTX::setTXDelay(uint8_t delay) +{ + m_txDelay = POCSAG_PREAMBLE_LENGTH_BYTES + uint16_t(delay); + + if (m_txDelay > 1200U) + m_txDelay = 1200U; +} + +uint8_t CPOCSAGTX::getSpace() const +{ + return m_buffer.getSpace() / POCSAG_FRAME_LENGTH_BYTES; +} + diff --git a/POCSAGTX.h b/POCSAGTX.h new file mode 100644 index 0000000..a2f487b --- /dev/null +++ b/POCSAGTX.h @@ -0,0 +1,49 @@ +/* + * 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; + +private: + CSerialRB m_buffer; + uint8_t m_poBuffer[1200U]; + uint16_t m_poLen; + uint16_t m_poPtr; + uint16_t m_txDelay; + + void writeByte(uint8_t c); +}; + +#endif + diff --git a/SerialPort.cpp b/SerialPort.cpp index 564df2d..b879cca 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -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; @@ -86,7 +88,7 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U; #define TCXO "19.2000" #endif -#define DESCRIPTION "MMDVM 20180327 (D-Star/DMR/System Fusion/P25/NXDN)" +#define DESCRIPTION "MMDVM 20180327 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG)" #if defined(GITVERSION) #define concat(a, b, c) a " " b "MHz GitID #" c "" @@ -155,6 +157,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); @@ -214,7 +218,12 @@ 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() @@ -238,7 +247,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; @@ -249,11 +258,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) @@ -261,7 +271,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; @@ -273,6 +283,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]; @@ -291,24 +303,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); @@ -318,7 +334,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(); @@ -335,7 +351,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; @@ -347,6 +363,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); @@ -404,6 +422,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(); @@ -768,6 +797,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; From b6cb23d87670bf0448fcde418f4815468c7757e9 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 12 Jun 2018 20:59:39 +0100 Subject: [PATCH 02/17] Invert the transmit frequencies. --- POCSAGTX.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/POCSAGTX.cpp b/POCSAGTX.cpp index 0f243d1..9019155 100644 --- a/POCSAGTX.cpp +++ b/POCSAGTX.cpp @@ -26,8 +26,8 @@ const uint16_t POCSAG_FRAME_LENGTH_BYTES = 17U * sizeof(uint32_t); const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 20U; -const q15_t POCSAG_LEVEL0[] = { 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155}; -const q15_t POCSAG_LEVEL1[] = {-3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155}; +const q15_t POCSAG_LEVEL1[] = { 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155}; +const q15_t POCSAG_LEVEL0[] = {-3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155}; const uint8_t POCSAG_SYNC = 0xAAU; From 56ced0d93989beb53f07bbec6c3a892f3498c87b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 12 Jun 2018 21:42:15 +0100 Subject: [PATCH 03/17] Decrease the deviation. --- POCSAGTX.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/POCSAGTX.cpp b/POCSAGTX.cpp index 9019155..ddbeb88 100644 --- a/POCSAGTX.cpp +++ b/POCSAGTX.cpp @@ -26,8 +26,8 @@ const uint16_t POCSAG_FRAME_LENGTH_BYTES = 17U * sizeof(uint32_t); const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 20U; -const q15_t POCSAG_LEVEL1[] = { 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155, 3155}; -const q15_t POCSAG_LEVEL0[] = {-3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155, -3155}; +const q15_t POCSAG_LEVEL1[] = { 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853}; +const q15_t POCSAG_LEVEL0[] = {-1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853}; const uint8_t POCSAG_SYNC = 0xAAU; From d151c100db8a1facf9ebf9c2a8beb2f1ec398706 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 14 Jun 2018 07:25:09 +0100 Subject: [PATCH 04/17] Fix length of the getConfig reply. --- SerialPort.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerialPort.cpp b/SerialPort.cpp index b879cca..11e4cea 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -139,11 +139,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; From ce05dec2e663415bb633736ab46bce72c8f866ba Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 18 Jun 2018 21:32:08 +0100 Subject: [PATCH 05/17] Fix crash caused by the larger version string. --- SerialPort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialPort.cpp b/SerialPort.cpp index d2011fe..a805ab7 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -230,7 +230,7 @@ void CSerialPort::getStatus() void CSerialPort::getVersion() { - uint8_t reply[100U]; + uint8_t reply[150U]; reply[0U] = MMDVM_FRAME_START; reply[1U] = 0U; From ef3298882773b159ae73e645a41f4c0b8fda7f36 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 18 Jun 2018 22:12:13 +0100 Subject: [PATCH 06/17] More tweaking of the POCSAG deviation. --- POCSAGTX.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/POCSAGTX.cpp b/POCSAGTX.cpp index ddbeb88..9fb6068 100644 --- a/POCSAGTX.cpp +++ b/POCSAGTX.cpp @@ -26,8 +26,8 @@ const uint16_t POCSAG_FRAME_LENGTH_BYTES = 17U * sizeof(uint32_t); const uint16_t POCSAG_RADIO_SYMBOL_LENGTH = 20U; -const q15_t POCSAG_LEVEL1[] = { 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853, 1853}; -const q15_t POCSAG_LEVEL0[] = {-1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853, -1853}; +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}; const uint8_t POCSAG_SYNC = 0xAAU; From 2098146af844f9d622eeced875b941b97b1f86e8 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 19 Jun 2018 18:01:24 +0100 Subject: [PATCH 07/17] Rename ARDUINO_MODE_PINS to MODE_PINS. --- Config.h | 4 ++-- IO.cpp | 6 +++--- IODue.cpp | 2 +- IOSTM.cpp | 2 +- IOTeensy.cpp | 2 +- MMDVM_STM32F4xx.coproj | 2 +- mmdvmmenu.sh | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Config.h b/Config.h index c8e78a1..baad81d 100644 --- a/Config.h +++ b/Config.h @@ -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 diff --git a/IO.cpp b/IO.cpp index 96b0128..8e718ab 100644 --- a/IO.cpp +++ b/IO.cpp @@ -137,7 +137,7 @@ 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); @@ -148,7 +148,7 @@ void CIO::selfTest() delayInt(250); } -#if defined(ARDUINO_MODE_PINS) +#if defined(MODE_PINS) setDStarInt(true); setDMRInt(false); setYSFInt(false); @@ -546,7 +546,7 @@ 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); diff --git a/IODue.cpp b/IODue.cpp index e5fa88b..8b5fff1 100644 --- a/IODue.cpp +++ b/IODue.cpp @@ -92,7 +92,7 @@ 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); diff --git a/IOSTM.cpp b/IOSTM.cpp index d8d84cc..bb5a1d3 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -812,7 +812,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; diff --git a/IOTeensy.cpp b/IOTeensy.cpp index b1091c0..3b74c99 100644 --- a/IOTeensy.cpp +++ b/IOTeensy.cpp @@ -62,7 +62,7 @@ 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); diff --git a/MMDVM_STM32F4xx.coproj b/MMDVM_STM32F4xx.coproj index 6bfeefe..d269fbd 100644 --- a/MMDVM_STM32F4xx.coproj +++ b/MMDVM_STM32F4xx.coproj @@ -97,7 +97,7 @@ - + diff --git a/mmdvmmenu.sh b/mmdvmmenu.sh index b5f5ded..014e32b 100755 --- a/mmdvmmenu.sh +++ b/mmdvmmenu.sh @@ -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";; From 9eb6bc1a6049b5005e2715f88bb4c8df4d6c1720 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 19 Jun 2018 18:17:05 +0100 Subject: [PATCH 08/17] Add the POCSAG mode pin for the Arduino Due, Teensy 3.2/3.6 and the STM32F105. --- IODue.cpp | 5 +++++ IOSTM_CMSIS.cpp | 22 ++++++++++++++-------- IOTeensy.cpp | 4 ++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/IODue.cpp b/IODue.cpp index 8b5fff1..d568e1d 100644 --- a/IODue.cpp +++ b/IODue.cpp @@ -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 @@ -99,6 +102,7 @@ void CIO::initInt() pinMode(PIN_YSF, OUTPUT); pinMode(PIN_P25, OUTPUT); pinMode(PIN_NXDN, OUTPUT); + pinMode(PIN_POCSAG, OUTPUT); #endif } @@ -237,6 +241,7 @@ void CIO::setNXDNInt(bool on) void CIO::setPOCSAGInt(bool on) { + digitalWrite(PIN_POCSAG, on ? HIGH : LOW); } void CIO::delayInt(unsigned int dly) diff --git a/IOSTM_CMSIS.cpp b/IOSTM_CMSIS.cpp index 7bded9c..43e9d89 100644 --- a/IOSTM_CMSIS.cpp +++ b/IOSTM_CMSIS.cpp @@ -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,17 @@ 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); + GPIOConfigPin(PORT_NXDN, PIN_NXDN, GPIO_CRL_MODE0_1); + GPIOConfigPin(PORT_POCSAG, PIN_POCSAG, GPIO_CRL_MODE0_1); GPIOConfigPin(PORT_RX, PIN_RX, 0); #if defined(SEND_RSSI_DATA) @@ -436,6 +441,7 @@ void CIO::setNXDNInt(bool on) void CIO::setPOCSAGInt(bool on) { + BB_POCSAG = !!on; } void CIO::delayInt(unsigned int dly) diff --git a/IOTeensy.cpp b/IOTeensy.cpp index 3b74c99..cf07856 100644 --- a/IOTeensy.cpp +++ b/IOTeensy.cpp @@ -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 @@ -69,6 +71,7 @@ void CIO::initInt() pinMode(PIN_YSF, OUTPUT); pinMode(PIN_P25, OUTPUT); pinMode(PIN_NXDN, OUTPUT); + pinMode(PIN_POCSAG, OUTPUT); #endif } @@ -223,6 +226,7 @@ void CIO::setNXDNInt(bool on) void CIO::setPOCSAGInt(bool on) { + digitalWrite(PIN_POCSAG, on ? HIGH : LOW); } void CIO::delayInt(unsigned int dly) From dcd8142c51f92063ccfdb6794faf482369464575 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 25 Jun 2018 18:00:11 +0100 Subject: [PATCH 09/17] Add a smoothing filter to the POCSAG TX waveform. --- POCSAGTX.cpp | 21 +++++++++++++++++---- POCSAGTX.h | 12 +++++++----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/POCSAGTX.cpp b/POCSAGTX.cpp index 9fb6068..6a15e59 100644 --- a/POCSAGTX.cpp +++ b/POCSAGTX.cpp @@ -29,15 +29,25 @@ 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() @@ -94,7 +104,8 @@ uint8_t CPOCSAGTX::writeData(const uint8_t* data, uint8_t length) void CPOCSAGTX::writeByte(uint8_t c) { - q15_t buffer[POCSAG_RADIO_SYMBOL_LENGTH * 8U]; + q15_t inBuffer[POCSAG_RADIO_SYMBOL_LENGTH * 8U]; + q15_t outBuffer[POCSAG_RADIO_SYMBOL_LENGTH * 8U]; const uint8_t MASK = 0x80U; @@ -102,15 +113,17 @@ void CPOCSAGTX::writeByte(uint8_t c) for (uint8_t i = 0U; i < 8U; i++, c <<= 1, n += POCSAG_RADIO_SYMBOL_LENGTH) { switch (c & MASK) { case 0x80U: - ::memcpy(buffer + n, POCSAG_LEVEL1, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t)); + ::memcpy(inBuffer + n, POCSAG_LEVEL1, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t)); break; default: - ::memcpy(buffer + n, POCSAG_LEVEL0, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t)); + ::memcpy(inBuffer + n, POCSAG_LEVEL0, POCSAG_RADIO_SYMBOL_LENGTH * sizeof(q15_t)); break; } } - io.write(STATE_POCSAG, buffer, POCSAG_RADIO_SYMBOL_LENGTH * 8U); + ::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) diff --git a/POCSAGTX.h b/POCSAGTX.h index a2f487b..e0b2d3a 100644 --- a/POCSAGTX.h +++ b/POCSAGTX.h @@ -36,11 +36,13 @@ public: uint8_t getSpace() const; private: - CSerialRB m_buffer; - uint8_t m_poBuffer[1200U]; - uint16_t m_poLen; - uint16_t m_poPtr; - uint16_t m_txDelay; + 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[1200U]; + uint16_t m_poLen; + uint16_t m_poPtr; + uint16_t m_txDelay; void writeByte(uint8_t c); }; From 76d20580757b6242dd4d015e83892752f9b70e89 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 26 Jun 2018 18:16:13 +0100 Subject: [PATCH 10/17] Recalculate the TX delay for POCSAG. --- POCSAGTX.cpp | 10 +++++----- POCSAGTX.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/POCSAGTX.cpp b/POCSAGTX.cpp index 6a15e59..8306410 100644 --- a/POCSAGTX.cpp +++ b/POCSAGTX.cpp @@ -20,10 +20,10 @@ #include "Globals.h" #include "POCSAGTX.h" -const uint16_t POCSAG_PREAMBLE_LENGTH_BYTES = 576U / 8U; - 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}; @@ -128,10 +128,10 @@ void CPOCSAGTX::writeByte(uint8_t c) void CPOCSAGTX::setTXDelay(uint8_t delay) { - m_txDelay = POCSAG_PREAMBLE_LENGTH_BYTES + uint16_t(delay); + m_txDelay = POCSAG_PREAMBLE_LENGTH_BYTES + (delay * 3U) / 2U; - if (m_txDelay > 1200U) - m_txDelay = 1200U; + if (m_txDelay > 150U) + m_txDelay = 150U; } uint8_t CPOCSAGTX::getSpace() const diff --git a/POCSAGTX.h b/POCSAGTX.h index e0b2d3a..ea41b7f 100644 --- a/POCSAGTX.h +++ b/POCSAGTX.h @@ -39,7 +39,7 @@ 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[1200U]; + uint8_t m_poBuffer[200U]; uint16_t m_poLen; uint16_t m_poPtr; uint16_t m_txDelay; From 78d79d41244ac4fae70bbf736f41380b3e87bbfa Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 26 Jun 2018 18:18:43 +0100 Subject: [PATCH 11/17] Update the README file. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e596822..8e994ab 100644 --- a/README.md +++ b/README.md @@ -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. From a4af04fae2c7e452ec326f7caeece156212553df Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 4 Jul 2018 18:40:54 +0100 Subject: [PATCH 12/17] Allow for alternative LEDs for NXDN and POCSAG. --- Config.h | 7 +++++++ IODue.cpp | 10 ++++++++++ IOSTM.cpp | 17 +++++++++++++++++ IOSTM_CMSIS.cpp | 10 ++++++++++ IOTeensy.cpp | 12 +++++++++++- 5 files changed, 55 insertions(+), 1 deletion(-) diff --git a/Config.h b/Config.h index baad81d..fb9f74d 100644 --- a/Config.h +++ b/Config.h @@ -73,4 +73,11 @@ // 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 + diff --git a/IODue.cpp b/IODue.cpp index d568e1d..e57de1a 100644 --- a/IODue.cpp +++ b/IODue.cpp @@ -236,12 +236,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) diff --git a/IOSTM.cpp b/IOSTM.cpp index bb5a1d3..ff4d742 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -1115,14 +1115,31 @@ 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 +#endif } // Simple delay function for STM32 diff --git a/IOSTM_CMSIS.cpp b/IOSTM_CMSIS.cpp index 43e9d89..d996fce 100644 --- a/IOSTM_CMSIS.cpp +++ b/IOSTM_CMSIS.cpp @@ -436,12 +436,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) diff --git a/IOTeensy.cpp b/IOTeensy.cpp index cf07856..03c6ebf 100644 --- a/IOTeensy.cpp +++ b/IOTeensy.cpp @@ -219,14 +219,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) From 5c61ee6be8233fd48cc42728aca9d91ae0c94177 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 5 Jul 2018 18:29:18 +0100 Subject: [PATCH 13/17] Add an mode output pin on the STM32-F7M board as suggested by Tom BG4TGO. --- IODue.cpp | 4 ++++ IOSTM.cpp | 32 +++++++++++++++++++++++++++++++- IOSTM_CMSIS.cpp | 6 +++++- IOTeensy.cpp | 4 ++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/IODue.cpp b/IODue.cpp index e57de1a..e06ce07 100644 --- a/IODue.cpp +++ b/IODue.cpp @@ -101,9 +101,13 @@ void CIO::initInt() 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() diff --git a/IOSTM.cpp b/IOSTM.cpp index ff4d742..6557496 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -338,6 +338,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 +371,10 @@ EXT_CLK PA15 input #define PORT_NXDN GPIOB #define RCC_Per_NXDN RCC_AHB1Periph_GPIOB +#define PIN_POCSAG GPIO_Pin_12 +#define PORT_NXDN 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 @@ -837,6 +842,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 +850,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 +884,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() @@ -1134,11 +1159,16 @@ 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); + 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 } diff --git a/IOSTM_CMSIS.cpp b/IOSTM_CMSIS.cpp index d996fce..b669d07 100644 --- a/IOSTM_CMSIS.cpp +++ b/IOSTM_CMSIS.cpp @@ -222,9 +222,13 @@ static inline void GPIOInit() 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); diff --git a/IOTeensy.cpp b/IOTeensy.cpp index 03c6ebf..10adde1 100644 --- a/IOTeensy.cpp +++ b/IOTeensy.cpp @@ -70,9 +70,13 @@ void CIO::initInt() 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() From f7056561789665c16e58839107e42a89cb44f03e Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 5 Jul 2018 18:44:31 +0100 Subject: [PATCH 14/17] Bump the version date. --- SerialPort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialPort.cpp b/SerialPort.cpp index a805ab7..a1e9f23 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -90,7 +90,7 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U; #define TCXO "NO TCXO" #endif -#define DESCRIPTION "MMDVM 20180327 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG)" +#define DESCRIPTION "MMDVM 20180705 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG)" #if defined(GITVERSION) #define concat(a, b, c) a " " b " GitID #" c "" From 88409dccd2fbd6f0b012a69f748cbf0fd327ebac Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 12 Jul 2018 00:59:08 -0400 Subject: [PATCH 15/17] Add temporary POCSAG pin definitions for F446 and F722 --- IOSTM.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/IOSTM.cpp b/IOSTM.cpp index 6557496..b8aae13 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -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 @@ -372,7 +387,7 @@ EXT_CLK PA15 input #define RCC_Per_NXDN RCC_AHB1Periph_GPIOB #define PIN_POCSAG GPIO_Pin_12 -#define PORT_NXDN GPIOB +#define PORT_POCSAG GPIOB #define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB #define PIN_DSTAR GPIO_Pin_7 @@ -420,6 +435,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 @@ -458,6 +474,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 @@ -523,6 +543,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 @@ -555,6 +576,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 From 0aea9aef38d71b476ba031506a5b67c838991d11 Mon Sep 17 00:00:00 2001 From: phl0 Date: Thu, 12 Jul 2018 07:16:40 +0200 Subject: [PATCH 16/17] Correct typo in Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bb8e3b5..2c5e005 100644 --- a/Makefile +++ b/Makefile @@ -148,7 +148,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 From d62c945887b1faddce2a3f2f80067da2a4eb4d51 Mon Sep 17 00:00:00 2001 From: phl0 Date: Thu, 12 Jul 2018 07:36:44 +0200 Subject: [PATCH 17/17] Add POCSAG pin defs for f767 target --- IOSTM.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/IOSTM.cpp b/IOSTM.cpp index b8aae13..701ebfa 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -627,6 +627,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 @@ -665,6 +666,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