first commit
This commit is contained in:
Executable
+16
@@ -0,0 +1,16 @@
|
||||
Debug
|
||||
Release
|
||||
x64
|
||||
MMDVMCal
|
||||
*.o
|
||||
*.opendb
|
||||
*.bak
|
||||
*.obj
|
||||
*~
|
||||
*.sdf
|
||||
*.log
|
||||
*.zip
|
||||
*.exe
|
||||
*.user
|
||||
*.VC.db
|
||||
.vs
|
||||
Executable
+1223
File diff suppressed because it is too large
Load Diff
Executable
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2018 by Andy Uribe CA6JAU
|
||||
* Copyright (C) 2018 by Bryan Biedenkapp N2PLL
|
||||
*
|
||||
* 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(BERCAL_H)
|
||||
#define BERCAL_H
|
||||
|
||||
class CBERCal {
|
||||
public:
|
||||
CBERCal();
|
||||
~CBERCal();
|
||||
|
||||
void DSTARFEC(const unsigned char* buffer, const unsigned char m_tag);
|
||||
void DMRFEC(const unsigned char* buffer, const unsigned char m_seq);
|
||||
void DMR1K(const unsigned char *buffer, const unsigned char m_seq);
|
||||
void YSFFEC(const unsigned char* buffer);
|
||||
void P25FEC(const unsigned char* buffer);
|
||||
void NXDNFEC(const unsigned char* buffer, const unsigned char m_tag);
|
||||
|
||||
void clock();
|
||||
|
||||
private:
|
||||
unsigned int m_errors;
|
||||
unsigned int m_bits;
|
||||
unsigned int m_frames;
|
||||
|
||||
unsigned int m_timeout;
|
||||
unsigned int m_timer;
|
||||
|
||||
void NXDNScrambler(unsigned char* data);
|
||||
unsigned int regenerateDStar(unsigned int& a, unsigned int& b);
|
||||
unsigned int regenerateDMR(unsigned int& a, unsigned int& b, unsigned int& c);
|
||||
unsigned int regenerateIMBE(const unsigned char* bytes);
|
||||
unsigned int regenerateYSFDN(unsigned char* bytes);
|
||||
|
||||
unsigned char countErrs(unsigned char a, unsigned char b);
|
||||
|
||||
void timerStart();
|
||||
void timerStop();
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+239
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 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 "CRC.h"
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
const uint8_t CRC8_TABLE[] = {
|
||||
0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31,
|
||||
0x24, 0x23, 0x2A, 0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
|
||||
0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D, 0xE0, 0xE7, 0xEE, 0xE9,
|
||||
0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
|
||||
0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1,
|
||||
0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
|
||||
0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9, 0xBE,
|
||||
0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
|
||||
0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16,
|
||||
0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
|
||||
0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80,
|
||||
0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
|
||||
0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8,
|
||||
0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
|
||||
0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10,
|
||||
0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
|
||||
0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F,
|
||||
0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
|
||||
0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7,
|
||||
0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
|
||||
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF,
|
||||
0xFA, 0xFD, 0xF4, 0xF3, 0x01 };
|
||||
|
||||
const uint16_t CCITT16_TABLE1[] = {
|
||||
0x0000U, 0x1189U, 0x2312U, 0x329bU, 0x4624U, 0x57adU, 0x6536U, 0x74bfU,
|
||||
0x8c48U, 0x9dc1U, 0xaf5aU, 0xbed3U, 0xca6cU, 0xdbe5U, 0xe97eU, 0xf8f7U,
|
||||
0x1081U, 0x0108U, 0x3393U, 0x221aU, 0x56a5U, 0x472cU, 0x75b7U, 0x643eU,
|
||||
0x9cc9U, 0x8d40U, 0xbfdbU, 0xae52U, 0xdaedU, 0xcb64U, 0xf9ffU, 0xe876U,
|
||||
0x2102U, 0x308bU, 0x0210U, 0x1399U, 0x6726U, 0x76afU, 0x4434U, 0x55bdU,
|
||||
0xad4aU, 0xbcc3U, 0x8e58U, 0x9fd1U, 0xeb6eU, 0xfae7U, 0xc87cU, 0xd9f5U,
|
||||
0x3183U, 0x200aU, 0x1291U, 0x0318U, 0x77a7U, 0x662eU, 0x54b5U, 0x453cU,
|
||||
0xbdcbU, 0xac42U, 0x9ed9U, 0x8f50U, 0xfbefU, 0xea66U, 0xd8fdU, 0xc974U,
|
||||
0x4204U, 0x538dU, 0x6116U, 0x709fU, 0x0420U, 0x15a9U, 0x2732U, 0x36bbU,
|
||||
0xce4cU, 0xdfc5U, 0xed5eU, 0xfcd7U, 0x8868U, 0x99e1U, 0xab7aU, 0xbaf3U,
|
||||
0x5285U, 0x430cU, 0x7197U, 0x601eU, 0x14a1U, 0x0528U, 0x37b3U, 0x263aU,
|
||||
0xdecdU, 0xcf44U, 0xfddfU, 0xec56U, 0x98e9U, 0x8960U, 0xbbfbU, 0xaa72U,
|
||||
0x6306U, 0x728fU, 0x4014U, 0x519dU, 0x2522U, 0x34abU, 0x0630U, 0x17b9U,
|
||||
0xef4eU, 0xfec7U, 0xcc5cU, 0xddd5U, 0xa96aU, 0xb8e3U, 0x8a78U, 0x9bf1U,
|
||||
0x7387U, 0x620eU, 0x5095U, 0x411cU, 0x35a3U, 0x242aU, 0x16b1U, 0x0738U,
|
||||
0xffcfU, 0xee46U, 0xdcddU, 0xcd54U, 0xb9ebU, 0xa862U, 0x9af9U, 0x8b70U,
|
||||
0x8408U, 0x9581U, 0xa71aU, 0xb693U, 0xc22cU, 0xd3a5U, 0xe13eU, 0xf0b7U,
|
||||
0x0840U, 0x19c9U, 0x2b52U, 0x3adbU, 0x4e64U, 0x5fedU, 0x6d76U, 0x7cffU,
|
||||
0x9489U, 0x8500U, 0xb79bU, 0xa612U, 0xd2adU, 0xc324U, 0xf1bfU, 0xe036U,
|
||||
0x18c1U, 0x0948U, 0x3bd3U, 0x2a5aU, 0x5ee5U, 0x4f6cU, 0x7df7U, 0x6c7eU,
|
||||
0xa50aU, 0xb483U, 0x8618U, 0x9791U, 0xe32eU, 0xf2a7U, 0xc03cU, 0xd1b5U,
|
||||
0x2942U, 0x38cbU, 0x0a50U, 0x1bd9U, 0x6f66U, 0x7eefU, 0x4c74U, 0x5dfdU,
|
||||
0xb58bU, 0xa402U, 0x9699U, 0x8710U, 0xf3afU, 0xe226U, 0xd0bdU, 0xc134U,
|
||||
0x39c3U, 0x284aU, 0x1ad1U, 0x0b58U, 0x7fe7U, 0x6e6eU, 0x5cf5U, 0x4d7cU,
|
||||
0xc60cU, 0xd785U, 0xe51eU, 0xf497U, 0x8028U, 0x91a1U, 0xa33aU, 0xb2b3U,
|
||||
0x4a44U, 0x5bcdU, 0x6956U, 0x78dfU, 0x0c60U, 0x1de9U, 0x2f72U, 0x3efbU,
|
||||
0xd68dU, 0xc704U, 0xf59fU, 0xe416U, 0x90a9U, 0x8120U, 0xb3bbU, 0xa232U,
|
||||
0x5ac5U, 0x4b4cU, 0x79d7U, 0x685eU, 0x1ce1U, 0x0d68U, 0x3ff3U, 0x2e7aU,
|
||||
0xe70eU, 0xf687U, 0xc41cU, 0xd595U, 0xa12aU, 0xb0a3U, 0x8238U, 0x93b1U,
|
||||
0x6b46U, 0x7acfU, 0x4854U, 0x59ddU, 0x2d62U, 0x3cebU, 0x0e70U, 0x1ff9U,
|
||||
0xf78fU, 0xe606U, 0xd49dU, 0xc514U, 0xb1abU, 0xa022U, 0x92b9U, 0x8330U,
|
||||
0x7bc7U, 0x6a4eU, 0x58d5U, 0x495cU, 0x3de3U, 0x2c6aU, 0x1ef1U, 0x0f78U };
|
||||
|
||||
const uint16_t CCITT16_TABLE2[] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
|
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
|
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
|
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
|
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
|
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
|
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
|
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
|
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
|
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
|
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
|
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
|
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
|
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
|
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
|
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
|
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
|
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
|
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
|
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
|
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
|
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
|
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 };
|
||||
|
||||
|
||||
bool CCRC::checkFiveBit(bool* in, unsigned int tcrc)
|
||||
{
|
||||
assert(in != NULL);
|
||||
|
||||
unsigned int crc;
|
||||
encodeFiveBit(in, crc);
|
||||
|
||||
return crc == tcrc;
|
||||
}
|
||||
|
||||
void CCRC::encodeFiveBit(const bool* in, unsigned int& tcrc)
|
||||
{
|
||||
assert(in != NULL);
|
||||
|
||||
unsigned short total = 0U;
|
||||
for (unsigned int i = 0U; i < 72U; i += 8U) {
|
||||
unsigned char c;
|
||||
CUtils::bitsToByteBE(in + i, c);
|
||||
total += c;
|
||||
}
|
||||
|
||||
total %= 31U;
|
||||
|
||||
tcrc = total;
|
||||
}
|
||||
|
||||
void CCRC::addCCITT162(unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
uint16_t crc16;
|
||||
uint8_t crc8[2U];
|
||||
};
|
||||
|
||||
crc16 = 0U;
|
||||
|
||||
for (unsigned i = 0U; i < (length - 2U); i++)
|
||||
crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ in[i]];
|
||||
|
||||
crc16 = ~crc16;
|
||||
|
||||
in[length - 1U] = crc8[0U];
|
||||
in[length - 2U] = crc8[1U];
|
||||
}
|
||||
|
||||
bool CCRC::checkCCITT162(const unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
uint16_t crc16;
|
||||
uint8_t crc8[2U];
|
||||
};
|
||||
|
||||
crc16 = 0U;
|
||||
|
||||
for (unsigned i = 0U; i < (length - 2U); i++)
|
||||
crc16 = (uint16_t(crc8[0U]) << 8) ^ CCITT16_TABLE2[crc8[1U] ^ in[i]];
|
||||
|
||||
crc16 = ~crc16;
|
||||
|
||||
return crc8[0U] == in[length - 1U] && crc8[1U] == in[length - 2U];
|
||||
}
|
||||
|
||||
void CCRC::addCCITT161(unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
uint16_t crc16;
|
||||
uint8_t crc8[2U];
|
||||
};
|
||||
|
||||
crc16 = 0xFFFFU;
|
||||
|
||||
for (unsigned int i = 0U; i < (length - 2U); i++)
|
||||
crc16 = uint16_t(crc8[1U]) ^ CCITT16_TABLE1[crc8[0U] ^ in[i]];
|
||||
|
||||
crc16 = ~crc16;
|
||||
|
||||
in[length - 2U] = crc8[0U];
|
||||
in[length - 1U] = crc8[1U];
|
||||
}
|
||||
|
||||
bool CCRC::checkCCITT161(const unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(length > 2U);
|
||||
|
||||
union {
|
||||
uint16_t crc16;
|
||||
uint8_t crc8[2U];
|
||||
};
|
||||
|
||||
crc16 = 0xFFFFU;
|
||||
|
||||
for (unsigned int i = 0U; i < (length - 2U); i++)
|
||||
crc16 = uint16_t(crc8[1U]) ^ CCITT16_TABLE1[crc8[0U] ^ in[i]];
|
||||
|
||||
crc16 = ~crc16;
|
||||
|
||||
return crc8[0U] == in[length - 2U] && crc8[1U] == in[length - 1U];
|
||||
}
|
||||
|
||||
unsigned char CCRC::crc8(const unsigned char *in, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
|
||||
uint8_t crc = 0U;
|
||||
|
||||
for (unsigned int i = 0U; i < length; i++)
|
||||
crc = CRC8_TABLE[crc ^ in[i]];
|
||||
|
||||
return crc;
|
||||
}
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 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(CRC_H)
|
||||
#define CRC_H
|
||||
|
||||
class CCRC
|
||||
{
|
||||
public:
|
||||
static bool checkFiveBit(bool* in, unsigned int tcrc);
|
||||
static void encodeFiveBit(const bool* in, unsigned int& tcrc);
|
||||
|
||||
static void addCCITT161(unsigned char* in, unsigned int length);
|
||||
static void addCCITT162(unsigned char* in, unsigned int length);
|
||||
|
||||
static bool checkCCITT161(const unsigned char* in, unsigned int length);
|
||||
static bool checkCCITT162(const unsigned char* in, unsigned int length);
|
||||
|
||||
static unsigned char crc8(const unsigned char* in, unsigned int length);
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 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 "Console.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#include <conio.h>
|
||||
|
||||
CConsole::CConsole()
|
||||
{
|
||||
}
|
||||
|
||||
CConsole::~CConsole()
|
||||
{
|
||||
}
|
||||
|
||||
bool CConsole::open()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int CConsole::getChar()
|
||||
{
|
||||
if (::_kbhit() == 0)
|
||||
return -1;
|
||||
|
||||
return ::_getch();
|
||||
}
|
||||
|
||||
void CConsole::close()
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
|
||||
CConsole::CConsole() :
|
||||
m_termios()
|
||||
{
|
||||
::memset(&m_termios, 0x00U, sizeof(termios));
|
||||
}
|
||||
|
||||
CConsole::~CConsole()
|
||||
{
|
||||
}
|
||||
|
||||
bool CConsole::open()
|
||||
{
|
||||
termios tios;
|
||||
|
||||
int n = ::tcgetattr(STDIN_FILENO, &tios);
|
||||
if (n != 0) {
|
||||
::fprintf(stderr, "tcgetattr: returned %d\r\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_termios = tios;
|
||||
|
||||
::cfmakeraw(&tios);
|
||||
|
||||
n = ::tcsetattr(STDIN_FILENO, TCSANOW, &tios);
|
||||
if (n != 0) {
|
||||
::fprintf(stderr, "tcsetattr: returned %d\r\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CConsole::getChar()
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
|
||||
timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
int n = ::select(STDIN_FILENO + 1, &fds, NULL, NULL, &tv);
|
||||
if (n <= 0) {
|
||||
if (n < 0)
|
||||
::fprintf(stderr, "select: returned %d\r\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char c;
|
||||
n = ::read(STDIN_FILENO, &c, 1);
|
||||
if (n <= 0) {
|
||||
if (n < 0)
|
||||
::fprintf(stderr, "read: returned %d\r\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void CConsole::close()
|
||||
{
|
||||
int n = ::tcsetattr(STDIN_FILENO, TCSANOW, &m_termios);
|
||||
if (n != 0)
|
||||
::fprintf(stderr, "tcsetattr: returned %d\r\n", n);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 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(CONSOLE_H)
|
||||
#define CONSOLE_H
|
||||
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
class CConsole {
|
||||
public:
|
||||
CConsole();
|
||||
~CConsole();
|
||||
|
||||
bool open();
|
||||
|
||||
int getChar();
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
#if !defined(_WIN32) && !defined(_WIN64)
|
||||
termios m_termios;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+1108
File diff suppressed because it is too large
Load Diff
Executable
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2010,2016 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.
|
||||
*/
|
||||
|
||||
#ifndef Golay24128_H
|
||||
#define Golay24128_H
|
||||
|
||||
class CGolay24128 {
|
||||
public:
|
||||
static unsigned int encode23127(unsigned int data);
|
||||
static unsigned int encode24128(unsigned int data);
|
||||
|
||||
static unsigned int decode23127(unsigned int code);
|
||||
static unsigned int decode24128(unsigned int code);
|
||||
static unsigned int decode24128(unsigned char* bytes);
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+349
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 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 "Hamming.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
// Hamming (15,11,3) check a boolean data array
|
||||
bool CHamming::decode15113_1(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the parity it should have
|
||||
bool c0 = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[6];
|
||||
bool c1 = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[7] ^ d[8] ^ d[9];
|
||||
bool c2 = d[0] ^ d[1] ^ d[4] ^ d[5] ^ d[7] ^ d[8] ^ d[10];
|
||||
bool c3 = d[0] ^ d[2] ^ d[4] ^ d[6] ^ d[7] ^ d[9] ^ d[10];
|
||||
|
||||
unsigned char n = 0U;
|
||||
n |= (c0 != d[11]) ? 0x01U : 0x00U;
|
||||
n |= (c1 != d[12]) ? 0x02U : 0x00U;
|
||||
n |= (c2 != d[13]) ? 0x04U : 0x00U;
|
||||
n |= (c3 != d[14]) ? 0x08U : 0x00U;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
// Parity bit errors
|
||||
case 0x01U: d[11] = !d[11]; return true;
|
||||
case 0x02U: d[12] = !d[12]; return true;
|
||||
case 0x04U: d[13] = !d[13]; return true;
|
||||
case 0x08U: d[14] = !d[14]; return true;
|
||||
|
||||
// Data bit errors
|
||||
case 0x0FU: d[0] = !d[0]; return true;
|
||||
case 0x07U: d[1] = !d[1]; return true;
|
||||
case 0x0BU: d[2] = !d[2]; return true;
|
||||
case 0x03U: d[3] = !d[3]; return true;
|
||||
case 0x0DU: d[4] = !d[4]; return true;
|
||||
case 0x05U: d[5] = !d[5]; return true;
|
||||
case 0x09U: d[6] = !d[6]; return true;
|
||||
case 0x0EU: d[7] = !d[7]; return true;
|
||||
case 0x06U: d[8] = !d[8]; return true;
|
||||
case 0x0AU: d[9] = !d[9]; return true;
|
||||
case 0x0CU: d[10] = !d[10]; return true;
|
||||
|
||||
// No bit errors
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CHamming::encode15113_1(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this row should have
|
||||
d[11] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[6];
|
||||
d[12] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[7] ^ d[8] ^ d[9];
|
||||
d[13] = d[0] ^ d[1] ^ d[4] ^ d[5] ^ d[7] ^ d[8] ^ d[10];
|
||||
d[14] = d[0] ^ d[2] ^ d[4] ^ d[6] ^ d[7] ^ d[9] ^ d[10];
|
||||
}
|
||||
|
||||
// Hamming (15,11,3) check a boolean data array
|
||||
bool CHamming::decode15113_2(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this row should have
|
||||
bool c0 = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8];
|
||||
bool c1 = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[9];
|
||||
bool c2 = d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[7] ^ d[9] ^ d[10];
|
||||
bool c3 = d[0] ^ d[1] ^ d[2] ^ d[4] ^ d[6] ^ d[7] ^ d[10];
|
||||
|
||||
unsigned char n = 0x00U;
|
||||
n |= (c0 != d[11]) ? 0x01U : 0x00U;
|
||||
n |= (c1 != d[12]) ? 0x02U : 0x00U;
|
||||
n |= (c2 != d[13]) ? 0x04U : 0x00U;
|
||||
n |= (c3 != d[14]) ? 0x08U : 0x00U;
|
||||
|
||||
switch (n) {
|
||||
// Parity bit errors
|
||||
case 0x01U: d[11] = !d[11]; return true;
|
||||
case 0x02U: d[12] = !d[12]; return true;
|
||||
case 0x04U: d[13] = !d[13]; return true;
|
||||
case 0x08U: d[14] = !d[14]; return true;
|
||||
|
||||
// Data bit errors
|
||||
case 0x09U: d[0] = !d[0]; return true;
|
||||
case 0x0BU: d[1] = !d[1]; return true;
|
||||
case 0x0FU: d[2] = !d[2]; return true;
|
||||
case 0x07U: d[3] = !d[3]; return true;
|
||||
case 0x0EU: d[4] = !d[4]; return true;
|
||||
case 0x05U: d[5] = !d[5]; return true;
|
||||
case 0x0AU: d[6] = !d[6]; return true;
|
||||
case 0x0DU: d[7] = !d[7]; return true;
|
||||
case 0x03U: d[8] = !d[8]; return true;
|
||||
case 0x06U: d[9] = !d[9]; return true;
|
||||
case 0x0CU: d[10] = !d[10]; return true;
|
||||
|
||||
// No bit errors
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CHamming::encode15113_2(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this row should have
|
||||
d[11] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8];
|
||||
d[12] = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[9];
|
||||
d[13] = d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[7] ^ d[9] ^ d[10];
|
||||
d[14] = d[0] ^ d[1] ^ d[2] ^ d[4] ^ d[6] ^ d[7] ^ d[10];
|
||||
}
|
||||
|
||||
// Hamming (13,9,3) check a boolean data array
|
||||
bool CHamming::decode1393(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this column should have
|
||||
bool c0 = d[0] ^ d[1] ^ d[3] ^ d[5] ^ d[6];
|
||||
bool c1 = d[0] ^ d[1] ^ d[2] ^ d[4] ^ d[6] ^ d[7];
|
||||
bool c2 = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8];
|
||||
bool c3 = d[0] ^ d[2] ^ d[4] ^ d[5] ^ d[8];
|
||||
|
||||
unsigned char n = 0x00U;
|
||||
n |= (c0 != d[9]) ? 0x01U : 0x00U;
|
||||
n |= (c1 != d[10]) ? 0x02U : 0x00U;
|
||||
n |= (c2 != d[11]) ? 0x04U : 0x00U;
|
||||
n |= (c3 != d[12]) ? 0x08U : 0x00U;
|
||||
|
||||
switch (n) {
|
||||
// Parity bit errors
|
||||
case 0x01U: d[9] = !d[9]; return true;
|
||||
case 0x02U: d[10] = !d[10]; return true;
|
||||
case 0x04U: d[11] = !d[11]; return true;
|
||||
case 0x08U: d[12] = !d[12]; return true;
|
||||
|
||||
// Data bit erros
|
||||
case 0x0FU: d[0] = !d[0]; return true;
|
||||
case 0x07U: d[1] = !d[1]; return true;
|
||||
case 0x0EU: d[2] = !d[2]; return true;
|
||||
case 0x05U: d[3] = !d[3]; return true;
|
||||
case 0x0AU: d[4] = !d[4]; return true;
|
||||
case 0x0DU: d[5] = !d[5]; return true;
|
||||
case 0x03U: d[6] = !d[6]; return true;
|
||||
case 0x06U: d[7] = !d[7]; return true;
|
||||
case 0x0CU: d[8] = !d[8]; return true;
|
||||
|
||||
// No bit errors
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CHamming::encode1393(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this column should have
|
||||
d[9] = d[0] ^ d[1] ^ d[3] ^ d[5] ^ d[6];
|
||||
d[10] = d[0] ^ d[1] ^ d[2] ^ d[4] ^ d[6] ^ d[7];
|
||||
d[11] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8];
|
||||
d[12] = d[0] ^ d[2] ^ d[4] ^ d[5] ^ d[8];
|
||||
}
|
||||
|
||||
// Hamming (10,6,3) check a boolean data array
|
||||
bool CHamming::decode1063(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this column should have
|
||||
bool c0 = d[0] ^ d[1] ^ d[2] ^ d[5];
|
||||
bool c1 = d[0] ^ d[1] ^ d[3] ^ d[5];
|
||||
bool c2 = d[0] ^ d[2] ^ d[3] ^ d[4];
|
||||
bool c3 = d[1] ^ d[2] ^ d[3] ^ d[4];
|
||||
|
||||
unsigned char n = 0x00U;
|
||||
n |= (c0 != d[6]) ? 0x01U : 0x00U;
|
||||
n |= (c1 != d[7]) ? 0x02U : 0x00U;
|
||||
n |= (c2 != d[8]) ? 0x04U : 0x00U;
|
||||
n |= (c3 != d[9]) ? 0x08U : 0x00U;
|
||||
|
||||
switch (n) {
|
||||
// Parity bit errors
|
||||
case 0x01U: d[6] = !d[6]; return true;
|
||||
case 0x02U: d[7] = !d[7]; return true;
|
||||
case 0x04U: d[8] = !d[8]; return true;
|
||||
case 0x08U: d[9] = !d[9]; return true;
|
||||
|
||||
// Data bit erros
|
||||
case 0x07U: d[0] = !d[0]; return true;
|
||||
case 0x0BU: d[1] = !d[1]; return true;
|
||||
case 0x0DU: d[2] = !d[2]; return true;
|
||||
case 0x0EU: d[3] = !d[3]; return true;
|
||||
case 0x0CU: d[4] = !d[4]; return true;
|
||||
case 0x03U: d[5] = !d[5]; return true;
|
||||
|
||||
// No bit errors
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CHamming::encode1063(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this column should have
|
||||
d[6] = d[0] ^ d[1] ^ d[2] ^ d[5];
|
||||
d[7] = d[0] ^ d[1] ^ d[3] ^ d[5];
|
||||
d[8] = d[0] ^ d[2] ^ d[3] ^ d[4];
|
||||
d[9] = d[1] ^ d[2] ^ d[3] ^ d[4];
|
||||
}
|
||||
|
||||
// A Hamming (16,11,4) Check
|
||||
bool CHamming::decode16114(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this column should have
|
||||
bool c0 = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8];
|
||||
bool c1 = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[9];
|
||||
bool c2 = d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[7] ^ d[9] ^ d[10];
|
||||
bool c3 = d[0] ^ d[1] ^ d[2] ^ d[4] ^ d[6] ^ d[7] ^ d[10];
|
||||
bool c4 = d[0] ^ d[2] ^ d[5] ^ d[6] ^ d[8] ^ d[9] ^ d[10];
|
||||
|
||||
// Compare these with the actual bits
|
||||
unsigned char n = 0x00U;
|
||||
n |= (c0 != d[11]) ? 0x01U : 0x00U;
|
||||
n |= (c1 != d[12]) ? 0x02U : 0x00U;
|
||||
n |= (c2 != d[13]) ? 0x04U : 0x00U;
|
||||
n |= (c3 != d[14]) ? 0x08U : 0x00U;
|
||||
n |= (c4 != d[15]) ? 0x10U : 0x00U;
|
||||
|
||||
switch (n) {
|
||||
// Parity bit errors
|
||||
case 0x01U: d[11] = !d[11]; return true;
|
||||
case 0x02U: d[12] = !d[12]; return true;
|
||||
case 0x04U: d[13] = !d[13]; return true;
|
||||
case 0x08U: d[14] = !d[14]; return true;
|
||||
case 0x10U: d[15] = !d[15]; return true;
|
||||
|
||||
// Data bit errors
|
||||
case 0x19U: d[0] = !d[0]; return true;
|
||||
case 0x0BU: d[1] = !d[1]; return true;
|
||||
case 0x1FU: d[2] = !d[2]; return true;
|
||||
case 0x07U: d[3] = !d[3]; return true;
|
||||
case 0x0EU: d[4] = !d[4]; return true;
|
||||
case 0x15U: d[5] = !d[5]; return true;
|
||||
case 0x1AU: d[6] = !d[6]; return true;
|
||||
case 0x0DU: d[7] = !d[7]; return true;
|
||||
case 0x13U: d[8] = !d[8]; return true;
|
||||
case 0x16U: d[9] = !d[9]; return true;
|
||||
case 0x1CU: d[10] = !d[10]; return true;
|
||||
|
||||
// No bit errors
|
||||
case 0x00U: return true;
|
||||
|
||||
// Unrecoverable errors
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CHamming::encode16114(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
d[11] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[5] ^ d[7] ^ d[8];
|
||||
d[12] = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[6] ^ d[8] ^ d[9];
|
||||
d[13] = d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[7] ^ d[9] ^ d[10];
|
||||
d[14] = d[0] ^ d[1] ^ d[2] ^ d[4] ^ d[6] ^ d[7] ^ d[10];
|
||||
d[15] = d[0] ^ d[2] ^ d[5] ^ d[6] ^ d[8] ^ d[9] ^ d[10];
|
||||
}
|
||||
|
||||
// A Hamming (17,12,3) Check
|
||||
bool CHamming::decode17123(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
// Calculate the checksum this column should have
|
||||
bool c0 = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[6] ^ d[7] ^ d[9];
|
||||
bool c1 = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[7] ^ d[8] ^ d[10];
|
||||
bool c2 = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[8] ^ d[9] ^ d[11];
|
||||
bool c3 = d[0] ^ d[1] ^ d[4] ^ d[5] ^ d[7] ^ d[10];
|
||||
bool c4 = d[0] ^ d[1] ^ d[2] ^ d[5] ^ d[6] ^ d[8] ^ d[11];
|
||||
|
||||
// Compare these with the actual bits
|
||||
unsigned char n = 0x00U;
|
||||
n |= (c0 != d[12]) ? 0x01U : 0x00U;
|
||||
n |= (c1 != d[13]) ? 0x02U : 0x00U;
|
||||
n |= (c2 != d[14]) ? 0x04U : 0x00U;
|
||||
n |= (c3 != d[15]) ? 0x08U : 0x00U;
|
||||
n |= (c4 != d[16]) ? 0x10U : 0x00U;
|
||||
|
||||
switch (n) {
|
||||
// Parity bit errors
|
||||
case 0x01U: d[12] = !d[12]; return true;
|
||||
case 0x02U: d[13] = !d[13]; return true;
|
||||
case 0x04U: d[14] = !d[14]; return true;
|
||||
case 0x08U: d[15] = !d[15]; return true;
|
||||
case 0x10U: d[16] = !d[16]; return true;
|
||||
|
||||
// Data bit errors
|
||||
case 0x1BU: d[0] = !d[0]; return true;
|
||||
case 0x1FU: d[1] = !d[1]; return true;
|
||||
case 0x17U: d[2] = !d[2]; return true;
|
||||
case 0x07U: d[3] = !d[3]; return true;
|
||||
case 0x0EU: d[4] = !d[4]; return true;
|
||||
case 0x1CU: d[5] = !d[5]; return true;
|
||||
case 0x11U: d[6] = !d[6]; return true;
|
||||
case 0x0BU: d[7] = !d[7]; return true;
|
||||
case 0x16U: d[8] = !d[8]; return true;
|
||||
case 0x05U: d[9] = !d[9]; return true;
|
||||
case 0x0AU: d[10] = !d[10]; return true;
|
||||
case 0x14U: d[11] = !d[11]; return true;
|
||||
|
||||
// No bit errors
|
||||
case 0x00U: return true;
|
||||
|
||||
// Unrecoverable errors
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CHamming::encode17123(bool* d)
|
||||
{
|
||||
assert(d != NULL);
|
||||
|
||||
d[12] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[6] ^ d[7] ^ d[9];
|
||||
d[13] = d[0] ^ d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[7] ^ d[8] ^ d[10];
|
||||
d[14] = d[1] ^ d[2] ^ d[3] ^ d[4] ^ d[5] ^ d[8] ^ d[9] ^ d[11];
|
||||
d[15] = d[0] ^ d[1] ^ d[4] ^ d[5] ^ d[7] ^ d[10];
|
||||
d[16] = d[0] ^ d[1] ^ d[2] ^ d[5] ^ d[6] ^ d[8] ^ d[11];
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 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.
|
||||
*/
|
||||
|
||||
#ifndef Hamming_H
|
||||
#define Hamming_H
|
||||
|
||||
class CHamming {
|
||||
public:
|
||||
static void encode15113_1(bool* d);
|
||||
static bool decode15113_1(bool* d);
|
||||
|
||||
static void encode15113_2(bool* d);
|
||||
static bool decode15113_2(bool* d);
|
||||
|
||||
static void encode1393(bool* d);
|
||||
static bool decode1393(bool* d);
|
||||
|
||||
static void encode1063(bool* d);
|
||||
static bool decode1063(bool* d);
|
||||
|
||||
static void encode16114(bool* d);
|
||||
static bool decode16114(bool* d);
|
||||
|
||||
static void encode17123(bool* d);
|
||||
static bool decode17123(bool* d);
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+340
@@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
Executable
+1472
File diff suppressed because it is too large
Load Diff
Executable
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2017,2018 by Andy Uribe CA6JAU
|
||||
* Copyright (C) 2018 by Bryan Biedenkapp N2PLL
|
||||
*
|
||||
* 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(MMDVMCAL_H)
|
||||
#define MMDVMCAL_H
|
||||
|
||||
#include "SerialController.h"
|
||||
#include "Console.h"
|
||||
#include "BERCal.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
enum RESP_TYPE_MMDVM {
|
||||
RTM_OK,
|
||||
RTM_TIMEOUT,
|
||||
RTM_ERROR
|
||||
};
|
||||
|
||||
enum HW_TYPE {
|
||||
HWT_MMDVM,
|
||||
HWT_MMDVM_HS
|
||||
};
|
||||
|
||||
enum MMDVM_STATE {
|
||||
STATE_IDLE = 0,
|
||||
STATE_DSTAR = 1,
|
||||
STATE_DMR = 2,
|
||||
STATE_YSF = 3,
|
||||
STATE_P25 = 4,
|
||||
STATE_NXDN = 5,
|
||||
STATE_POCSAG = 6,
|
||||
STATE_NXDNCAL1K = 91,
|
||||
STATE_DMRDMO1K = 92,
|
||||
STATE_P25CAL1K = 93,
|
||||
STATE_DMRCAL1K = 94,
|
||||
STATE_LFCAL = 95,
|
||||
STATE_RSSICAL = 96,
|
||||
STATE_DMRCAL = 98,
|
||||
STATE_DSTARCAL = 99,
|
||||
STATE_INTCAL = 100,
|
||||
STATE_POCSAGCAL = 101,
|
||||
STATE_FMCAL10K = 102,
|
||||
STATE_FMCAL12K = 103,
|
||||
STATE_FMCAL15K = 104,
|
||||
STATE_FMCAL20K = 105,
|
||||
STATE_FMCAL25K = 106,
|
||||
STATE_FMCAL30K = 107
|
||||
};
|
||||
|
||||
class CMMDVMCal {
|
||||
public:
|
||||
CMMDVMCal(const std::string& port);
|
||||
~CMMDVMCal();
|
||||
|
||||
int run();
|
||||
|
||||
private:
|
||||
CSerialController m_serial;
|
||||
CConsole m_console;
|
||||
CBERCal m_ber;
|
||||
bool m_transmit;
|
||||
bool m_carrier;
|
||||
float m_txLevel;
|
||||
float m_rxLevel;
|
||||
int m_txDCOffset;
|
||||
int m_rxDCOffset;
|
||||
bool m_txInvert;
|
||||
bool m_rxInvert;
|
||||
bool m_pttInvert;
|
||||
unsigned int m_frequency;
|
||||
unsigned int m_startfrequency;
|
||||
unsigned int m_step;
|
||||
float m_power;
|
||||
MMDVM_STATE m_mode;
|
||||
bool m_duplex;
|
||||
bool m_debug;
|
||||
unsigned char* m_buffer;
|
||||
unsigned int m_length;
|
||||
unsigned int m_offset;
|
||||
HW_TYPE m_hwType;
|
||||
bool m_dstarEnabled;
|
||||
bool m_dmrEnabled;
|
||||
bool m_dmrBERFEC;
|
||||
bool m_ysfEnabled;
|
||||
bool m_p25Enabled;
|
||||
bool m_nxdnEnabled;
|
||||
bool m_pocsagEnabled;
|
||||
bool m_fmEnabled;
|
||||
|
||||
void displayHelp_MMDVM();
|
||||
void displayHelp_MMDVM_HS();
|
||||
void loop_MMDVM();
|
||||
void loop_MMDVM_HS();
|
||||
bool setTransmit();
|
||||
bool setTXLevel(int incr);
|
||||
bool setRXLevel(int incr);
|
||||
bool setTXDCOffset(int incr);
|
||||
bool setRXDCOffset(int incr);
|
||||
bool setTXInvert();
|
||||
bool setRXInvert();
|
||||
bool setPTTInvert();
|
||||
bool setDebug();
|
||||
bool setFreq(int incr);
|
||||
bool setStepFreq();
|
||||
bool setPower(int incr);
|
||||
bool setCarrier();
|
||||
bool setEnterFreq();
|
||||
bool setFMDeviation();
|
||||
bool setDMRDeviation();
|
||||
bool setLowFrequencyCal();
|
||||
bool setDMRCal1K();
|
||||
bool setDMRDMO1K();
|
||||
bool setP25Cal1K();
|
||||
bool setNXDNCal1K();
|
||||
bool setPOCSAGCal();
|
||||
bool setDSTARBER_FEC();
|
||||
bool setDMRBER_FEC();
|
||||
bool setDMRBER_1K();
|
||||
bool setYSFBER_FEC();
|
||||
bool setP25BER_FEC();
|
||||
bool setNXDNBER_FEC();
|
||||
bool setDSTAR();
|
||||
bool setRSSI();
|
||||
bool setIntCal();
|
||||
|
||||
bool initModem();
|
||||
void displayModem(const unsigned char* buffer, unsigned int length);
|
||||
bool writeConfig(float txlevel, bool debug);
|
||||
void sleep(unsigned int ms);
|
||||
bool setFrequency();
|
||||
bool getStatus();
|
||||
|
||||
RESP_TYPE_MMDVM getResponse();
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.24720.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MMDVMCal", "MMDVMCal.vcxproj", "{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Debug|x64.Build.0 = Debug|x64
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Release|x64.ActiveCfg = Release|x64
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Release|x64.Build.0 = Release|x64
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Executable
+180
@@ -0,0 +1,180 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{85986F1C-C8FC-4A79-B7F7-02859B4A0DA8}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>MMDVMCal</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BERCal.h" />
|
||||
<ClInclude Include="Console.h" />
|
||||
<ClInclude Include="CRC.h" />
|
||||
<ClInclude Include="Golay24128.h" />
|
||||
<ClInclude Include="Hamming.h" />
|
||||
<ClInclude Include="MMDVMCal.h" />
|
||||
<ClInclude Include="NXDNDefines.h" />
|
||||
<ClInclude Include="NXDNLICH.h" />
|
||||
<ClInclude Include="P25Utils.h" />
|
||||
<ClInclude Include="SerialController.h" />
|
||||
<ClInclude Include="SerialPort.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
<ClInclude Include="Version.h" />
|
||||
<ClInclude Include="YSFConvolution.h" />
|
||||
<ClInclude Include="YSFDefines.h" />
|
||||
<ClInclude Include="YSFFICH.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BERCal.cpp" />
|
||||
<ClCompile Include="Console.cpp" />
|
||||
<ClCompile Include="CRC.cpp" />
|
||||
<ClCompile Include="Golay24128.cpp" />
|
||||
<ClCompile Include="Hamming.cpp" />
|
||||
<ClCompile Include="MMDVMCal.cpp" />
|
||||
<ClCompile Include="NXDNLICH.cpp" />
|
||||
<ClCompile Include="P25Utils.cpp" />
|
||||
<ClCompile Include="SerialController.cpp" />
|
||||
<ClCompile Include="SerialPort.cpp" />
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
<ClCompile Include="YSFConvolution.cpp" />
|
||||
<ClCompile Include="YSFFICH.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="BERCal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Console.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CRC.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Golay24128.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MMDVMCal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NXDNLICH.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="NXDNDefines.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SerialController.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="SerialPort.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Hamming.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="P25Utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="YSFConvolution.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="YSFDefines.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="YSFFICH.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BERCal.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Console.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CRC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Golay24128.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MMDVMCal.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="NXDNLICH.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SerialController.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SerialPort.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Hamming.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="P25Utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="YSFConvolution.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="YSFFICH.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Executable
+51
@@ -0,0 +1,51 @@
|
||||
all: MMDVMCal
|
||||
|
||||
LD = c++
|
||||
CXX = c++
|
||||
|
||||
CXXFLAGS = -O2 -Wall -std=c++0x
|
||||
|
||||
MMDVMCal: BERCal.o CRC.o Hamming.o Golay24128.o P25Utils.o MMDVMCal.o NXDNLICH.o SerialController.o SerialPort.o Console.o Utils.o YSFConvolution.o YSFFICH.o
|
||||
$(LD) $(LDFLAGS) -o MMDVMCal BERCal.o CRC.o Hamming.o Golay24128.o P25Utils.o MMDVMCal.o NXDNLICH.o SerialController.o SerialPort.o Console.o Utils.o YSFConvolution.o YSFFICH.o $(LIBS)
|
||||
|
||||
BERCal.o: BERCal.cpp BERCal.h Golay24128.h Utils.h
|
||||
$(CXX) $(CXXFLAGS) -c BERCal.cpp
|
||||
|
||||
CRC.o: CRC.cpp CRC.h
|
||||
$(CXX) $(CXXFLAGS) -c CRC.cpp
|
||||
|
||||
Hamming.o: Hamming.cpp Hamming.h
|
||||
$(CXX) $(CXXFLAGS) -c Hamming.cpp
|
||||
|
||||
Golay24128.o: Golay24128.cpp Golay24128.h
|
||||
$(CXX) $(CXXFLAGS) -c Golay24128.cpp
|
||||
|
||||
P25Utils.o: P25Utils.cpp P25Utils.h
|
||||
$(CXX) $(CXXFLAGS) -c P25Utils.cpp
|
||||
|
||||
MMDVMCal.o: MMDVMCal.cpp MMDVMCal.h SerialController.h Console.h Utils.h
|
||||
$(CXX) $(CXXFLAGS) -c MMDVMCal.cpp
|
||||
|
||||
NXDNLICH.o: NXDNLICH.cpp NXDNLICH.h NXDNDefines.h
|
||||
$(CXX) $(CXXFLAGS) -c NXDNLICH.cpp
|
||||
|
||||
SerialController.o: SerialController.cpp SerialController.h
|
||||
$(CXX) $(CXXFLAGS) -c SerialController.cpp
|
||||
|
||||
SerialPort.o: SerialPort.cpp SerialPort.h
|
||||
$(CXX) $(CXXFLAGS) -c SerialPort.cpp
|
||||
|
||||
Console.o: Console.cpp Console.h
|
||||
$(CXX) $(CXXFLAGS) -c Console.cpp
|
||||
|
||||
Utils.o: Utils.cpp Utils.h
|
||||
$(CXX) $(CXXFLAGS) -c Utils.cpp
|
||||
|
||||
YSFConvolution.o: YSFConvolution.cpp YSFConvolution.h
|
||||
$(CXX) $(CXXFLAGS) -c YSFConvolution.cpp
|
||||
|
||||
YSFFICH: YSFFICH.cpp CRC.h Golay24128.h YSFConvolution.h YSFDefines.h YSFFICH.h
|
||||
$(CXX) $(CXXFLAGS) -c YSFFICH.cpp
|
||||
|
||||
clean:
|
||||
rm -f *.o *.bak *~ MMDVMCal
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 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(NXDNDEFINES_H)
|
||||
#define NXDNDEFINES_H
|
||||
|
||||
const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
||||
|
||||
const unsigned int NXDN_FRAME_LENGTH_BITS = 384U;
|
||||
const unsigned int NXDN_FRAME_LENGTH_BYTES = NXDN_FRAME_LENGTH_BITS / 8U;
|
||||
const unsigned int NXDN_FRAME_LENGTH_SYMBOLS = NXDN_FRAME_LENGTH_BITS / 2U;
|
||||
|
||||
const unsigned int NXDN_FSW_LENGTH_BITS = 20U;
|
||||
const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U;
|
||||
const unsigned int NXDN_FSW_LENGTH_SAMPLES = NXDN_FSW_LENGTH_SYMBOLS * NXDN_RADIO_SYMBOL_LENGTH;
|
||||
|
||||
const unsigned char NXDN_FSW_BYTES[] = {0xCDU, 0xF5U, 0x90U};
|
||||
const unsigned char NXDN_FSW_BYTES_MASK[] = {0xFFU, 0xFFU, 0xF0U};
|
||||
const unsigned int NXDN_FSW_BYTES_LENGTH = 3U;
|
||||
|
||||
const unsigned int NXDN_LICH_LENGTH_BITS = 16U;
|
||||
|
||||
const unsigned int NXDN_SACCH_LENGTH_BITS = 60U;
|
||||
const unsigned int NXDN_FACCH1_LENGTH_BITS = 144U;
|
||||
const unsigned int NXDN_FACCH2_LENGTH_BITS = 348U;
|
||||
|
||||
const unsigned int NXDN_FSW_LICH_SACCH_LENGTH_BITS = NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS;
|
||||
const unsigned int NXDN_FSW_LICH_SACCH_LENGTH_BYTES = NXDN_FSW_LICH_SACCH_LENGTH_BITS / 8U;
|
||||
|
||||
const unsigned char NXDN_LICH_RFCT_RCCH = 0U;
|
||||
const unsigned char NXDN_LICH_RFCT_RTCH = 1U;
|
||||
const unsigned char NXDN_LICH_RFCT_RDCH = 2U;
|
||||
const unsigned char NXDN_LICH_RFCT_RTCH_C = 3U;
|
||||
|
||||
const unsigned char NXDN_LICH_USC_SACCH_NS = 0U;
|
||||
const unsigned char NXDN_LICH_USC_UDCH = 1U;
|
||||
const unsigned char NXDN_LICH_USC_SACCH_SS = 2U;
|
||||
const unsigned char NXDN_LICH_USC_SACCH_SS_IDLE = 3U;
|
||||
|
||||
const unsigned char NXDN_LICH_STEAL_NONE = 3U;
|
||||
const unsigned char NXDN_LICH_STEAL_FACCH1_2 = 2U;
|
||||
const unsigned char NXDN_LICH_STEAL_FACCH1_1 = 1U;
|
||||
const unsigned char NXDN_LICH_STEAL_FACCH = 0U;
|
||||
|
||||
const unsigned char NXDN_LICH_DIRECTION_INBOUND = 0U;
|
||||
const unsigned char NXDN_LICH_DIRECTION_OUTBOUND = 1U;
|
||||
|
||||
const unsigned char NXDN_SR_SINGLE = 0U;
|
||||
const unsigned char NXDN_SR_4_4 = 0U;
|
||||
const unsigned char NXDN_SR_3_4 = 1U;
|
||||
const unsigned char NXDN_SR_2_4 = 2U;
|
||||
const unsigned char NXDN_SR_1_4 = 3U;
|
||||
|
||||
const unsigned char NXDN_MESSAGE_TYPE_VCALL = 0x01U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_VCALL_IV = 0x03U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_DCALL_HDR = 0x09U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_DCALL_DATA = 0x0BU;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_DCALL_ACK = 0x0CU;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_TX_REL = 0x08U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_HEAD_DLY = 0x0FU;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_REQ_HDR = 0x38U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_REQ_DATA = 0x39U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_RESP = 0x3BU;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_SDCALL_IV = 0x3AU;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_INQ_REQ = 0x30U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_INQ_RESP = 0x31U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_REQ = 0x32U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_STAT_RESP = 0x33U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_REM_CON_REQ = 0x34U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_REM_CON_RESP = 0x35U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_IDLE = 0x10U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_AUTH_INQ_REQ = 0x28U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_AUTH_INQ_RESP = 0x29U;
|
||||
const unsigned char NXDN_MESSAGE_TYPE_PROP_FORM = 0x3FU;
|
||||
|
||||
const unsigned char NXDN_VOICE_CALL_OPTION_HALF_DUPLEX = 0x00U;
|
||||
const unsigned char NXDN_VOICE_CALL_OPTION_DUPLEX = 0x10U;
|
||||
|
||||
const unsigned char NXDN_DATA_CALL_OPTION_HALF_DUPLEX = 0x00U;
|
||||
const unsigned char NXDN_DATA_CALL_OPTION_DUPLEX = 0x10U;
|
||||
|
||||
const unsigned char NXDN_DATA_CALL_OPTION_4800 = 0x00U;
|
||||
const unsigned char NXDN_DATA_CALL_OPTION_9600 = 0x02U;
|
||||
|
||||
const unsigned char SACCH_IDLE[] = { NXDN_MESSAGE_TYPE_IDLE, 0x00U, 0x00U };
|
||||
|
||||
#endif
|
||||
Executable
+162
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 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 "NXDNDefines.h"
|
||||
#include "NXDNLICH.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
#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])
|
||||
|
||||
CNXDNLICH::CNXDNLICH(const CNXDNLICH& lich) :
|
||||
m_lich(NULL)
|
||||
{
|
||||
m_lich = new unsigned char[1U];
|
||||
m_lich[0U] = lich.m_lich[0U];
|
||||
}
|
||||
|
||||
CNXDNLICH::CNXDNLICH() :
|
||||
m_lich(NULL)
|
||||
{
|
||||
m_lich = new unsigned char[1U];
|
||||
}
|
||||
|
||||
CNXDNLICH::~CNXDNLICH()
|
||||
{
|
||||
delete[] m_lich;
|
||||
}
|
||||
|
||||
bool CNXDNLICH::decode(const unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
|
||||
unsigned int offset = NXDN_FSW_LENGTH_BITS;
|
||||
for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++, offset += 2U) {
|
||||
bool b = READ_BIT1(bytes, offset);
|
||||
WRITE_BIT1(m_lich, i, b);
|
||||
}
|
||||
|
||||
bool newParity = getParity();
|
||||
bool origParity = (m_lich[0U] & 0x01U) == 0x01U;
|
||||
|
||||
return origParity == newParity;
|
||||
}
|
||||
|
||||
void CNXDNLICH::encode(unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
|
||||
bool parity = getParity();
|
||||
if (parity)
|
||||
m_lich[0U] |= 0x01U;
|
||||
else
|
||||
m_lich[0U] &= 0xFEU;
|
||||
|
||||
unsigned int offset = NXDN_FSW_LENGTH_BITS;
|
||||
for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++) {
|
||||
bool b = READ_BIT1(m_lich, i);
|
||||
WRITE_BIT1(bytes, offset, b);
|
||||
offset++;
|
||||
WRITE_BIT1(bytes, offset, true);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char CNXDNLICH::getRFCT() const
|
||||
{
|
||||
return (m_lich[0U] >> 6) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CNXDNLICH::getFCT() const
|
||||
{
|
||||
return (m_lich[0U] >> 4) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CNXDNLICH::getOption() const
|
||||
{
|
||||
return (m_lich[0U] >> 2) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CNXDNLICH::getDirection() const
|
||||
{
|
||||
return (m_lich[0U] >> 1) & 0x01U;
|
||||
}
|
||||
|
||||
unsigned char CNXDNLICH::getRaw() const
|
||||
{
|
||||
bool parity = getParity();
|
||||
if (parity)
|
||||
m_lich[0U] |= 0x01U;
|
||||
else
|
||||
m_lich[0U] &= 0xFEU;
|
||||
|
||||
return m_lich[0U];
|
||||
}
|
||||
|
||||
void CNXDNLICH::setRFCT(unsigned char rfct)
|
||||
{
|
||||
m_lich[0U] &= 0x3FU;
|
||||
m_lich[0U] |= (rfct << 6) & 0xC0U;
|
||||
}
|
||||
|
||||
void CNXDNLICH::setFCT(unsigned char usc)
|
||||
{
|
||||
m_lich[0U] &= 0xCFU;
|
||||
m_lich[0U] |= (usc << 4) & 0x30U;
|
||||
}
|
||||
|
||||
void CNXDNLICH::setOption(unsigned char option)
|
||||
{
|
||||
m_lich[0U] &= 0xF3U;
|
||||
m_lich[0U] |= (option << 2) & 0x0CU;
|
||||
}
|
||||
|
||||
void CNXDNLICH::setDirection(unsigned char direction)
|
||||
{
|
||||
m_lich[0U] &= 0xFDU;
|
||||
m_lich[0U] |= (direction << 1) & 0x02U;
|
||||
}
|
||||
|
||||
void CNXDNLICH::setRaw(unsigned char lich)
|
||||
{
|
||||
m_lich[0U] = lich;
|
||||
}
|
||||
|
||||
CNXDNLICH& CNXDNLICH::operator=(const CNXDNLICH& lich)
|
||||
{
|
||||
if (&lich != this)
|
||||
m_lich[0U] = lich.m_lich[0U];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CNXDNLICH::getParity() const
|
||||
{
|
||||
switch (m_lich[0U] & 0xF0U) {
|
||||
case 0x80U:
|
||||
case 0xB0U:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 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(NXDNLICH_H)
|
||||
#define NXDNLICH_H
|
||||
|
||||
class CNXDNLICH {
|
||||
public:
|
||||
CNXDNLICH(const CNXDNLICH& lich);
|
||||
CNXDNLICH();
|
||||
~CNXDNLICH();
|
||||
|
||||
bool decode(const unsigned char* bytes);
|
||||
|
||||
void encode(unsigned char* bytes);
|
||||
|
||||
unsigned char getRFCT() const;
|
||||
unsigned char getFCT() const;
|
||||
unsigned char getOption() const;
|
||||
unsigned char getDirection() const;
|
||||
unsigned char getRaw() const;
|
||||
|
||||
void setRFCT(unsigned char rfct);
|
||||
void setFCT(unsigned char usc);
|
||||
void setOption(unsigned char option);
|
||||
void setDirection(unsigned char direction);
|
||||
void setRaw(unsigned char lich);
|
||||
|
||||
CNXDNLICH& operator=(const CNXDNLICH& lich);
|
||||
|
||||
private:
|
||||
unsigned char* m_lich;
|
||||
|
||||
bool getParity() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2016,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 "P25Utils.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
||||
|
||||
#define WRITE_BIT(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_BIT(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||
|
||||
const unsigned int P25_SS0_START = 70U;
|
||||
const unsigned int P25_SS1_START = 71U;
|
||||
const unsigned int P25_SS_INCREMENT = 72U;
|
||||
|
||||
unsigned int CP25Utils::decode(const unsigned char* in, unsigned char* out, unsigned int start, unsigned int stop)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(out != NULL);
|
||||
|
||||
// Move the SSx positions to the range needed
|
||||
unsigned int ss0Pos = P25_SS0_START;
|
||||
unsigned int ss1Pos = P25_SS1_START;
|
||||
|
||||
while (ss0Pos < start) {
|
||||
ss0Pos += P25_SS_INCREMENT;
|
||||
ss1Pos += P25_SS_INCREMENT;
|
||||
}
|
||||
|
||||
unsigned int n = 0U;
|
||||
for (unsigned int i = start; i < stop; i++) {
|
||||
if (i == ss0Pos) {
|
||||
ss0Pos += P25_SS_INCREMENT;
|
||||
} else if (i == ss1Pos) {
|
||||
ss1Pos += P25_SS_INCREMENT;
|
||||
} else {
|
||||
bool b = READ_BIT(in, i);
|
||||
WRITE_BIT(out, n, b);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
unsigned int CP25Utils::encode(const unsigned char* in, unsigned char* out, unsigned int start, unsigned int stop)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(out != NULL);
|
||||
|
||||
// Move the SSx positions to the range needed
|
||||
unsigned int ss0Pos = P25_SS0_START;
|
||||
unsigned int ss1Pos = P25_SS1_START;
|
||||
|
||||
while (ss0Pos < start) {
|
||||
ss0Pos += P25_SS_INCREMENT;
|
||||
ss1Pos += P25_SS_INCREMENT;
|
||||
}
|
||||
|
||||
unsigned int n = 0U;
|
||||
for (unsigned int i = start; i < stop; i++) {
|
||||
if (i == ss0Pos) {
|
||||
ss0Pos += P25_SS_INCREMENT;
|
||||
} else if (i == ss1Pos) {
|
||||
ss1Pos += P25_SS_INCREMENT;
|
||||
} else {
|
||||
bool b = READ_BIT(in, n);
|
||||
WRITE_BIT(out, i, b);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
unsigned int CP25Utils::encode(const unsigned char* in, unsigned char* out, unsigned int length)
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(out != NULL);
|
||||
|
||||
// Move the SSx positions to the range needed
|
||||
unsigned int ss0Pos = P25_SS0_START;
|
||||
unsigned int ss1Pos = P25_SS1_START;
|
||||
|
||||
unsigned int n = 0U;
|
||||
unsigned int pos = 0U;
|
||||
while (n < length) {
|
||||
if (pos == ss0Pos) {
|
||||
ss0Pos += P25_SS_INCREMENT;
|
||||
} else if (pos == ss1Pos) {
|
||||
ss1Pos += P25_SS_INCREMENT;
|
||||
} else {
|
||||
bool b = READ_BIT(in, n);
|
||||
WRITE_BIT(out, pos, b);
|
||||
n++;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
unsigned int CP25Utils::compare(const unsigned char* data1, const unsigned char* data2, unsigned int length)
|
||||
{
|
||||
assert(data1 != NULL);
|
||||
assert(data2 != NULL);
|
||||
|
||||
unsigned int errs = 0U;
|
||||
for (unsigned int i = 0U; i < length; i++) {
|
||||
unsigned char v = data1[i] ^ data2[i];
|
||||
while (v != 0U) {
|
||||
v &= v - 1U;
|
||||
errs++;
|
||||
}
|
||||
}
|
||||
|
||||
return errs;
|
||||
}
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2016,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(P25Utils_H)
|
||||
#define P25Utils_H
|
||||
|
||||
class CP25Utils {
|
||||
public:
|
||||
static unsigned int encode(const unsigned char* in, unsigned char* out, unsigned int start, unsigned int stop);
|
||||
static unsigned int encode(const unsigned char* in, unsigned char* out, unsigned int length);
|
||||
|
||||
static unsigned int decode(const unsigned char* in, unsigned char* out, unsigned int start, unsigned int stop);
|
||||
|
||||
static unsigned int compare(const unsigned char* data1, const unsigned char* data2, unsigned int length);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
This is the calibration program to be used with the MMDVM and MMDVM_HS. It is started by
|
||||
adding the serial port onto the command line. On Windows the serial port must be
|
||||
prefixed with \\.\ as in \\.\COM4 to be valid. Once started the program takes
|
||||
the following commands:
|
||||
|
||||
- MMDVM:
|
||||
|
||||
<table>
|
||||
<tr><th>Command</th><th>Description</th></tr>
|
||||
<tr><td>H/h</td><td>Display help</td></tr>
|
||||
<tr><td>Q/q</td><td>Quit</td></tr>
|
||||
<tr><td>W/w</td><td>Enable/disable modem debug messages</td></tr>
|
||||
<tr><td>I</td><td>Toggle transmit inversion</td><tr>
|
||||
<tr><td>i</td><td>Toggle receive inversion</td></tr>
|
||||
<tr><td>O</td><td>Increase TX DC offset level</td></tr>
|
||||
<tr><td>o</td><td>Decrease TX DC offset level</td></tr>
|
||||
<tr><td>C</td><td>Increase RX DC offset level</td></tr>
|
||||
<tr><td>c</td><td>Decrease RX DC offset level</td></tr>
|
||||
<tr><td>P/p</td><td>Toggle PTT inversion</td></tr>
|
||||
<tr><td>R</td><td>Increase receive level</td></tr>
|
||||
<tr><td>r</td><td>Decrease receive level</td></tr>
|
||||
<tr><td>T</td><td>Increase transmit level</td></tr>
|
||||
<tr><td>t</td><td>Decrease transmit level</td></tr>
|
||||
<tr><td>d</td><td>D-Star mode</td></tr>
|
||||
<tr><td>D</td><td>Set DMR Deviation Mode. Generates a 1.2Khz Sinewave. Set radio for 2.75 Khz Deviation</td></tr>
|
||||
<tr><td>L/l</td><td>DMR Low Frequency Mode (80 Hz square wave)</td></tr>
|
||||
<tr><td>A</td><td>DMR Duplex 1031 Hz Test Pattern (TS2 CC1 ID1 TG9)</td></tr>
|
||||
<tr><td>M/m</td><td>DMR Simplex 1031 Hz Test Pattern (CC1 ID1 TG9)</td></tr>
|
||||
<tr><td>a</td><td>P25 1011 Hz Test Pattern (NAC293 ID1 TG1)</td></tr>
|
||||
<tr><td>N</td><td>NXDN 1031 Hz Test Pattern (RAN1 ID1 TG1)</td></tr>
|
||||
<tr><td>K/k</td><td>BER Test Mode (FEC) for D-Star</td></tr>
|
||||
<tr><td>b</td><td>BER Test Mode (FEC) for DMR Simplex (CC1)</td></tr>
|
||||
<tr><td>B</td><td>BER Test Mode (1031 Hz Test Pattern) for DMR Simplex (CC1 ID1 TG9)</td></tr>
|
||||
<tr><td>J</td><td>BER Test Mode (FEC) for YSF</td></tr>
|
||||
<tr><td>j</td><td>BER Test Mode (FEC) for P25</td></tr>
|
||||
<tr><td>n</td><td>BER Test Mode (FEC) for NXDN</td></tr>
|
||||
<tr><td>g</td><td>POCSAG 600Hz Test Pattern</td></tr>
|
||||
<tr><td>S/s</td><td>RSSI Mode</td></tr>
|
||||
<tr><td>V/v</td><td>Display version of MMDVMCal</td></tr>
|
||||
<tr><td><space></td><td>Toggle transmit</td></tr>
|
||||
</table>
|
||||
|
||||
- MMDVM_HS:
|
||||
|
||||
<table>
|
||||
<tr><th>Command</th><th>Description</th></tr>
|
||||
<tr><td>H/h</td><td>Display help</td></tr>
|
||||
<tr><td>Q/q</td><td>Quit</td></tr>
|
||||
<tr><td>W/w</td><td>Enable/disable modem debug messages</td></tr>
|
||||
<tr><td>E/e</td><td>Enter frequency</td><tr>
|
||||
<tr><td>F</td><td>Increase frequency</td></tr>
|
||||
<tr><td>f</td><td>Decrease frequency</td></tr>
|
||||
<tr><td>Z/z</td><td>Enter frequency step</td></tr>
|
||||
<tr><td>T</td><td>Increase deviation</td></tr>
|
||||
<tr><td>t</td><td>Decrease deviation</td></tr>
|
||||
<tr><td>P</td><td>Increase RF power</td></tr>
|
||||
<tr><td>p</td><td>Decrease RF power</td></tr>
|
||||
<tr><td>C/c</td><td>Carrier Only Mode</td></tr>
|
||||
<tr><td>D/d</td><td>DMR Deviation Mode</td></tr>
|
||||
<tr><td>M/m</td><td>DMR Simplex 1031 Hz Test Pattern (CC1 ID1 TG9)</td></tr>
|
||||
<tr><td>K/k</td><td>BER Test Mode (FEC) for D-Star</td></tr>
|
||||
<tr><td>b</td><td>BER Test Mode (FEC) for DMR Simplex (CC1)</td></tr>
|
||||
<tr><td>B</td><td>BER Test Mode (1031 Hz Test Pattern) for DMR Simplex (CC1 ID1 TG9)</td></tr>
|
||||
<tr><td>J</td><td>BER Test Mode (FEC) for YSF</td></tr>
|
||||
<tr><td>j</td><td>BER Test Mode (FEC) for P25</td></tr>
|
||||
<tr><td>n</td><td>BER Test Mode (FEC) for NXDN</td></tr>
|
||||
<tr><td>g</td><td>POCSAG 600Hz Test Pattern</td></tr>
|
||||
<tr><td>S/s</td><td>RSSI Mode</td></tr>
|
||||
<tr><td>I/i</td><td>Interrupt Counter Mode</td></tr>
|
||||
<tr><td>V/v</td><td>Display version of MMDVMCal</td></tr>
|
||||
<tr><td><space></td><td>Toggle transmit</td></tr>
|
||||
</table>
|
||||
Executable
+516
@@ -0,0 +1,516 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004,2007-2011,2013,2014-2017 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
||||
*
|
||||
* 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 "SerialController.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <setupapi.h>
|
||||
#include <winioctl.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
#if defined(__linux__)
|
||||
#include <linux/i2c-dev.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define EOL "\n"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define EOL "\r\n"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS) :
|
||||
m_device(device),
|
||||
m_speed(speed),
|
||||
m_assertRTS(assertRTS),
|
||||
m_handle(INVALID_HANDLE_VALUE)
|
||||
{
|
||||
assert(!device.empty());
|
||||
}
|
||||
|
||||
CSerialController::~CSerialController()
|
||||
{
|
||||
}
|
||||
|
||||
bool CSerialController::open()
|
||||
{
|
||||
assert(m_handle == INVALID_HANDLE_VALUE);
|
||||
|
||||
DWORD errCode;
|
||||
|
||||
std::string baseName = m_device.substr(4U); // Convert "\\.\COM10" to "COM10"
|
||||
|
||||
m_handle = ::CreateFileA(m_device.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (m_handle == INVALID_HANDLE_VALUE) {
|
||||
::fprintf(stderr, "Cannot open device - %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
DCB dcb;
|
||||
if (::GetCommState(m_handle, &dcb) == 0) {
|
||||
::fprintf(stderr, "Cannot get the attributes for %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
::ClearCommError(m_handle, &errCode, NULL);
|
||||
::CloseHandle(m_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
dcb.BaudRate = DWORD(m_speed);
|
||||
dcb.ByteSize = 8;
|
||||
dcb.Parity = NOPARITY;
|
||||
dcb.fParity = FALSE;
|
||||
dcb.StopBits = ONESTOPBIT;
|
||||
dcb.fInX = FALSE;
|
||||
dcb.fOutX = FALSE;
|
||||
dcb.fOutxCtsFlow = FALSE;
|
||||
dcb.fOutxDsrFlow = FALSE;
|
||||
dcb.fDsrSensitivity = FALSE;
|
||||
dcb.fDtrControl = DTR_CONTROL_DISABLE;
|
||||
dcb.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
|
||||
if (::SetCommState(m_handle, &dcb) == 0) {
|
||||
::fprintf(stderr, "Cannot set the attributes for %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
::ClearCommError(m_handle, &errCode, NULL);
|
||||
::CloseHandle(m_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
COMMTIMEOUTS timeouts;
|
||||
if (!::GetCommTimeouts(m_handle, &timeouts)) {
|
||||
::fprintf(stderr, "Cannot get the timeouts for %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
::ClearCommError(m_handle, &errCode, NULL);
|
||||
::CloseHandle(m_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
timeouts.ReadIntervalTimeout = MAXDWORD;
|
||||
timeouts.ReadTotalTimeoutMultiplier = 0UL;
|
||||
timeouts.ReadTotalTimeoutConstant = 0UL;
|
||||
|
||||
if (!::SetCommTimeouts(m_handle, &timeouts)) {
|
||||
::fprintf(stderr, "Cannot set the timeouts for %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
::ClearCommError(m_handle, &errCode, NULL);
|
||||
::CloseHandle(m_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::EscapeCommFunction(m_handle, CLRDTR) == 0) {
|
||||
::fprintf(stderr, "Cannot clear DTR for %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
::ClearCommError(m_handle, &errCode, NULL);
|
||||
::CloseHandle(m_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::EscapeCommFunction(m_handle, m_assertRTS ? SETRTS : CLRRTS) == 0) {
|
||||
::fprintf(stderr, "Cannot set/clear RTS for %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
::ClearCommError(m_handle, &errCode, NULL);
|
||||
::CloseHandle(m_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
::ClearCommError(m_handle, &errCode, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CSerialController::read(unsigned char* buffer, unsigned int length)
|
||||
{
|
||||
assert(m_handle != INVALID_HANDLE_VALUE);
|
||||
assert(buffer != NULL);
|
||||
|
||||
unsigned int ptr = 0U;
|
||||
|
||||
while (ptr < length) {
|
||||
int ret = readNonblock(buffer + ptr, length - ptr);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
} else if (ret == 0) {
|
||||
if (ptr == 0U)
|
||||
return 0;
|
||||
} else {
|
||||
ptr += ret;
|
||||
}
|
||||
}
|
||||
|
||||
return int(length);
|
||||
}
|
||||
|
||||
int CSerialController::readNonblock(unsigned char* buffer, unsigned int length)
|
||||
{
|
||||
assert(m_handle != INVALID_HANDLE_VALUE);
|
||||
assert(buffer != NULL);
|
||||
|
||||
if (length == 0U)
|
||||
return 0;
|
||||
|
||||
DWORD errors;
|
||||
COMSTAT status;
|
||||
if (::ClearCommError(m_handle, &errors, &status) == 0) {
|
||||
::fprintf(stderr, "Error from ClearCommError for %s, err=%04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status.cbInQue == 0UL)
|
||||
return 0;
|
||||
|
||||
DWORD readLength = status.cbInQue;
|
||||
if (length < readLength)
|
||||
readLength = length;
|
||||
|
||||
DWORD bytes = 0UL;
|
||||
BOOL ret = ::ReadFile(m_handle, buffer, readLength, &bytes, NULL);
|
||||
if (!ret) {
|
||||
::fprintf(stderr, "Error from ReadFile for %s: %04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return int(bytes);
|
||||
}
|
||||
|
||||
int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
||||
{
|
||||
assert(m_handle != INVALID_HANDLE_VALUE);
|
||||
assert(buffer != NULL);
|
||||
|
||||
if (length == 0U)
|
||||
return 0;
|
||||
|
||||
unsigned int ptr = 0U;
|
||||
|
||||
while (ptr < length) {
|
||||
DWORD bytes = 0UL;
|
||||
BOOL ret = ::WriteFile(m_handle, buffer + ptr, length - ptr, &bytes, NULL);
|
||||
if (!ret) {
|
||||
::fprintf(stderr, "Error from WriteFile for %s: %04lx" EOL, m_device.c_str(), ::GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr += bytes;
|
||||
}
|
||||
|
||||
return int(length);
|
||||
}
|
||||
|
||||
void CSerialController::close()
|
||||
{
|
||||
assert(m_handle != INVALID_HANDLE_VALUE);
|
||||
|
||||
::CloseHandle(m_handle);
|
||||
m_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CSerialController::CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS) :
|
||||
m_device(device),
|
||||
m_speed(speed),
|
||||
m_assertRTS(assertRTS),
|
||||
m_fd(-1)
|
||||
{
|
||||
assert(!device.empty());
|
||||
}
|
||||
|
||||
CSerialController::~CSerialController()
|
||||
{
|
||||
}
|
||||
|
||||
bool CSerialController::open()
|
||||
{
|
||||
assert(m_fd == -1);
|
||||
|
||||
if (m_device == "/dev/i2c-1") {
|
||||
#if defined(__linux__)
|
||||
m_fd = ::open(m_device.c_str(), O_RDWR);
|
||||
if (m_fd < 0) {
|
||||
::fprintf(stderr, "Cannot open device - %s", m_device.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::ioctl(m_fd, I2C_TENBIT, 0) < 0) {
|
||||
::fprintf(stderr, "CI2C: failed to set 7bitaddress");
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::ioctl(m_fd, I2C_SLAVE, 0x22) < 0) {
|
||||
::fprintf(stderr, "CI2C: Failed to acquire bus access/talk to slave 0x22");
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if defined(__APPLE__)
|
||||
m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); /*open in block mode under OSX*/
|
||||
#else
|
||||
m_fd = ::open(m_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY, 0);
|
||||
#endif
|
||||
if (m_fd < 0) {
|
||||
::fprintf(stderr, "Cannot open device - %s" EOL, m_device.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::isatty(m_fd) == 0) {
|
||||
::fprintf(stderr, "%s is not a TTY device" EOL, m_device.c_str());
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
termios termios;
|
||||
if (::tcgetattr(m_fd, &termios) < 0) {
|
||||
::fprintf(stderr, "Cannot get the attributes for %s" EOL, m_device.c_str());
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
termios.c_iflag &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK);
|
||||
termios.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL);
|
||||
termios.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
termios.c_oflag &= ~(OPOST);
|
||||
termios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | CRTSCTS);
|
||||
termios.c_cflag |= (CS8 | CLOCAL | CREAD);
|
||||
termios.c_lflag &= ~(ISIG | ICANON | IEXTEN);
|
||||
termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
#if defined(__APPLE__)
|
||||
termios.c_cc[VMIN] = 1;
|
||||
termios.c_cc[VTIME] = 1;
|
||||
#else
|
||||
termios.c_cc[VMIN] = 0;
|
||||
termios.c_cc[VTIME] = 10;
|
||||
#endif
|
||||
|
||||
switch (m_speed) {
|
||||
case SERIAL_1200:
|
||||
::cfsetospeed(&termios, B1200);
|
||||
::cfsetispeed(&termios, B1200);
|
||||
break;
|
||||
case SERIAL_2400:
|
||||
::cfsetospeed(&termios, B2400);
|
||||
::cfsetispeed(&termios, B2400);
|
||||
break;
|
||||
case SERIAL_4800:
|
||||
::cfsetospeed(&termios, B4800);
|
||||
::cfsetispeed(&termios, B4800);
|
||||
break;
|
||||
case SERIAL_9600:
|
||||
::cfsetospeed(&termios, B9600);
|
||||
::cfsetispeed(&termios, B9600);
|
||||
break;
|
||||
case SERIAL_19200:
|
||||
::cfsetospeed(&termios, B19200);
|
||||
::cfsetispeed(&termios, B19200);
|
||||
break;
|
||||
case SERIAL_38400:
|
||||
::cfsetospeed(&termios, B38400);
|
||||
::cfsetispeed(&termios, B38400);
|
||||
break;
|
||||
case SERIAL_115200:
|
||||
::cfsetospeed(&termios, B115200);
|
||||
::cfsetispeed(&termios, B115200);
|
||||
break;
|
||||
case SERIAL_230400:
|
||||
::cfsetospeed(&termios, B230400);
|
||||
::cfsetispeed(&termios, B230400);
|
||||
break;
|
||||
default:
|
||||
::fprintf(stderr, "Unsupported serial port speed - %d" EOL, int(m_speed));
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::tcsetattr(m_fd, TCSANOW, &termios) < 0) {
|
||||
::fprintf(stderr, "Cannot set the attributes for %s" EOL, m_device.c_str());
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_assertRTS) {
|
||||
unsigned int y;
|
||||
if (::ioctl(m_fd, TIOCMGET, &y) < 0) {
|
||||
::fprintf(stderr, "Cannot get the control attributes for %s" EOL, m_device.c_str());
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
y |= TIOCM_RTS;
|
||||
|
||||
if (::ioctl(m_fd, TIOCMSET, &y) < 0) {
|
||||
::fprintf(stderr, "Cannot set the control attributes for %s" EOL, m_device.c_str());
|
||||
::close(m_fd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
setNonblock(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
int CSerialController::setNonblock(bool nonblock)
|
||||
{
|
||||
int flag = ::fcntl(m_fd, F_GETFD, 0);
|
||||
|
||||
if (nonblock)
|
||||
flag |= O_NONBLOCK;
|
||||
else
|
||||
flag &= ~O_NONBLOCK;
|
||||
|
||||
return ::fcntl(m_fd, F_SETFL, flag);
|
||||
}
|
||||
#endif
|
||||
|
||||
int CSerialController::read(unsigned char* buffer, unsigned int length)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(m_fd != -1);
|
||||
|
||||
if (length == 0U)
|
||||
return 0;
|
||||
|
||||
unsigned int offset = 0U;
|
||||
|
||||
while (offset < length) {
|
||||
if (m_device == "/dev/i2c-1"){
|
||||
#if defined(__linux__)
|
||||
ssize_t c = ::read(m_fd, buffer + offset, 1U);
|
||||
if (c < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
::fprintf(stderr, "Error returned from read(), errno=%d" EOL, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (c > 0)
|
||||
offset += c;
|
||||
#endif
|
||||
} else {
|
||||
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(m_fd, &fds);
|
||||
int n;
|
||||
if (offset == 0U) {
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
n = ::select(m_fd + 1, &fds, NULL, NULL, &tv);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
} else {
|
||||
n = ::select(m_fd + 1, &fds, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
::fprintf(stderr, "Error from select(), errno=%d" EOL, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
ssize_t len = ::read(m_fd, buffer + offset, length - offset);
|
||||
if (len < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
::fprintf(stderr, "Error from read(), errno=%d" EOL, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (len > 0)
|
||||
offset += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
bool CSerialController::canWrite(){
|
||||
#if defined(__APPLE__)
|
||||
fd_set wset;
|
||||
FD_ZERO(&wset);
|
||||
FD_SET(m_fd, &wset);
|
||||
|
||||
struct timeval timeo;
|
||||
timeo.tv_sec = 0;
|
||||
timeo.tv_usec = 0;
|
||||
|
||||
int rc = select(m_fd + 1, NULL, &wset, NULL, &timeo);
|
||||
if (rc >0 && FD_ISSET(m_fd, &wset))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
int CSerialController::write(const unsigned char* buffer, unsigned int length)
|
||||
{
|
||||
assert(buffer != NULL);
|
||||
assert(m_fd != -1);
|
||||
|
||||
if (length == 0U)
|
||||
return 0;
|
||||
|
||||
unsigned int ptr = 0U;
|
||||
while (ptr < length) {
|
||||
ssize_t n = 0U;
|
||||
if (m_device == "/dev/i2c-1"){
|
||||
#if defined(__linux__)
|
||||
n = ::write(m_fd, buffer + ptr, 1U);
|
||||
#endif
|
||||
} else {
|
||||
if (canWrite())
|
||||
n = ::write(m_fd, buffer + ptr, length - ptr);
|
||||
}
|
||||
if (n < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
::fprintf(stderr, "Error returned from write(), errno=%d" EOL, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
ptr += n;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void CSerialController::close()
|
||||
{
|
||||
assert(m_fd != -1);
|
||||
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004,2007-2009,2011-2013,2015-2017 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 1999-2001 by Thomas Sailor HB9JNX
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SerialController_H
|
||||
#define SerialController_H
|
||||
|
||||
#include "SerialPort.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
enum SERIAL_SPEED {
|
||||
SERIAL_1200 = 1200,
|
||||
SERIAL_2400 = 2400,
|
||||
SERIAL_4800 = 4800,
|
||||
SERIAL_9600 = 9600,
|
||||
SERIAL_19200 = 19200,
|
||||
SERIAL_38400 = 38400,
|
||||
SERIAL_76800 = 76800,
|
||||
SERIAL_115200 = 115200,
|
||||
SERIAL_230400 = 230400
|
||||
};
|
||||
|
||||
class CSerialController : public ISerialPort {
|
||||
public:
|
||||
CSerialController(const std::string& device, SERIAL_SPEED speed, bool assertRTS = false);
|
||||
virtual ~CSerialController();
|
||||
|
||||
virtual bool open();
|
||||
|
||||
virtual int read(unsigned char* buffer, unsigned int length);
|
||||
|
||||
virtual int write(const unsigned char* buffer, unsigned int length);
|
||||
|
||||
virtual void close();
|
||||
|
||||
#if defined(__APPLE__)
|
||||
virtual int setNonblock(bool nonblock);
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::string m_device;
|
||||
SERIAL_SPEED m_speed;
|
||||
bool m_assertRTS;
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
HANDLE m_handle;
|
||||
#else
|
||||
int m_fd;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
int readNonblock(unsigned char* buffer, unsigned int length);
|
||||
#else
|
||||
bool canWrite();
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 "SerialPort.h"
|
||||
|
||||
ISerialPort::~ISerialPort()
|
||||
{
|
||||
}
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.
|
||||
*/
|
||||
|
||||
#ifndef SerialPort_H
|
||||
#define SerialPort_H
|
||||
|
||||
class ISerialPort {
|
||||
public:
|
||||
virtual ~ISerialPort() = 0;
|
||||
|
||||
virtual bool open() = 0;
|
||||
|
||||
virtual int read(unsigned char* buffer, unsigned int length) = 0;
|
||||
|
||||
virtual int write(const unsigned char* buffer, unsigned int length) = 0;
|
||||
|
||||
virtual void close() = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2009,2014-2016 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; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
void CUtils::dump(const std::string& title, const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::fprintf(stdout, "%s\n", title.c_str());
|
||||
#else
|
||||
::fprintf(stdout, "%s\r\n", title.c_str());
|
||||
#endif
|
||||
|
||||
unsigned int offset = 0U;
|
||||
|
||||
while (length > 0U) {
|
||||
::fprintf(stdout, "%04X: ", offset);
|
||||
|
||||
unsigned int bytes = (length > 16U) ? 16U : length;
|
||||
|
||||
for (unsigned i = 0U; i < bytes; i++)
|
||||
::fprintf(stdout, "%02X ", data[offset + i]);
|
||||
|
||||
for (unsigned int i = bytes; i < 16U; i++)
|
||||
::fprintf(stdout, " ");
|
||||
|
||||
::fprintf(stdout, " *");
|
||||
|
||||
for (unsigned i = 0U; i < bytes; i++) {
|
||||
unsigned char c = data[offset + i];
|
||||
|
||||
if (::isprint(c))
|
||||
::fprintf(stdout, "%c", c);
|
||||
else
|
||||
::fprintf(stdout, ".");
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::fprintf(stdout, "*\n");
|
||||
#else
|
||||
::fprintf(stdout, "*\r\n");
|
||||
#endif
|
||||
|
||||
offset += 16U;
|
||||
|
||||
if (length >= 16U)
|
||||
length -= 16U;
|
||||
else
|
||||
length = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
void CUtils::bitsToByteBE(const bool* bits, unsigned char& byte)
|
||||
{
|
||||
assert(bits != NULL);
|
||||
|
||||
byte = bits[0U] ? 0x80U : 0x00U;
|
||||
byte |= bits[1U] ? 0x40U : 0x00U;
|
||||
byte |= bits[2U] ? 0x20U : 0x00U;
|
||||
byte |= bits[3U] ? 0x10U : 0x00U;
|
||||
byte |= bits[4U] ? 0x08U : 0x00U;
|
||||
byte |= bits[5U] ? 0x04U : 0x00U;
|
||||
byte |= bits[6U] ? 0x02U : 0x00U;
|
||||
byte |= bits[7U] ? 0x01U : 0x00U;
|
||||
}
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2009,2014,2015 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; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef Utils_H
|
||||
#define Utils_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class CUtils {
|
||||
public:
|
||||
static void dump(const std::string& title, const unsigned char* data, unsigned int length);
|
||||
|
||||
static void bitsToByteBE(const bool* bits, unsigned char& byte);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
#endif
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2018,2019,2020 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(VERSION_H)
|
||||
#define VERSION_H
|
||||
|
||||
#define VERSION "MMDVMCal 20200506"
|
||||
|
||||
#endif
|
||||
Executable
+141
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2016 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 "YSFConvolution.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
#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])
|
||||
|
||||
const uint8_t BRANCH_TABLE1[] = {0U, 0U, 0U, 0U, 1U, 1U, 1U, 1U};
|
||||
const uint8_t BRANCH_TABLE2[] = {0U, 1U, 1U, 0U, 0U, 1U, 1U, 0U};
|
||||
|
||||
const unsigned int NUM_OF_STATES_D2 = 8U;
|
||||
const unsigned int NUM_OF_STATES = 16U;
|
||||
const uint32_t M = 2U;
|
||||
const unsigned int K = 5U;
|
||||
|
||||
CYSFConvolution::CYSFConvolution() :
|
||||
m_metrics1(NULL),
|
||||
m_metrics2(NULL),
|
||||
m_oldMetrics(NULL),
|
||||
m_newMetrics(NULL),
|
||||
m_decisions(NULL),
|
||||
m_dp(NULL)
|
||||
{
|
||||
m_metrics1 = new uint16_t[16U];
|
||||
m_metrics2 = new uint16_t[16U];
|
||||
m_decisions = new uint64_t[180U];
|
||||
}
|
||||
|
||||
CYSFConvolution::~CYSFConvolution()
|
||||
{
|
||||
delete[] m_metrics1;
|
||||
delete[] m_metrics2;
|
||||
delete[] m_decisions;
|
||||
}
|
||||
|
||||
void CYSFConvolution::start()
|
||||
{
|
||||
::memset(m_metrics1, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
||||
::memset(m_metrics2, 0x00U, NUM_OF_STATES * sizeof(uint16_t));
|
||||
|
||||
m_oldMetrics = m_metrics1;
|
||||
m_newMetrics = m_metrics2;
|
||||
m_dp = m_decisions;
|
||||
}
|
||||
|
||||
void CYSFConvolution::decode(uint8_t s0, uint8_t s1)
|
||||
{
|
||||
*m_dp = 0U;
|
||||
|
||||
for (uint8_t i = 0U; i < NUM_OF_STATES_D2; i++) {
|
||||
uint8_t j = i * 2U;
|
||||
|
||||
uint16_t metric = (BRANCH_TABLE1[i] ^ s0) + (BRANCH_TABLE2[i] ^ s1);
|
||||
|
||||
uint16_t m0 = m_oldMetrics[i] + metric;
|
||||
uint16_t m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + (M - metric);
|
||||
uint8_t decision0 = (m0 >= m1) ? 1U : 0U;
|
||||
m_newMetrics[j + 0U] = decision0 != 0U ? m1 : m0;
|
||||
|
||||
m0 = m_oldMetrics[i] + (M - metric);
|
||||
m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + metric;
|
||||
uint8_t decision1 = (m0 >= m1) ? 1U : 0U;
|
||||
m_newMetrics[j + 1U] = decision1 != 0U ? m1 : m0;
|
||||
|
||||
*m_dp |= (uint64_t(decision1) << (j + 1U)) | (uint64_t(decision0) << (j + 0U));
|
||||
}
|
||||
|
||||
++m_dp;
|
||||
|
||||
assert((m_dp - m_decisions) <= 180);
|
||||
|
||||
uint16_t* tmp = m_oldMetrics;
|
||||
m_oldMetrics = m_newMetrics;
|
||||
m_newMetrics = tmp;
|
||||
}
|
||||
|
||||
void CYSFConvolution::chainback(unsigned char* out, unsigned int nBits)
|
||||
{
|
||||
assert(out != NULL);
|
||||
|
||||
uint32_t state = 0U;
|
||||
|
||||
while (nBits-- > 0) {
|
||||
--m_dp;
|
||||
|
||||
uint32_t i = state >> (9 - K);
|
||||
uint8_t bit = uint8_t(*m_dp >> i) & 1;
|
||||
state = (bit << 7) | (state >> 1);
|
||||
|
||||
WRITE_BIT1(out, nBits, bit != 0U);
|
||||
}
|
||||
}
|
||||
|
||||
void CYSFConvolution::encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const
|
||||
{
|
||||
assert(in != NULL);
|
||||
assert(out != NULL);
|
||||
assert(nBits > 0U);
|
||||
|
||||
uint8_t d1 = 0U, d2 = 0U, d3 = 0U, d4 = 0U;
|
||||
uint32_t k = 0U;
|
||||
for (unsigned int i = 0U; i < nBits; i++) {
|
||||
uint8_t d = READ_BIT1(in, i) ? 1U : 0U;
|
||||
|
||||
uint8_t g1 = (d + d3 + d4) & 1;
|
||||
uint8_t g2 = (d + d1 + d2 + d4) & 1;
|
||||
|
||||
d4 = d3;
|
||||
d3 = d2;
|
||||
d2 = d1;
|
||||
d1 = d;
|
||||
|
||||
WRITE_BIT1(out, k, g1 != 0U);
|
||||
k++;
|
||||
|
||||
WRITE_BIT1(out, k, g2 != 0U);
|
||||
k++;
|
||||
}
|
||||
}
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016 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(YSFConvolution_H)
|
||||
#define YSFConvolution_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CYSFConvolution {
|
||||
public:
|
||||
CYSFConvolution();
|
||||
~CYSFConvolution();
|
||||
|
||||
void start();
|
||||
void decode(uint8_t s0, uint8_t s1);
|
||||
void chainback(unsigned char* out, unsigned int nBits);
|
||||
|
||||
void encode(const unsigned char* in, unsigned char* out, unsigned int nBits) const;
|
||||
|
||||
private:
|
||||
uint16_t* m_metrics1;
|
||||
uint16_t* m_metrics2;
|
||||
uint16_t* m_oldMetrics;
|
||||
uint16_t* m_newMetrics;
|
||||
uint64_t* m_decisions;
|
||||
uint64_t* m_dp;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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(YSFDefines_H)
|
||||
#define YSFDefines_H
|
||||
|
||||
const unsigned int YSF_FRAME_LENGTH_BYTES = 120U;
|
||||
|
||||
const unsigned char YSF_SYNC_BYTES[] = {0xD4U, 0x71U, 0xC9U, 0x63U, 0x4DU};
|
||||
const unsigned int YSF_SYNC_LENGTH_BYTES = 5U;
|
||||
|
||||
const unsigned int YSF_FICH_LENGTH_BYTES = 25U;
|
||||
|
||||
const unsigned char YSF_SYNC_OK = 0x01U;
|
||||
|
||||
const unsigned int YSF_CALLSIGN_LENGTH = 10U;
|
||||
|
||||
const unsigned int YSF_FRAME_TIME = 100U;
|
||||
|
||||
const unsigned char YSF_FI_HEADER = 0x00U;
|
||||
const unsigned char YSF_FI_COMMUNICATIONS = 0x01U;
|
||||
const unsigned char YSF_FI_TERMINATOR = 0x02U;
|
||||
const unsigned char YSF_FI_TEST = 0x03U;
|
||||
|
||||
const unsigned char YSF_DT_VD_MODE1 = 0x00U;
|
||||
const unsigned char YSF_DT_DATA_FR_MODE = 0x01U;
|
||||
const unsigned char YSF_DT_VD_MODE2 = 0x02U;
|
||||
const unsigned char YSF_DT_VOICE_FR_MODE = 0x03U;
|
||||
|
||||
const unsigned char YSF_CM_GROUP1 = 0x00U;
|
||||
const unsigned char YSF_CM_GROUP2 = 0x01U;
|
||||
const unsigned char YSF_CM_INDIVIDUAL = 0x03U;
|
||||
|
||||
const unsigned char YSF_MR_DIRECT = 0x00U;
|
||||
const unsigned char YSF_MR_NOT_BUSY = 0x01U;
|
||||
const unsigned char YSF_MR_BUSY = 0x02U;
|
||||
|
||||
#endif
|
||||
Executable
+286
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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 "YSFConvolution.h"
|
||||
#include "YSFDefines.h"
|
||||
#include "Golay24128.h"
|
||||
#include "YSFFICH.h"
|
||||
#include "CRC.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
#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])
|
||||
|
||||
const unsigned int INTERLEAVE_TABLE[] = {
|
||||
0U, 40U, 80U, 120U, 160U,
|
||||
2U, 42U, 82U, 122U, 162U,
|
||||
4U, 44U, 84U, 124U, 164U,
|
||||
6U, 46U, 86U, 126U, 166U,
|
||||
8U, 48U, 88U, 128U, 168U,
|
||||
10U, 50U, 90U, 130U, 170U,
|
||||
12U, 52U, 92U, 132U, 172U,
|
||||
14U, 54U, 94U, 134U, 174U,
|
||||
16U, 56U, 96U, 136U, 176U,
|
||||
18U, 58U, 98U, 138U, 178U,
|
||||
20U, 60U, 100U, 140U, 180U,
|
||||
22U, 62U, 102U, 142U, 182U,
|
||||
24U, 64U, 104U, 144U, 184U,
|
||||
26U, 66U, 106U, 146U, 186U,
|
||||
28U, 68U, 108U, 148U, 188U,
|
||||
30U, 70U, 110U, 150U, 190U,
|
||||
32U, 72U, 112U, 152U, 192U,
|
||||
34U, 74U, 114U, 154U, 194U,
|
||||
36U, 76U, 116U, 156U, 196U,
|
||||
38U, 78U, 118U, 158U, 198U};
|
||||
|
||||
CYSFFICH::CYSFFICH(const CYSFFICH& fich) :
|
||||
m_fich(NULL)
|
||||
{
|
||||
m_fich = new unsigned char[6U];
|
||||
|
||||
::memcpy(m_fich, fich.m_fich, 6U);
|
||||
}
|
||||
|
||||
CYSFFICH::CYSFFICH() :
|
||||
m_fich(NULL)
|
||||
{
|
||||
m_fich = new unsigned char[6U];
|
||||
|
||||
memset(m_fich, 0x00U, 6U);
|
||||
}
|
||||
|
||||
CYSFFICH::~CYSFFICH()
|
||||
{
|
||||
delete[] m_fich;
|
||||
}
|
||||
|
||||
bool CYSFFICH::decode(const unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
|
||||
// Skip the sync bytes
|
||||
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||
|
||||
CYSFConvolution viterbi;
|
||||
viterbi.start();
|
||||
|
||||
// Deinterleave the FICH and send bits to the Viterbi decoder
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE[i];
|
||||
uint8_t s0 = READ_BIT1(bytes, n) ? 1U : 0U;
|
||||
|
||||
n++;
|
||||
uint8_t s1 = READ_BIT1(bytes, n) ? 1U : 0U;
|
||||
|
||||
viterbi.decode(s0, s1);
|
||||
}
|
||||
|
||||
unsigned char output[13U];
|
||||
viterbi.chainback(output, 96U);
|
||||
|
||||
unsigned int b0 = CGolay24128::decode24128(output + 0U);
|
||||
unsigned int b1 = CGolay24128::decode24128(output + 3U);
|
||||
unsigned int b2 = CGolay24128::decode24128(output + 6U);
|
||||
unsigned int b3 = CGolay24128::decode24128(output + 9U);
|
||||
|
||||
m_fich[0U] = (b0 >> 4) & 0xFFU;
|
||||
m_fich[1U] = ((b0 << 4) & 0xF0U) | ((b1 >> 8) & 0x0FU);
|
||||
m_fich[2U] = (b1 >> 0) & 0xFFU;
|
||||
m_fich[3U] = (b2 >> 4) & 0xFFU;
|
||||
m_fich[4U] = ((b2 << 4) & 0xF0U) | ((b3 >> 8) & 0x0FU);
|
||||
m_fich[5U] = (b3 >> 0) & 0xFFU;
|
||||
|
||||
return CCRC::checkCCITT162(m_fich, 6U);
|
||||
}
|
||||
|
||||
void CYSFFICH::encode(unsigned char* bytes)
|
||||
{
|
||||
assert(bytes != NULL);
|
||||
|
||||
// Skip the sync bytes
|
||||
bytes += YSF_SYNC_LENGTH_BYTES;
|
||||
|
||||
CCRC::addCCITT162(m_fich, 6U);
|
||||
|
||||
unsigned int b0 = ((m_fich[0U] << 4) & 0xFF0U) | ((m_fich[1U] >> 4) & 0x00FU);
|
||||
unsigned int b1 = ((m_fich[1U] << 8) & 0xF00U) | ((m_fich[2U] >> 0) & 0x0FFU);
|
||||
unsigned int b2 = ((m_fich[3U] << 4) & 0xFF0U) | ((m_fich[4U] >> 4) & 0x00FU);
|
||||
unsigned int b3 = ((m_fich[4U] << 8) & 0xF00U) | ((m_fich[5U] >> 0) & 0x0FFU);
|
||||
|
||||
unsigned int c0 = CGolay24128::encode24128(b0);
|
||||
unsigned int c1 = CGolay24128::encode24128(b1);
|
||||
unsigned int c2 = CGolay24128::encode24128(b2);
|
||||
unsigned int c3 = CGolay24128::encode24128(b3);
|
||||
|
||||
unsigned char conv[13U];
|
||||
conv[0U] = (c0 >> 16) & 0xFFU;
|
||||
conv[1U] = (c0 >> 8) & 0xFFU;
|
||||
conv[2U] = (c0 >> 0) & 0xFFU;
|
||||
conv[3U] = (c1 >> 16) & 0xFFU;
|
||||
conv[4U] = (c1 >> 8) & 0xFFU;
|
||||
conv[5U] = (c1 >> 0) & 0xFFU;
|
||||
conv[6U] = (c2 >> 16) & 0xFFU;
|
||||
conv[7U] = (c2 >> 8) & 0xFFU;
|
||||
conv[8U] = (c2 >> 0) & 0xFFU;
|
||||
conv[9U] = (c3 >> 16) & 0xFFU;
|
||||
conv[10U] = (c3 >> 8) & 0xFFU;
|
||||
conv[11U] = (c3 >> 0) & 0xFFU;
|
||||
conv[12U] = 0x00U;
|
||||
|
||||
CYSFConvolution convolution;
|
||||
unsigned char convolved[25U];
|
||||
convolution.encode(conv, convolved, 100U);
|
||||
|
||||
unsigned int j = 0U;
|
||||
for (unsigned int i = 0U; i < 100U; i++) {
|
||||
unsigned int n = INTERLEAVE_TABLE[i];
|
||||
|
||||
bool s0 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
bool s1 = READ_BIT1(convolved, j) != 0U;
|
||||
j++;
|
||||
|
||||
WRITE_BIT1(bytes, n, s0);
|
||||
|
||||
n++;
|
||||
WRITE_BIT1(bytes, n, s1);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getFI() const
|
||||
{
|
||||
return (m_fich[0U] >> 6) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getCM() const
|
||||
{
|
||||
return (m_fich[0U] >> 2) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getBN() const
|
||||
{
|
||||
return m_fich[0U] & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getBT() const
|
||||
{
|
||||
return (m_fich[1U] >> 6) & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getFN() const
|
||||
{
|
||||
return (m_fich[1U] >> 3) & 0x07U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getFT() const
|
||||
{
|
||||
return m_fich[1U] & 0x07U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getDT() const
|
||||
{
|
||||
return m_fich[2U] & 0x03U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getMR() const
|
||||
{
|
||||
return (m_fich[2U] >> 3) & 0x03U;
|
||||
}
|
||||
|
||||
bool CYSFFICH::getDev() const
|
||||
{
|
||||
return (m_fich[2U] & 0x40U) == 0x40U;
|
||||
}
|
||||
|
||||
bool CYSFFICH::getSQL() const
|
||||
{
|
||||
return (m_fich[3U] & 0x80U) == 0x80U;
|
||||
}
|
||||
|
||||
unsigned char CYSFFICH::getSQ() const
|
||||
{
|
||||
return m_fich[3U] & 0x7FU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setFI(unsigned char fi)
|
||||
{
|
||||
m_fich[0U] &= 0x3FU;
|
||||
m_fich[0U] |= (fi << 6) & 0xC0U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setFN(unsigned char fn)
|
||||
{
|
||||
m_fich[1U] &= 0xC7U;
|
||||
m_fich[1U] |= (fn << 3) & 0x38U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setFT(unsigned char ft)
|
||||
{
|
||||
m_fich[1U] &= 0xF8U;
|
||||
m_fich[1U] |= ft & 0x07U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setMR(unsigned char mr)
|
||||
{
|
||||
m_fich[2U] &= 0xC7U;
|
||||
m_fich[2U] |= (mr << 3) & 0x38U;
|
||||
}
|
||||
|
||||
void CYSFFICH::setVoIP(bool on)
|
||||
{
|
||||
if (on)
|
||||
m_fich[2U] |= 0x04U;
|
||||
else
|
||||
m_fich[2U] &= 0xFBU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setDev(bool on)
|
||||
{
|
||||
if (on)
|
||||
m_fich[2U] |= 0x40U;
|
||||
else
|
||||
m_fich[2U] &= 0xBFU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setSQL(bool on)
|
||||
{
|
||||
if (on)
|
||||
m_fich[3U] |= 0x80U;
|
||||
else
|
||||
m_fich[3U] &= 0x7FU;
|
||||
}
|
||||
|
||||
void CYSFFICH::setSQ(unsigned char sq)
|
||||
{
|
||||
m_fich[3U] &= 0x80U;
|
||||
m_fich[3U] |= sq & 0x7FU;
|
||||
}
|
||||
|
||||
CYSFFICH& CYSFFICH::operator=(const CYSFFICH& fich)
|
||||
{
|
||||
if (&fich != this)
|
||||
::memcpy(m_fich, fich.m_fich, 6U);
|
||||
|
||||
return *this;
|
||||
}
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* 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(YSFFICH_H)
|
||||
#define YSFFICH_H
|
||||
|
||||
class CYSFFICH {
|
||||
public:
|
||||
CYSFFICH(const CYSFFICH& fich);
|
||||
CYSFFICH();
|
||||
~CYSFFICH();
|
||||
|
||||
bool decode(const unsigned char* bytes);
|
||||
|
||||
void encode(unsigned char* bytes);
|
||||
|
||||
unsigned char getFI() const;
|
||||
unsigned char getCM() const;
|
||||
unsigned char getBN() const;
|
||||
unsigned char getBT() const;
|
||||
unsigned char getFN() const;
|
||||
unsigned char getFT() const;
|
||||
unsigned char getDT() const;
|
||||
unsigned char getMR() const;
|
||||
bool getDev() const;
|
||||
bool getSQL() const;
|
||||
unsigned char getSQ() const;
|
||||
|
||||
void setFI(unsigned char fi);
|
||||
void setFN(unsigned char fn);
|
||||
void setFT(unsigned char ft);
|
||||
void setMR(unsigned char mr);
|
||||
void setVoIP(bool set);
|
||||
void setDev(bool set);
|
||||
void setSQL(bool set);
|
||||
void setSQ(unsigned char sq);
|
||||
|
||||
CYSFFICH& operator=(const CYSFFICH& fich);
|
||||
|
||||
private:
|
||||
unsigned char* m_fich;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user