Add software

This commit is contained in:
RocketGod
2022-09-22 09:26:57 -07:00
parent fee0ab05fd
commit 957ea3d712
4511 changed files with 1943182 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "aprs.hpp"
#include "ax25.hpp"
#include "portapack_persistent_memory.hpp"
using namespace ax25;
namespace aprs {
void make_aprs_frame(const char * src_address, const uint32_t src_ssid,
const char * dest_address, const uint32_t dest_ssid,
const std::string& payload) {
AX25Frame frame;
char address[14] = { 0 };
memcpy(&address[0], dest_address, 6);
memcpy(&address[7], src_address, 6);
//euquiq: According to ax.25 doc section 2.2.13.x.x and 2.4.1.2
// SSID need bits 5.6 set, so later when shifted it will end up being 011xxxx0 (xxxx = SSID number)
// Notice that if need to signal usage of AX.25 V2.0, (dest_ssid | 112); (MSb will need to be set at the end)
address[6] = (dest_ssid | 48);
address[13] = (src_ssid | 48);
frame.make_ui_frame(address, 0x03, protocol_id_t::NO_LAYER3, payload);
}
} /* namespace aprs */

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <cstring>
#include <string>
#ifndef __APRS_H__
#define __APRS_H__
namespace aprs {
void make_aprs_frame(
const char * src_address, const uint32_t src_ssid,
const char * dest_address, const uint32_t dest_ssid,
const std::string& payload);
} /* namespace aprs */
#endif/*__APRS_H__*/

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ax25.hpp"
#include "portapack_shared_memory.hpp"
namespace ax25 {
void AX25Frame::make_extended_field(char * const data, size_t length) {
size_t i = 0;
for (i = 0; i < length - 1; i++)
add_data(data[i] << 1);
add_data((data[i] << 1) | 1);
}
void AX25Frame::NRZI_add_bit(const uint32_t bit) {
if (!bit)
current_bit ^= 1; // Zero: flip
current_byte <<= 1;
current_byte |= current_bit;
bit_counter++;
if (bit_counter == 8) {
bit_counter = 0;
*bb_data_ptr = current_byte;
bb_data_ptr++;
}
}
void AX25Frame::add_byte(uint8_t byte, bool is_flag, bool is_data)
{
bool bit;
if (is_data)
crc_ccitt.process_byte(byte);
for (uint32_t i = 0; i < 8; i++)
{
bit = (byte >> i) & 1;
NRZI_add_bit(bit);
if (bit)
{
ones_counter++;
if ((ones_counter == 5) && (!is_flag))
{
NRZI_add_bit(0);
ones_counter = 0;
}
}
else
ones_counter = 0;
}
}
void AX25Frame::flush()
{
if (bit_counter)
*bb_data_ptr = current_byte << (8 - bit_counter); //euquiq: This was 7 but there are 8 bits
};
void AX25Frame::add_flag() {
add_byte(AX25_FLAG, true, false);
};
void AX25Frame::add_data(uint8_t byte) {
add_byte(byte, false, true);
};
void AX25Frame::add_checksum() {
auto checksum = crc_ccitt.checksum();
add_byte(checksum, false, false);
add_byte(checksum >> 8, false, false);
}
void AX25Frame::make_ui_frame(char * const address, const uint8_t control,
const uint8_t protocol, const std::string& info) {
size_t i;
bb_data_ptr = (uint16_t*)shared_memory.bb_data.data;
memset(bb_data_ptr, 0, sizeof(shared_memory.bb_data.data));
bit_counter = 0;
current_bit = 0;
current_byte = 0;
ones_counter = 0;
crc_ccitt.reset();
add_flag();
add_flag();
add_flag();
add_flag();
make_extended_field(address, 14);
add_data(control);
add_data(protocol);
for (i = 0; i < info.size(); i++)
add_data(info[i]);
add_checksum();
add_flag();
add_flag();
flush();
}
} /* namespace ax25 */

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "crc.hpp"
#include <cstring>
#include <string>
#ifndef __AX25_H__
#define __AX25_H__
#define AX25_FLAG 0x7E
namespace ax25 {
enum protocol_id_t {
X25_PLP = 0x01,
COMP_TCPIP = 0x06,
UNCOMP_TCPIP = 0x07,
SEG_FRAG = 0x08,
FLEXNET = 0xCE,
NO_LAYER3 = 0xF0
};
class AX25Frame {
public:
void make_ui_frame(char * const address, const uint8_t control, const uint8_t protocol,
const std::string& info);
private:
void NRZI_add_bit(const uint32_t bit);
void make_extended_field(char * const data, size_t length);
void add_byte(uint8_t byte, bool is_flag, bool is_data);
void add_data(uint8_t byte);
void add_checksum();
void add_flag();
void flush();
uint16_t * bb_data_ptr { nullptr };
uint8_t current_bit { 0 };
uint8_t current_byte { 0 };
size_t bit_counter { 0 };
uint8_t ones_counter { 0 };
CRC<16, true, true> crc_ccitt { 0x1021, 0xFFFF, 0xFFFF };
};
} /* namespace ax25 */
#endif/*__AX25_H__*/

View File

