Add software
This commit is contained in:
		@@ -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 */
 | 
			
		||||
@@ -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__*/
 | 
			
		||||
@@ -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 */
 | 
			
		||||
@@ -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__*/
 | 
			
		||||
							
								
								
									
										154
									
								
								Software/portapack-mayhem/firmware/application/protocols/bht.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								Software/portapack-mayhem/firmware/application/protocols/bht.cpp
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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);
 | 
			
		||||
							
								
								
									
										547
									
								
								Software/portapack-mayhem/firmware/application/protocols/dcs.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										547
									
								
								Software/portapack-mayhem/firmware/application/protocols/dcs.cpp
									
									
									
									
									
										Normal 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -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_*/
 | 
			
		||||
@@ -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 */
 | 
			
		||||
@@ -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__*/
 | 
			
		||||
@@ -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 */
 | 
			
		||||
@@ -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__*/
 | 
			
		||||
@@ -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 */
 | 
			
		||||
@@ -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__*/
 | 
			
		||||
							
								
								
									
										163
									
								
								Software/portapack-mayhem/firmware/application/protocols/rds.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								Software/portapack-mayhem/firmware/application/protocols/rds.cpp
									
									
									
									
									
										Normal 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 */
 | 
			
		||||
@@ -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__*/
 | 
			
		||||
		Reference in New Issue
	
	Block a user