mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-15 06:07:42 +00:00
Formatted code (#1007)
* Updated style * Updated files * fixed new line * Updated spacing * File fix WIP * Updated to clang 13 * updated comment style * Removed old comment code
This commit is contained in:
@@ -29,24 +29,20 @@ 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);
|
||||
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;
|
||||
|
||||
|
||||
frame.make_ui_frame(address, 0x03, protocol_id_t::NO_LAYER3, payload);
|
||||
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 */
|
||||
|
@@ -28,11 +28,13 @@
|
||||
|
||||
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);
|
||||
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__*/
|
||||
#endif /*__APRS_H__*/
|
||||
|
@@ -26,109 +26,101 @@
|
||||
|
||||
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::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++;
|
||||
}
|
||||
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;
|
||||
void AX25Frame::add_byte(uint8_t byte, bool is_flag, bool is_data) {
|
||||
bool bit;
|
||||
|
||||
if (is_data)
|
||||
crc_ccitt.process_byte(byte);
|
||||
if (is_data)
|
||||
crc_ccitt.process_byte(byte);
|
||||
|
||||
for (uint32_t i = 0; i < 8; i++)
|
||||
{
|
||||
bit = (byte >> i) & 1;
|
||||
for (uint32_t i = 0; i < 8; i++) {
|
||||
bit = (byte >> i) & 1;
|
||||
|
||||
NRZI_add_bit(bit);
|
||||
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;
|
||||
}
|
||||
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::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);
|
||||
add_byte(AX25_FLAG, true, false);
|
||||
};
|
||||
|
||||
void AX25Frame::add_data(uint8_t byte) {
|
||||
add_byte(byte, false, true);
|
||||
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);
|
||||
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();
|
||||
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 */
|
||||
|
@@ -33,37 +33,36 @@
|
||||
namespace ax25 {
|
||||
|
||||
enum protocol_id_t {
|
||||
X25_PLP = 0x01,
|
||||
COMP_TCPIP = 0x06,
|
||||
UNCOMP_TCPIP = 0x07,
|
||||
SEG_FRAG = 0x08,
|
||||
FLEXNET = 0xCE,
|
||||
NO_LAYER3 = 0xF0
|
||||
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 };
|
||||
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__*/
|
||||
#endif /*__AX25_H__*/
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -24,131 +24,129 @@
|
||||
#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];
|
||||
size_t c;
|
||||
const encoder_def_t* um3750_def;
|
||||
uint8_t bits[12];
|
||||
std::string ep_fragments;
|
||||
// char ep_message[13] = { 0 };
|
||||
|
||||
// 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';
|
||||
// Repeated 2x 26 times
|
||||
// Whole frame + space = 128ms, data only = 64ms
|
||||
|
||||
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);
|
||||
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 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;
|
||||
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);
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -28,24 +28,22 @@
|
||||
|
||||
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 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
|
||||
|
||||
#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;
|
||||
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);
|
||||
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);
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -33,4 +33,4 @@ uint32_t dcs_word(uint32_t code);
|
||||
|
||||
}
|
||||
|
||||
#endif/*__DCS_H_*/
|
||||
#endif /*__DCS_H_*/
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -29,59 +29,59 @@ 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;
|
||||
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;
|
||||
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 */
|
||||
|
@@ -29,200 +29,253 @@
|
||||
|
||||
namespace encoders {
|
||||
|
||||
#define ENC_TYPES_COUNT 14
|
||||
#define OOK_SAMPLERATE 2280000U
|
||||
#define ENC_TYPES_COUNT 14
|
||||
#define OOK_SAMPLERATE 2280000U
|
||||
|
||||
#define ENCODER_UM3750 8
|
||||
#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);
|
||||
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
|
||||
};
|
||||
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
|
||||
},
|
||||
// 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
|
||||
},
|
||||
// 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
|
||||
},
|
||||
// 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 // ?
|
||||
},
|
||||
// 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,
|
||||
0
|
||||
},
|
||||
// RT1527
|
||||
{
|
||||
"1527 ",
|
||||
"01",
|
||||
"01",
|
||||
128,
|
||||
32,
|
||||
{"1000", "1110"},
|
||||
24,
|
||||
"SAAAAAAAAAAAAAAAAAAAADDDD",
|
||||
"10000000000000000000000000000000",
|
||||
100000,
|
||||
4,
|
||||
0},
|
||||
|
||||
// HK526E
|
||||
{
|
||||
"526E ",
|
||||
"01", "01",
|
||||
24, 8,
|
||||
{ "110", "100" },
|
||||
12, "AAAAAAAAAAAA",
|
||||
"",
|
||||
20000, 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 // ?
|
||||
},
|
||||
// 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 // ?
|
||||
},
|
||||
// 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
|
||||
},
|
||||
// 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 // ?
|
||||
},
|
||||
// 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 // ?
|
||||
},
|
||||
// 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
|
||||
},
|
||||
// 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 // ?
|
||||
},
|
||||
// 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 // ?
|
||||
}
|
||||
};
|
||||
// TC9148
|
||||
{
|
||||
"TC9148 ",
|
||||
"01",
|
||||
"01",
|
||||
48,
|
||||
12,
|
||||
{
|
||||
"1000",
|
||||
"1110",
|
||||
},
|
||||
12,
|
||||
"AAAAAAAAAAAA",
|
||||
"",
|
||||
455000,
|
||||
3,
|
||||
10 // ?
|
||||
}};
|
||||
|
||||
} /* namespace encoders */
|
||||
|
||||
#endif/*__ENCODERS_H__*/
|
||||
#endif /*__ENCODERS_H__*/
|
||||
|
@@ -26,46 +26,46 @@
|
||||
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;
|
||||
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 */
|
||||
|
@@ -34,4 +34,4 @@ std::string generate_message(std::string rgsb, std::vector<std::string> litteral
|
||||
|
||||
} /* namespace lcr */
|
||||
|
||||
#endif/*__LCR_H__*/
|
||||
#endif /*__LCR_H__*/
|
||||
|
@@ -29,91 +29,91 @@ 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;
|
||||
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;
|
||||
|
||||
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
|
||||
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;*/
|
||||
uint32_t cur_bit, deframed_word{0};
|
||||
size_t bit;
|
||||
|
||||
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;
|
||||
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 */
|
||||
|
@@ -28,38 +28,37 @@
|
||||
#define __MODEMS_H__
|
||||
|
||||
namespace modems {
|
||||
|
||||
|
||||
#define MODEM_DEF_COUNT 7
|
||||
#define AFSK_TX_SAMPLERATE 1536000U
|
||||
|
||||
enum ModemModulation {
|
||||
AFSK = 0,
|
||||
FSK,
|
||||
PSK,
|
||||
AM // SSB
|
||||
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;
|
||||
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 }
|
||||
};
|
||||
{"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);
|
||||
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__*/
|
||||
#endif /*__MODEMS_H__*/
|
||||
|
@@ -35,129 +35,123 @@ 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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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_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;
|
||||
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
|
||||
radiotext_buffer += 0x0D;
|
||||
rt_length = radiotext_buffer.length();
|
||||
rt_length = (rt_length + 3) & 0xFC;
|
||||
|
||||
//groups_ptr = (RDSGroup*)chHeapAlloc(0, group_count * sizeof(RDSGroup));
|
||||
group_count = rt_length >> 2; // 4 characters per group
|
||||
|
||||
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);
|
||||
}
|
||||
// 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);
|
||||
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 */
|
||||
|
@@ -28,43 +28,37 @@
|
||||
#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
|
||||
|
||||
#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;
|
||||
uint16_t PI_code;
|
||||
uint8_t PTY;
|
||||
uint8_t DI;
|
||||
bool TP;
|
||||
bool TA;
|
||||
bool MS;
|
||||
};
|
||||
|
||||
struct RDSGroup {
|
||||
uint32_t block[4];
|
||||
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);
|
||||
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);
|
||||
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__*/
|
||||
#endif /*__RDS_H__*/
|
||||
|
Reference in New Issue
Block a user