@@ -0,0 +1,154 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "bht.hpp"
#include "portapack_persistent_memory.hpp"
size_t gen_message_ep(uint8_t city_code, size_t family_code_ep, uint32_t relay_number, uint32_t relay_state) {
size_t c;
const encoder_def_t * um3750_def;
uint8_t bits[12];
std::string ep_fragments;
//char ep_message[13] = { 0 };
// Repeated 2x 26 times
// Whole frame + space = 128ms, data only = 64ms
um3750_def = &encoder_defs[ENCODER_UM3750];
// City code is bit-reversed
for (c = 0; c < 8; c++)
bits[c] = (city_code >> c) & 1;
bits[8] = (family_code_ep >> 1) & 1;
bits[9] = family_code_ep & 1;
bits[10] = relay_number & 1;
bits[11] = relay_state ? 1 : 0;
// Text for display
//for (c = 0; c < 12; c++)
// ep_message[c] = bits[c] + '0';
c = 0;
for (auto ch : um3750_def->word_format) {
if (ch == 'S')
ep_fragments += um3750_def->sync;
else
ep_fragments += um3750_def->bit_format[bits[c++]];
}
// Return bitstream length
return make_bitstream(ep_fragments);
}
std::string gen_message_xy(const std::string& ascii_code) {
std::string local_code = ascii_code;
uint8_t ccir_message[XY_TONE_COUNT];
uint8_t translate;
uint32_t c;
// Replace repeats with E code
for (c = 1; c < XY_TONE_COUNT; c++)
if (local_code[c] == local_code[c - 1]) local_code[c] = 'E';
for (c = 0; c < XY_TONE_COUNT; c++) {
if (local_code[c] <= '9')
translate = local_code[c] - '0';
else
translate = local_code[c] - 'A' + 10;
ccir_message[c] = (translate < 16) ? translate : 0; // Sanitize
}
// Copy for baseband
memcpy(shared_memory.bb_data.tones_data.message, ccir_message, XY_TONE_COUNT);
// Return as text for display
return local_code;
}
std::string gen_message_xy(size_t header_code_a, size_t header_code_b, size_t city_code, size_t family_code,
bool subfamily_wc, size_t subfamily_code, bool id_wc, size_t receiver_code,
size_t relay_state_A, size_t relay_state_B, size_t relay_state_C, size_t relay_state_D) {
uint8_t ccir_message[XY_TONE_COUNT];
size_t c;
// Header
ccir_message[0] = (header_code_a / 10);
ccir_message[1] = (header_code_a % 10);
ccir_message[2] = (header_code_b / 10);
ccir_message[3] = (header_code_b % 10);
// Addresses
ccir_message[4] = (city_code / 10);
ccir_message[5] = (city_code % 10);
ccir_message[6] = family_code;
if (subfamily_wc)
ccir_message[7] = 0xA; // Wildcard
else
ccir_message[7] = subfamily_code;
if (id_wc) {
ccir_message[8] = 0xA; // Wildcard
ccir_message[9] = 0xA; // Wildcard
} else {
ccir_message[8] = (receiver_code / 10);
ccir_message[9] = (receiver_code % 10);
}
ccir_message[10] = 0xB;
// Relay states
ccir_message[11] = relay_state_A;
ccir_message[12] = relay_state_B;
ccir_message[13] = relay_state_C;
ccir_message[14] = relay_state_D;
ccir_message[15] = 0xB;
// End
for (c = 16; c < XY_TONE_COUNT; c++)
ccir_message[c] = 0;
// Replace repeats with E code
for (c = 1; c < XY_TONE_COUNT; c++)
if (ccir_message[c] == ccir_message[c - 1]) ccir_message[c] = 0xE;
// Copy for baseband
memcpy(shared_memory.bb_data.tones_data.message, ccir_message, XY_TONE_COUNT);
// Return as text for display
return ccir_to_ascii(ccir_message);
}
std::string ccir_to_ascii(uint8_t * ccir) {
std::string ascii;
for (size_t c = 0; c < XY_TONE_COUNT; c++) {
if (ccir[c] > 9)
ascii += (char)(ccir[c] - 10 + 'A');
else
ascii += (char)(ccir[c] + '0');
}
return ascii;
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "tonesets.hpp"
#include "encoders.hpp"
using namespace encoders;
#define XY_TONE_DURATION ((TONES_SAMPLERATE * 0.1) - 1) // 100ms
#define XY_SILENCE (TONES_SAMPLERATE * 0.4) // 400ms
#define XY_TONE_COUNT 20
#define XY_MAX_CITY 99
#define EPAR_BIT_DURATION (OOK_SAMPLERATE / 580)
#define EPAR_REPEAT_COUNT 26
#define EPAR_MAX_CITY 255
struct bht_city {
std::string name;
uint8_t freq_index;
bool recent;
};
size_t gen_message_ep(uint8_t city_code, size_t family_code_ep, uint32_t relay_state_A, uint32_t relay_state_B);
std::string gen_message_xy(const std::string& code);
std::string gen_message_xy(size_t header_code_a, size_t header_code_b, size_t city_code, size_t family_code,
bool subfamily_wc, size_t subfamily_code, bool id_wc, size_t receiver_code,
size_t relay_state_A, size_t relay_state_B, size_t relay_state_C, size_t relay_state_D);
std::string ccir_to_ascii(uint8_t * ccir);

View File

@@ -0,0 +1,547 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "dcs.hpp"
namespace dcs {
const uint16_t dcs_parity[DCS_CODES_NB] = {
0b11000111010, // 0
0b01001001111, // 1
0b01010100101, // 2
0b11011010000, // 3
0b01101110001, // 4
0b11100000100, // 5
0b11111101110, // 6
0b01110011011, // 7
0b00011011001, // 8
0b10010101100, // 9
0b10001000110, // 10
0b00000110011, // 11
0b10110010010, // 12
0b00111100111, // 13
0b00100001101, // 14
0b10101111000, // 15
0b11110001001, // 16
0b01111111100, // 17
0b01100010110, // 18
0b11101100011, // 19
0b01011000010, // 20
0b11010110111, // 21
0b11001011101, // 22
0b01000101000, // 23
0b00101101010, // 24
0b10100011111, // 25
0b10111110101, // 26
0b00110000000, // 27
0b10000100001, // 28
0b00001010100, // 29
0b00010111110, // 30
0b10011001011, // 31
0b10101011100, // 32
0b00100101001, // 33
0b00111000011, // 34
0b10110110110, // 35
0b00000010111, // 36
0b10001100010, // 37
0b10010001000, // 38
0b00011111101, // 39
0b01110111111, // 40
0b11111001010, // 41
0b11100100000, // 42
0b01101010101, // 43
0b11011110100, // 44
0b01010000001, // 45
0b01001101011, // 46
0b11000011110, // 47
0b10011101111, // 48
0b00010011010, // 49
0b00001110000, // 50
0b10000000101, // 51
0b00110100100, // 52
0b10111010001, // 53
0b10100111011, // 54
0b00101001110, // 55
0b01000001100, // 56
0b11001111001, // 57
0b11010010011, // 58
0b01011100110, // 59
0b11101000111, // 60
0b01100110010, // 61
0b01111011000, // 62
0b11110101101, // 63
0b00011110110, // 64
0b10010000011, // 65
0b10001101001, // 66
0b00000011100, // 67
0b10110111101, // 68
0b00111001000, // 69
0b00100100010, // 70
0b10101010111, // 71
0b11000010101, // 72
0b01001100000, // 73
0b01010001010, // 74
0b11011111111, // 75
0b01101011110, // 76
0b11100101011, // 77
0b11111000001, // 78
0b01110110100, // 79
0b00101000101, // 80
0b10100110000, // 81
0b10111011010, // 82
0b00110101111, // 83
0b10000001110, // 84
0b00001111011, // 85
0b00010010001, // 86
0b10011100100, // 87
0b11110100110, // 88
0b01111010011, // 89
0b01100111001, // 90
0b11101001100, // 91
0b01011101101, // 92
0b11010011000, // 93
0b11001110010, // 94
0b01000000111, // 95
0b01110010000, // 96
0b11111100101, // 97
0b11100001111, // 98
0b01101111010, // 99
0b11011011011, // 100
0b01010101110, // 101
0b01001000100, // 102
0b11000110001, // 103
0b10101110011, // 104
0b00100000110, // 105
0b00111101100, // 106
0b10110011001, // 107
0b00000111000, // 108
0b10001001101, // 109
0b10010100111, // 110
0b00011010010, // 111
0b01000100011, // 112
0b11001010110, // 113
0b11010111100, // 114
0b01011001001, // 115
0b11101101000, // 116
0b01100011101, // 117
0b01111110111, // 118
0b11110000010, // 119
0b10011000000, // 120
0b00010110101, // 121
0b00001011111, // 122
0b10000101010, // 123
0b00110001011, // 124
0b10111111110, // 125
0b10100010100, // 126
0b00101100001, // 127
0b11111010111, // 128
0b01110100010, // 129
0b01101001000, // 130
0b11100111101, // 131
0b01010011100, // 132
0b11011101001, // 133
0b11000000011, // 134
0b01001110110, // 135
0b00100110100, // 136
0b10101000001, // 137
0b10110101011, // 138
0b00111011110, // 139
0b10001111111, // 140
0b00000001010, // 141
0b00011100000, // 142
0b10010010101, // 143
0b11001100100, // 144
0b01000010001, // 145
0b01011111011, // 146
0b11010001110, // 147
0b01100101111, // 148
0b11101011010, // 149
0b11110110000, // 150
0b01111000101, // 151
0b00010000111, // 152
0b10011110010, // 153
0b10000011000, // 154
0b00001101101, // 155
0b10111001100, // 156
0b00110111001, // 157
0b00101010011, // 158
0b10100100110, // 159
0b10010110001, // 160
0b00011000100, // 161
0b00000101110, // 162
0b10001011011, // 163
0b00111111010, // 164
0b10110001111, // 165
0b10101100101, // 166
0b00100010000, // 167
0b01001010010, // 168
0b11000100111, // 169
0b11011001101, // 170
0b01010111000, // 171
0b11100011001, // 172
0b01101101100, // 173
0b01110000110, // 174
0b11111110011, // 175
0b10100000010, // 176
0b00101110111, // 177
0b00110011101, // 178
0b10111101000, // 179
0b00001001001, // 180
0b10000111100, // 181
0b10011010110, // 182
0b00010100011, // 183
0b01111100001, // 184
0b11110010100, // 185
0b11101111110, // 186
0b01100001011, // 187
0b11010101010, // 188
0b01011011111, // 189
0b01000110101, // 190
0b11001000000, // 191
0b00100011011, // 192
0b10101101110, // 193
0b10110000100, // 194
0b00111110001, // 195
0b10001010000, // 196
0b00000100101, // 197
0b00011001111, // 198
0b10010111010, // 199
0b11111111000, // 200
0b01110001101, // 201
0b01101100111, // 202
0b11100010010, // 203
0b01010110011, // 204
0b11011000110, // 205
0b11000101100, // 206
0b01001011001, // 207
0b00010101000, // 208
0b10011011101, // 209
0b10000110111, // 210
0b00001000010, // 211
0b10111100011, // 212
0b00110010110, // 213
0b00101111100, // 214
0b10100001001, // 215
0b11001001011, // 216
0b01000111110, // 217
0b01011010100, // 218
0b11010100001, // 219
0b01100000000, // 220
0b11101110101, // 221
0b11110011111, // 222
0b01111101010, // 223
0b01001111101, // 224
0b11000001000, // 225
0b11011100010, // 226
0b01010010111, // 227
0b11100110110, // 228
0b01101000011, // 229
0b01110101001, // 230
0b11111011100, // 231
0b10010011110, // 232
0b00011101011, // 233
0b00000000001, // 234
0b10001110100, // 235
0b00111010101, // 236
0b10110100000, // 237
0b10101001010, // 238
0b00100111111, // 239
0b01111001110, // 240
0b11110111011, // 241
0b11101010001, // 242
0b01100100100, // 243
0b11010000101, // 244
0b01011110000, // 245
0b01000011010, // 246
0b11001101111, // 247
0b10100101101, // 248
0b00101011000, // 249
0b00110110010, // 250
0b10111000111, // 251
0b00001100110, // 252
0b10000010011, // 253
0b10011111001, // 254
0b00010001100, // 255
0b10111100000, // 256
0b00110010101, // 257
0b00101111111, // 258
0b10100001010, // 259
0b00010101011, // 260
0b10011011110, // 261
0b10000110100, // 262
0b00001000001, // 263
0b01100000011, // 264
0b11101110110, // 265
0b11110011100, // 266
0b01111101001, // 267
0b11001001000, // 268
0b01000111101, // 269
0b01011010111, // 270
0b11010100010, // 271
0b10001010011, // 272
0b00000100110, // 273
0b00011001100, // 274
0b10010111001, // 275
0b00100011000, // 276
0b10101101101, // 277
0b10110000111, // 278
0b00111110010, // 279
0b01010110000, // 280
0b11011000101, // 281
0b11000101111, // 282
0b01001011010, // 283
0b11111111011, // 284
0b01110001110, // 285
0b01101100100, // 286
0b11100010001, // 287
0b11010000110, // 288
0b01011110011, // 289
0b01000011001, // 290
0b11001101100, // 291
0b01111001101, // 292
0b11110111000, // 293
0b11101010010, // 294
0b01100100111, // 295
0b00001100101, // 296
0b10000010000, // 297
0b10011111010, // 298
0b00010001111, // 299
0b10100101110, // 300
0b00101011011, // 301
0b00110110001, // 302
0b10111000100, // 303
0b11100110101, // 304
0b01101000000, // 305
0b01110101010, // 306
0b11111011111, // 307
0b01001111110, // 308
0b11000001011, // 309
0b11011100001, // 310
0b01010010100, // 311
0b00111010110, // 312
0b10110100011, // 313
0b10101001001, // 314
0b00100111100, // 315
0b10010011101, // 316
0b00011101000, // 317
0b00000000010, // 318
0b10001110111, // 319
0b01100101100, // 320
0b11101011001, // 321
0b11110110011, // 322
0b01111000110, // 323
0b11001100111, // 324
0b01000010010, // 325
0b01011111000, // 326
0b11010001101, // 327
0b10111001111, // 328
0b00110111010, // 329
0b00101010000, // 330
0b10100100101, // 331
0b00010000100, // 332
0b10011110001, // 333
0b10000011011, // 334
0b00001101110, // 335
0b01010011111, // 336
0b11011101010, // 337
0b11000000000, // 338
0b01001110101, // 339
0b11111010100, // 340
0b01110100001, // 341
0b01101001011, // 342
0b11100111110, // 343
0b10001111100, // 344
0b00000001001, // 345
0b00011100011, // 346
0b10010010110, // 347
0b00100110111, // 348
0b10101000010, // 349
0b10110101000, // 350
0b00111011101, // 351
0b00001001010, // 352
0b10000111111, // 353
0b10011010101, // 354
0b00010100000, // 355
0b10100000001, // 356
0b00101110100, // 357
0b00110011110, // 358
0b10111101011, // 359
0b11010101001, // 360
0b01011011100, // 361
0b01000110110, // 362
0b11001000011, // 363
0b01111100010, // 364
0b11110010111, // 365
0b11101111101, // 366
0b01100001000, // 367
0b00111111001, // 368
0b10110001100, // 369
0b10101100110, // 370
0b00100010011, // 371
0b10010110010, // 372
0b00011000111, // 373
0b00000101101, // 374
0b10001011000, // 375
0b11100011010, // 376
0b01101101111, // 377
0b01110000101, // 378
0b11111110000, // 379
0b01001010001, // 380
0b11000100100, // 381
0b11011001110, // 382
0b01010111011, // 383
0b10000001101, // 384
0b00001111000, // 385
0b00010010010, // 386
0b10011100111, // 387
0b00101000110, // 388
0b10100110011, // 389
0b10111011001, // 390
0b00110101100, // 391
0b01011101110, // 392
0b11010011011, // 393
0b11001110001, // 394
0b01000000100, // 395
0b11110100101, // 396
0b01111010000, // 397
0b01100111010, // 398
0b11101001111, // 399
0b10110111110, // 400
0b00111001011, // 401
0b00100100001, // 402
0b10101010100, // 403
0b00011110101, // 404
0b10010000000, // 405
0b10001101010, // 406
0b00000011111, // 407
0b01101011101, // 408
0b11100101000, // 409
0b11111000010, // 410
0b01110110111, // 411
0b11000010110, // 412
0b01001100011, // 413
0b01010001001, // 414
0b11011111100, // 415
0b11101101011, // 416
0b01100011110, // 417
0b01111110100, // 418
0b11110000001, // 419
0b01000100000, // 420
0b11001010101, // 421
0b11010111111, // 422
0b01011001010, // 423
0b00110001000, // 424
0b10111111101, // 425
0b10100010111, // 426
0b00101100010, // 427
0b10011000011, // 428
0b00010110110, // 429
0b00001011100, // 430
0b10000101001, // 431
0b11011011000, // 432
0b01010101101, // 433
0b01001000111, // 434
0b11000110010, // 435
0b01110010011, // 436
0b11111100110, // 437
0b11100001100, // 438
0b01101111001, // 439
0b00000111011, // 440
0b10001001110, // 441
0b10010100100, // 442
0b00011010001, // 443
0b10101110000, // 444
0b00100000101, // 445
0b00111101111, // 446
0b10110011010, // 447
0b01011000001, // 448
0b11010110100, // 449
0b11001011110, // 450
0b01000101011, // 451
0b11110001010, // 452
0b01111111111, // 453
0b01100010101, // 454
0b11101100000, // 455
0b10000100010, // 456
0b00001010111, // 457
0b00010111101, // 458
0b10011001000, // 459
0b00101101001, // 460
0b10100011100, // 461
0b10111110110, // 462
0b00110000011, // 463
0b01101110010, // 464
0b11100000111, // 465
0b11111101101, // 466
0b01110011000, // 467
0b11000111001, // 468
0b01001001100, // 469
0b01010100110, // 470
0b11011010011, // 471
0b10110010001, // 472
0b00111100100, // 473
0b00100001110, // 474
0b10101111011, // 475
0b00011011010, // 476
0b10010101111, // 477
0b10001000101, // 478
0b00000110000, // 479
0b00110100111, // 480
0b10111010010, // 481
0b10100111000, // 482
0b00101001101, // 483
0b10011101100, // 484
0b00010011001, // 485
0b00001110011, // 486
0b10000000110, // 487
0b11101000100, // 488
0b01100110001, // 489
0b01111011011, // 490
0b11110101110, // 491
0b01000001111, // 492
0b11001111010, // 493
0b11010010000, // 494
0b01011100101, // 495
0b00000010100, // 496
0b10001100001, // 497
0b10010001011, // 498
0b00011111110, // 499
0b10101011111, // 500
0b00100101010, // 501
0b00111000000, // 502
0b10110110101, // 503
0b11011110111, // 504
0b01010000010, // 505
0b01001101000, // 506
0b11000011101, // 507
0b01110111100, // 508
0b11111001001, // 509
0b11100100011, // 510
0b01101010110 // 511
};
uint32_t dcs_word(uint32_t code) {
code &= 511;
return (dcs_parity[code] << 12) | (0b100 << 9) | code;
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __DCS_H_
#define __DCS_H_
#include <memory>
#define DCS_CODES_NB 512
namespace dcs {
uint32_t dcs_word(uint32_t code);
}
#endif/*__DCS_H_*/

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include "ui_navigation.hpp"
#include "encoders.hpp"
using namespace portapack;
namespace encoders {
size_t make_bitstream(std::string& fragments) {
uint8_t byte = 0;
size_t bitstream_length = 0;
uint8_t * bitstream = shared_memory.bb_data.data;
for (auto c : fragments) {
byte <<= 1;
if (c != '0')
byte |= 1;
if ((bitstream_length & 7) == 7)
bitstream[bitstream_length >> 3] = byte;
bitstream_length++;
}
// Finish last byte if needed
size_t padding = 8 - (bitstream_length & 7);
if (padding != 8) {
byte <<= padding;
bitstream[(bitstream_length + padding - 1) >> 3] = byte;
padding++;
}
return bitstream_length;
}
void bitstream_append(size_t& bitstream_length, uint32_t bit_count, uint32_t bits) {
uint8_t * bitstream = shared_memory.bb_data.data;
uint32_t bit_mask = 1 << (bit_count - 1);
uint32_t bit_index;
uint8_t byte = 0;
if (bitstream_length & 7)
byte = bitstream[bitstream_length >> 3];
bit_index = 7 - (bitstream_length & 7);
for (size_t i = 0; i < bit_count; i++) {
if (bits & bit_mask)
byte |= (1 << bit_index);
if (!bit_index) {
bitstream[bitstream_length >> 3] = byte;
byte = 0;
}
bit_index = (bit_index - 1) & 7;
bits <<= 1;
bitstream_length++;
}
bitstream[bitstream_length >> 3] = byte;
}
} /* namespace encoders */

View File

@@ -0,0 +1,228 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <vector>
#include <cstring>
#include <string>
#ifndef __ENCODERS_H__
#define __ENCODERS_H__
namespace encoders {
#define ENC_TYPES_COUNT 14
#define OOK_SAMPLERATE 2280000U
#define ENCODER_UM3750 8
size_t make_bitstream(std::string& fragments);
void bitstream_append(size_t& bitstream_length, uint32_t bit_count, uint32_t bits);
struct encoder_def_t {
char name[16]; // Encoder chip ref/name
char address_symbols[8]; // List of possible symbols like "01", "01F"...
char data_symbols[8]; // Same
uint16_t clk_per_symbol; // Oscillator periods per symbol
uint16_t clk_per_fragment; // Oscillator periods per symbol fragment (state)
char bit_format[4][20]; // List of fragments for each symbol in previous *_symbols list order
uint8_t word_length; // Total # of symbols (not counting sync)
char word_format[32]; // A for Address, D for Data, S for sync
char sync[64]; // Like bit_format
uint32_t default_speed; // Default encoder clk frequency (often set by shitty resistor)
uint8_t repeat_min; // Minimum repeat count
uint16_t pause_symbols; // Length of pause between repeats in symbols
};
// Warning ! If this is changed, make sure that ENCODER_UM3750 is still valid !
constexpr encoder_def_t encoder_defs[ENC_TYPES_COUNT] = {
// PT2260-R2
{
"2260-R2",
"01F", "01",
1024, 128,
{ "10001000", "11101110", "10001110" },
12, "AAAAAAAAAADDS",
"10000000000000000000000000000000",
150000, 2,
0
},
// PT2260-R4
{
"2260-R4",
"01F", "01",
1024, 128,
{ "10001000", "11101110", "10001110" },
12, "AAAAAAAADDDDS",
"10000000000000000000000000000000",
150000, 2,
0
},
// PT2262
{
"2262 ",
"01F", "01F",
32, 4,
{ "10001000", "11101110", "10001110" },
12, "AAAAAAAAAAAAS",
"10000000000000000000000000000000",
20000, 4,
0
},
// 16-bit ?
{
"16-bit ",
"01", "01",
32, 8,
{ "1110", "1000" }, // Opposite ?
16, "AAAAAAAAAAAAAAAAS",
"100000000000000000000",
25000, 50,
0 // ?
},
// RT1527
{
"1527 ",
"01", "01",
128, 32,
{ "1000", "1110" },
24, "SAAAAAAAAAAAAAAAAAAAADDDD",
"10000000000000000000000000000000",
100000, 4,
10 // ?
},
// HK526E
{
"526E ",
"01", "01",
24, 8,
{ "110", "100" },
12, "AAAAAAAAAAAA",
"",
20000, 4,
10 // ?
},
// HT12E
{
"12E ",
"01", "01",
3, 1,
{ "011", "001" },
12, "SAAAAAAAADDDD",
"0000000000000000000000000000000000001",
3000, 4,
10 // ?
},
// VD5026 13 bits ?
{
"5026 ",
"0123", "0123",
128, 8,
{ "1000000010000000", "1111111011111110", "1111111010000000", "1000000011111110" },
12, "SAAAAAAAAAAAA",
"000000000000000000000000000000000000000000000001", // ?
100000, 4,
10 // ?
},
// UM3750
{
"UM3750 ",
"01", "01",
96, 32,
{ "011", "001" },
12, "SAAAAAAAAAAAA",
"001",
100000, 4,
(3 * 12) - 6 // Compensates for pause delay bug in proc_ook
},
// UM3758
{
"UM3758 ",
"01F", "01",
96, 16,
{ "011011", "001001", "011001" },
18, "SAAAAAAAAAADDDDDDDD",
"1",
160000, 4,
10 // ?
},
// BA5104
{
"BA5104 ",
"01", "01",
3072, 768,
{ "1000", "1110" },
9, "SDDAAAAAAA",
"",
455000, 4,
10 // ?
},
// MC145026
{
"145026 ",
"01F", "01",
16, 1,
{ "0111111101111111", "0100000001000000", "0111111101000000" },
9, "SAAAAADDDD",
"000000000000000000",
455000, 2,
2
},
// HT6*** TODO: Add individual variations
{
"HT6*** ",
"01F", "01",
198, 33,
{ "011011", "001001", "001011" },
18, "SAAAAAAAAAAAADDDDDD",
"0000000000000000000000000000000000001011001011001",
80000, 3,
10 // ?
},
// TC9148
{
"TC9148 ",
"01", "01",
48, 12,
{ "1000", "1110", },
12, "AAAAAAAAAAAA",
"",
455000, 3,
10 // ?
}
};
} /* namespace encoders */
#endif/*__ENCODERS_H__*/

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "lcr.hpp"
#include "string_format.hpp"
namespace lcr {
std::string generate_message(std::string rgsb, std::vector<std::string> litterals, size_t option_ec) {
const std::string ec_lut[4] = { "A", "J", "N", "S" }; // Eclairage (Auto, Jour, Nuit)
char eom[3] = { 3, 0, 0 }; // EOM and space for checksum
uint8_t i;
std::string lcr_message { 127, 127, 127, 127, 127, 127, 127, 5 }; // 5/15 ? Modem sync and SOM
char checksum = 0;
// Pad litterals to 7 chars (not required ?)
for (auto & litteral : litterals)
while (litteral.length() < 7)
litteral += ' ';
// Compose LCR message
lcr_message += rgsb;
lcr_message += "PA ";
i = 1;
for (auto & litteral : litterals) {
lcr_message += "AM=";
lcr_message += to_string_dec_uint(i, 1);
lcr_message += " AF=\"";
lcr_message += litteral;
lcr_message += "\" CL=0 ";
i++;
}
lcr_message += "EC=";
lcr_message += ec_lut[option_ec];
lcr_message += " SAB=0";
// Checksum
i = 7; // Skip modem sync
while (lcr_message[i])
checksum ^= lcr_message[i++];
checksum ^= eom[0]; // EOM char
checksum &= 0x7F; // Trim
eom[1] = checksum;
lcr_message += eom;
return lcr_message;
}
} /* namespace lcr */

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include <cstring>
#include <string>
#include <vector>
#ifndef __LCR_H__
#define __LCR_H__
namespace lcr {
std::string generate_message(std::string rgsb, std::vector<std::string> litterals, size_t option_ec);
} /* namespace lcr */
#endif/*__LCR_H__*/

View File

@@ -0,0 +1,119 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "modems.hpp"
#include "serializer.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
namespace modems {
void generate_data(const std::string& in_message, uint16_t * out_data) {
uint8_t parity_init, parity, bits, bit, cur_byte;
uint16_t ordered_word;
size_t bytes;
serial_format_t serial_format = persistent_memory::serial_format();
size_t message_length = in_message.length();
if (serial_format.parity == ODD)
parity_init = 1;
else
parity_init = 0;
uint8_t data_bits = serial_format.data_bits;
for (bytes = 0; bytes < message_length; bytes++) {
parity = parity_init;
cur_byte = in_message[bytes];
bit = 0;
if (serial_format.bit_order == MSB_FIRST) {
ordered_word = cur_byte;
for (bits = 0; bits < data_bits; bits++) {
bit = (cur_byte >> bits) & 1; // Get LSB
parity += bit;
}
} else {
ordered_word = 0;
for (bits = 0; bits < data_bits; bits++) {
bit = (cur_byte >> bits) & 1; // Get LSB
parity += bit;
ordered_word |= (bit << ((data_bits - 1) - bits)); // Set MSB
}
}
if (serial_format.parity) {
ordered_word <<= 1;
ordered_word |= (parity & 1);
}
for (bits = 0; bits < serial_format.stop_bits; bits++) {
ordered_word <<= 1;
ordered_word |= 1;
}
out_data[bytes] = ordered_word;
}
out_data[bytes] = 0; // End marker
}
// This accepts a word with start and stop bits removed !
uint32_t deframe_word(uint32_t raw_word) {
uint32_t cur_bit, deframed_word { 0 };
size_t bit;
serial_format_t serial_format = persistent_memory::serial_format();
/*if (serial_format.parity == ODD)
parity = 1;
else
parity = 0;*/
size_t data_bits = serial_format.data_bits;
// Ignore parity for now
if (serial_format.parity)
raw_word >>= 1;
if (serial_format.bit_order == LSB_FIRST) {
// Reverse data bits
for (bit = 0; bit < data_bits; bit++) {
cur_bit = raw_word & 1;
deframed_word <<= 1;
deframed_word |= cur_bit;
//parity += cur_bit;
raw_word >>= 1;
}
return deframed_word;
} else
return raw_word;
}
} /* namespace modems */

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui.hpp"
#include <cstring>
#include <string>
#ifndef __MODEMS_H__
#define __MODEMS_H__
namespace modems {
#define MODEM_DEF_COUNT 7
#define AFSK_TX_SAMPLERATE 1536000U
enum ModemModulation {
AFSK = 0,
FSK,
PSK,
AM // SSB
};
struct modem_def_t {
char name[16];
ModemModulation modulation;
uint16_t mark_freq;
uint16_t space_freq;
uint16_t baudrate;
};
constexpr modem_def_t modem_defs[MODEM_DEF_COUNT] = {
{ "Bell202", AFSK, 1200, 2200, 1200 },
{ "Bell103", AFSK, 1270, 1070, 300 },
{ "V21", AFSK, 980, 1180, 300 },
{ "V23 M1", AFSK, 1300, 1700, 600 },
{ "V23 M2", AFSK, 1300, 2100, 1200 },
{ "RTTY US", AM, 2295, 2125, 45 },
{ "RTTY EU", AM, 2125, 1955, 45 }
};
void generate_data(const std::string& in_message, uint16_t * out_data);
uint32_t deframe_word(uint32_t raw_word);
} /* namespace modems */
#endif/*__MODEMS_H__*/

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "rds.hpp"
#include "portapack_shared_memory.hpp"
// RDS infos:
// One frame = X groups (as necessary)
// One group = 4 blocks = 4 * 26 bits
// One block = 26 bits (16 bits data + 10 bits checkword)
// Sent MSB first
namespace rds {
uint32_t make_block(uint32_t data, uint16_t offset) {
uint16_t CRC = 0;
uint8_t bit;
for (uint8_t i = 0; i < 16; i++) {
bit = (((data << i) & 0x8000) >> 15) ^ (CRC >> 9);
if (bit) CRC ^= 0b0011011100;
CRC = ((CRC << 1) | bit) & 0x3FF;
}
return (data << 10) | (CRC ^ offset);
}
// Boolean to binary
uint8_t b2b(const bool in) {
if (in)
return 1;
else
return 0;
}
// Type 0B groups are like 0A groups but without alternative frequency data
RDSGroup make_0B_group(const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool TA,
const bool MS, const bool DI, const uint8_t C, const std::string chars) {
RDSGroup group;
group.block[0] = PI_code;
group.block[1] = (0x0 << 12) | (1 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | (b2b(TA) << 4) | (b2b(MS) << 3) | (b2b(DI) << 2) | (C & 3);
group.block[2] = PI_code;
group.block[3] = (chars[0] << 8) | chars[1];
return group;
}
// For RadioText, up to 64 chars with 2A, 32 chars with 2B
RDSGroup make_2A_group(const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool AB,
const uint8_t segment, const std::string chars) {
RDSGroup group;
group.block[0] = PI_code;
group.block[1] = (0x2 << 12) | (0 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | (b2b(AB) << 4) | (segment & 15);
group.block[2] = (chars[0] << 8) | chars[1];
group.block[3] = (chars[2] << 8) | chars[3];
return group;
}
// Time and date - usually one message per minute - Month: 1~12 - Day: 1~31 - Hour/Minute: 0~59 - Local offset: -12/+12 from UTC
RDSGroup make_4A_group(const uint16_t PI_code, const bool TP, const uint8_t PTY,
const uint16_t year, const uint8_t month, const uint8_t day,
const uint8_t hour, const uint8_t minute, const int8_t local_offset) {
RDSGroup group;
uint32_t L = 0;
uint32_t day_code;
if ((month == 1) || (month == 2)) L = 1;
day_code = 14956 + day + (uint32_t)((float)(year - 1900 - L) * 365.25) + uint16_t((float)((month + 1) + L * 12) * 30.6001);
group.block[0] = PI_code;
group.block[1] = (0x4 << 12) | (0 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | ((day_code & 0x18000) >> 15);
group.block[2] = ((day_code & 0x7FFF) << 1) | (hour >> 4);
group.block[3] = ((hour & 15) << 12) | ((minute & 0x3F) << 6) | (local_offset & 0x3F);
return group;
}
void gen_PSN(std::vector<RDSGroup>& frame, const std::string& psname, const RDS_flags * rds_flags) {
uint8_t c;
RDSGroup group;
frame.clear();
// 4 groups with 2 PSN characters in each
for (c = 0; c < 4; c++) {
group = make_0B_group(rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, rds_flags->TA, rds_flags->MS, rds_flags->DI, c, psname.substr(c * 2, 2));
group.block[0] = make_block(group.block[0], RDS_OFFSET_A);
group.block[1] = make_block(group.block[1], RDS_OFFSET_B);
group.block[2] = make_block(group.block[2], RDS_OFFSET_Cp); // C' !
group.block[3] = make_block(group.block[3], RDS_OFFSET_D);
frame.emplace_back(group);
}
}
void gen_RadioText(std::vector<RDSGroup>& frame, const std::string& text, const bool AB, const RDS_flags * rds_flags) {
size_t c;
//RDSGroup * groups_ptr;
std::string radiotext_buffer = text;
size_t rt_length, group_count;
RDSGroup group;
radiotext_buffer += 0x0D;
rt_length = radiotext_buffer.length();
rt_length = (rt_length + 3) & 0xFC;
group_count = rt_length >> 2; // 4 characters per group
//groups_ptr = (RDSGroup*)chHeapAlloc(0, group_count * sizeof(RDSGroup));
frame.clear();
for (c = 0; c < group_count; c++) {
group = make_2A_group(rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, AB, c, radiotext_buffer.substr(c * 4, 4));
group.block[0] = make_block(group.block[0], RDS_OFFSET_A);
group.block[1] = make_block(group.block[1], RDS_OFFSET_B);
group.block[2] = make_block(group.block[2], RDS_OFFSET_C);
group.block[3] = make_block(group.block[3], RDS_OFFSET_D);
frame.emplace_back(group);
}
}
void gen_ClockTime(std::vector<RDSGroup>& frame, const RDS_flags * rds_flags,
const uint16_t year, const uint8_t month, const uint8_t day,
const uint8_t hour, const uint8_t minute, const int8_t local_offset) {
RDSGroup group;
group = make_4A_group(rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, year, month, day, hour, minute, local_offset);
// Generate checkbits for each block
group.block[0] = make_block(group.block[0], RDS_OFFSET_A);
group.block[1] = make_block(group.block[1], RDS_OFFSET_B);
group.block[2] = make_block(group.block[2], RDS_OFFSET_C);
group.block[3] = make_block(group.block[3], RDS_OFFSET_D);
frame.clear();
frame.emplace_back(group);
}
} /* namespace rds */

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* 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, 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; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <string>
#include <vector>
#include "ch.h"
#ifndef __RDS_H__
#define __RDS_H__
namespace rds {
#define RDS_OFFSET_A 0b0011111100
#define RDS_OFFSET_B 0b0110011000
#define RDS_OFFSET_C 0b0101101000
#define RDS_OFFSET_Cp 0b1101010000
#define RDS_OFFSET_D 0b0110110100
struct RDS_flags {
uint16_t PI_code;
uint8_t PTY;
uint8_t DI;
bool TP;
bool TA;
bool MS;
};
struct RDSGroup {
uint32_t block[4];
};
uint32_t make_block(uint32_t blockdata, uint16_t offset);
uint8_t b2b(const bool in);
RDSGroup make_0B_group(const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool TA,
const bool MS, const bool DI, const uint8_t C, const std::string chars);
RDSGroup make_2A_group(const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool AB,
const uint8_t segment, const std::string chars);
RDSGroup make_4A_group(const uint16_t PI_code, const bool TP, const uint8_t PTY,
const uint16_t year, const uint8_t month, const uint8_t day,
const uint8_t hour, const uint8_t minute, const int8_t local_offset);
void gen_PSN(std::vector<RDSGroup>& frame, const std::string& psname, const RDS_flags * rds_flags);
void gen_RadioText(std::vector<RDSGroup>& frame, const std::string& text, const bool AB, const RDS_flags * rds_flags);
void gen_ClockTime(std::vector<RDSGroup>& frame, const RDS_flags * rds_flags,
const uint16_t year, const uint8_t month, const uint8_t day,
const uint8_t hour, const uint8_t minute, const int8_t local_offset);
} /* namespace rds */
#endif/*__RDS_H__*/