Merge remote-tracking branch 'upstream/master'

Conflicts:
	firmware/Makefile
	firmware/application/Makefile
	firmware/application/event_m0.cpp
	firmware/application/ui_setup.cpp
	firmware/application/ui_setup.hpp
	firmware/baseband/baseband_thread.cpp
	firmware/baseband/baseband_thread.hpp
	firmware/bootstrap/CMakeLists.txt
	firmware/common/message.hpp
	firmware/common/portapack_shared_memory.hpp
	hardware/.gitignore
This commit is contained in:
furrtek
2016-07-25 16:35:42 +02:00
138 changed files with 17603 additions and 1930 deletions

View File

@@ -114,6 +114,13 @@ bool CPLD::verify(
return block_0_success && block_1_success;
}
uint32_t CPLD::crc() {
crc_t crc { 0x04c11db7, 0xffffffff, 0xffffffff };
block_crc(0, 3328, crc);
block_crc(1, 512, crc);
return crc.checksum();
}
void CPLD::sector_select(const uint16_t id) {
shift_ir(0x203); // Sector select
jtag.runtest_tck(93); // 5us
@@ -219,6 +226,17 @@ bool CPLD::is_blank_block(const uint16_t id, const size_t count) {
return success;
}
void CPLD::block_crc(const uint16_t id, const size_t count, crc_t& crc) {
sector_select(id);
shift_ir(0x205); // Read
jtag.runtest_tck(93); // 5us
for(size_t i=0; i<count; i++) {
const uint16_t from_device = jtag.shift_dr(16, 0xffff);
crc.process_bytes(&from_device, sizeof(from_device));
}
}
bool CPLD::is_blank() {
const auto block_0_blank = is_blank_block(0x0000, 3328);
const auto block_1_blank = is_blank_block(0x0001, 512);

View File

@@ -23,6 +23,7 @@
#define __CPLD_MAX5_H__
#include "jtag.hpp"
#include "crc.hpp"
#include <cstdint>
#include <cstddef>
@@ -75,6 +76,8 @@ public:
bool is_blank();
uint32_t crc();
std::pair<bool, uint8_t> boundary_scan();
enum class Instruction {
@@ -91,11 +94,6 @@ public:
shift_ir(static_cast<uint32_t>(instruction));
}
template<size_t N>
void shift_dr(std::bitset<N>& bits) {
jtag.shift_dr(bits);
}
private:
jtag::JTAG& jtag;
@@ -135,6 +133,9 @@ private:
bool is_blank_block(const uint16_t id, const size_t count);
using crc_t = CRC<32, true, true>;
void block_crc(const uint16_t id, const size_t count, crc_t& crc);
const uint32_t IDCODE = 0b00000010000010100101000011011101;
const size_t IR_LENGTH = 10;

View File

@@ -0,0 +1,179 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
*
* 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 "cpld_xilinx.hpp"
namespace cpld {
namespace xilinx {
void XC2C64A::write_sram(const verify_blocks_t& blocks) {
tap.set_repeat(0);
tap.set_end_ir(state_t::run_test_idle);
tap.set_end_dr(state_t::run_test_idle);
reset();
enable();
shift_ir(instruction_t::ISC_WRITE);
for(const auto& block : blocks) {
tap.state(state_t::shift_dr);
tap.shift({ block.data.data(), block_length }, false);
tap.shift({ &block.id, block_id_length }, true);
tap.state(state_t::run_test_idle);
}
disable();
bypass();
tap.state(state_t::test_logic_reset);
}
bool XC2C64A::verify_sram(const verify_blocks_t& blocks) {
tap.set_repeat(0);
tap.set_end_ir(state_t::run_test_idle);
tap.set_end_dr(state_t::run_test_idle);
reset();
enable();
shift_ir(instruction_t::ISC_SRAM_READ);
// Prime the operation with a read of an empty row.
const jtag::tap::bits_t empty_row { block_length };
tap.state(state_t::shift_dr);
tap.shift(empty_row, false);
auto error = false;
for(const auto& block : blocks) {
tap.shift({ &block.id, block_id_length }, true);
tap.state(state_t::run_test_idle);
tap.state(state_t::shift_dr);
error |= tap.shift(empty_row, { block.data.data(), block_length }, { block.mask.data(), block_length }, false);
}
// Redundant operation to finish the row.
tap.shift({ &blocks[0].id, block_id_length }, true);
tap.state(state_t::run_test_idle);
tap.set_end_dr(state_t::run_test_idle);
disable();
bypass();
tap.state(state_t::test_logic_reset);
return !error;
}
bool XC2C64A::verify_eeprom(const verify_blocks_t& blocks) {
tap.set_repeat(0);
tap.set_end_ir(state_t::run_test_idle);
tap.set_end_dr(state_t::run_test_idle);
reset();
bypass();
enable();
shift_ir(instruction_t::ISC_READ);
const jtag::tap::bits_t empty_row { block_length };
auto error = false;
for(const auto& block : blocks) {
tap.set_end_dr(state_t::pause_dr);
tap.shift_dr({ &block.id, block_id_length });
tap.set_end_ir(state_t::run_test_idle);
tap.wait(state_t::pause_dr, state_t::pause_dr, 20);
tap.set_end_ir(state_t::run_test_idle);
tap.wait(state_t::run_test_idle, state_t::run_test_idle, 100);
error |= tap.shift_dr(empty_row, { block.data.data(), block_length }, { block.mask.data(), block_length });
tap.wait(state_t::run_test_idle, state_t::run_test_idle, 100);
}
disable();
bypass();
tap.state(state_t::test_logic_reset);
return !error;
}
void XC2C64A::init_from_eeprom() {
tap.set_repeat(0);
tap.set_end_ir(state_t::run_test_idle);
tap.set_end_dr(state_t::run_test_idle);
reset();
enable();
discharge();
init();
disable();
bypass();
tap.state(state_t::test_logic_reset);
}
bool XC2C64A::shift_ir(const instruction_t instruction) {
const ir_t ir_buffer = toUType(instruction);
const jtag::tap::bits_t bits { &ir_buffer, ir_length };
return tap.shift_ir(bits);
}
void XC2C64A::reset() {
tap.state(state_t::test_logic_reset);
tap.state(state_t::run_test_idle);
}
void XC2C64A::enable() {
shift_ir(instruction_t::ISC_ENABLE);
tap.wait(state_t::run_test_idle, state_t::run_test_idle, 800);
}
void XC2C64A::enable_otf() {
shift_ir(instruction_t::ISC_ENABLE_OTF);
}
void XC2C64A::discharge() {
shift_ir(instruction_t::ISC_INIT);
tap.wait(state_t::run_test_idle, state_t::run_test_idle, 20);
}
void XC2C64A::init() {
tap.set_end_ir(state_t::update_ir);
shift_ir(instruction_t::ISC_INIT);
tap.set_end_ir(state_t::run_test_idle);
tap.state(state_t::capture_dr);
tap.wait(state_t::run_test_idle, state_t::run_test_idle, 800);
}
void XC2C64A::disable() {
shift_ir(instruction_t::ISC_DISABLE);
tap.wait(state_t::run_test_idle, state_t::run_test_idle, 100);
}
bool XC2C64A::bypass() {
return shift_ir(instruction_t::BYPASS);
}
} /* namespace xilinx */
} /* namespace cpld */

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
*
* 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 __CPLD_XILINX_H__
#define __CPLD_XILINX_H__
#include "jtag_tap.hpp"
#include "utility.hpp"
#include <cstdint>
#include <cstddef>
#include <array>
namespace cpld {
namespace xilinx {
using jtag::tap::state_t;
class XC2C64A {
public:
using block_id_t = uint8_t;
static constexpr size_t block_length = 274;
static constexpr size_t blocks_count = 98;
static constexpr size_t block_bytes = (block_length + 7) >> 3;
struct verify_block_t {
block_id_t id;
std::array<uint8_t, block_bytes> data;
std::array<uint8_t, block_bytes> mask;
};
struct program_block_t {
block_id_t id;
std::array<uint8_t, block_bytes> data;
};
using verify_blocks_t = std::array<verify_block_t, blocks_count>;
constexpr XC2C64A(
jtag::Target& jtag_interface
) : tap { jtag_interface }
{
}
void write_sram(const verify_blocks_t& blocks);
bool verify_sram(const verify_blocks_t& blocks);
bool verify_eeprom(const verify_blocks_t& blocks);
void init_from_eeprom();
private:
static constexpr size_t idcode_length = 32;
using idcode_t = uint32_t;
static constexpr size_t ir_length = 8;
static constexpr size_t block_id_length = 7;
static constexpr idcode_t idcode = 0x06e58093;
static constexpr idcode_t idcode_mask = 0x0fff8fff;
using ir_t = uint8_t;
jtag::tap::TAPMachine tap;
enum class instruction_t : ir_t {
INTEST = 0b00000010, // -> boundary-scan
BYPASS = 0b11111111, // -> bypass
SAMPLE = 0b00000011, // -> boundary-scan
EXTEST = 0b00000000, // -> boundary-scan
IDCODE = 0b00000001, // -> device ID
USERCODE = 0b11111101, // -> device ID
HIGHZ = 0b11111100, // -> bypass
ISC_ENABLE_CLAMP = 0b11101001, // -> ISC shift
ISC_ENABLE_OTF = 0b11100100, // -> ISC shift
ISC_ENABLE = 0b11101000, // -> ISC shift
ISC_SRAM_READ = 0b11100111, // -> ISC shift
ISC_WRITE = 0b11100110, // -> ISC shift, alias ISC_SRAM_WRITE
ISC_ERASE = 0b11101101, // -> ISC shift
ISC_PROGRAM = 0b11101010, // -> ISC shift
ISC_READ = 0b11101110, // -> ISC shift, alias ISC_VERIFY
ISC_INIT = 0b11110000, // -> ISC shift
ISC_DISABLE = 0b11000000, // -> ISC shift
TEST_ENABLE = 0b00010001, // alias Private1
BULKPROG = 0b00010010, // alias Private2
ERASE_ALL = 0b00010100, // alias Private4
MVERIFY = 0b00010011, // alias Private3
TEST_DISABLE = 0b00010101, // alias Private5
ISC_NOOP = 0b11100000, // -> bypass
};
bool shift_ir(const instruction_t instruction);
void reset();
void enable();
void enable_otf();
void discharge();
void init();
void disable();
bool bypass();
};
} /* namespace xilinx */
} /* namespace cpld */
#endif/*__CPLD_XILINX_H__*/

View File

@@ -78,27 +78,15 @@ public:
}
void process_bits(value_type bits, size_t bit_count) {
constexpr auto digits = std::numeric_limits<value_type>::digits;
constexpr auto mask = static_cast<value_type>(1) << (digits - 1);
bits <<= (std::numeric_limits<value_type>::digits - bit_count);
for(size_t i=bit_count; i>0; --i, bits <<= 1) {
process_bit(static_cast<bool>(bits & mask));
}
}
void process_bits_lsb_first(value_type bits, size_t bit_count) {
for(size_t i=bit_count; i>0; --i, bits >>= 1) {
process_bit(static_cast<bool>(bits & 0x01));
if( RevIn ) {
process_bits_lsb_first(bits, bit_count);
} else {
process_bits_msb_first(bits, bit_count);
}
}
void process_byte(const uint8_t byte) {
if( RevIn ) {
process_bits_lsb_first(byte, 8);
} else {
process_bits(byte, 8);
}
process_bits(byte, 8);
}
void process_bytes(const void* const data, const size_t length) {
@@ -147,6 +135,22 @@ private:
}
return reflection;
}
void process_bits_msb_first(value_type bits, size_t bit_count) {
constexpr auto digits = std::numeric_limits<value_type>::digits;
constexpr auto mask = static_cast<value_type>(1) << (digits - 1);
bits <<= (std::numeric_limits<value_type>::digits - bit_count);
for(size_t i=bit_count; i>0; --i, bits <<= 1) {
process_bit(static_cast<bool>(bits & mask));
}
}
void process_bits_lsb_first(value_type bits, size_t bit_count) {
for(size_t i=bit_count; i>0; --i, bits >>= 1) {
process_bit(static_cast<bool>(bits & 0x01));
}
}
};
class Adler32 {

View File

@@ -24,6 +24,8 @@
#include <ch.h>
#include <hal.h>
#include "portapack_shared_memory.hpp"
#if defined(LPC43XX_M0)
static void debug_indicate_error_init() {
// TODO: Get knowledge of LED GPIO port/bit from shared place.
@@ -75,6 +77,16 @@ void __early_init(void) {
}
void port_halt(void) {
// Copy debug panic message to M0 region.
const auto* p = dbg_panic_msg;
for(size_t i=0; i<sizeof(shared_memory.m4_panic_msg); i++) {
if( *p == 0 ) {
shared_memory.m4_panic_msg[i] = 0;
} else {
shared_memory.m4_panic_msg[i] = *(p++);
}
}
port_disable();
runtime_error();
}

View File

@@ -73,8 +73,8 @@ CommodityType Packet::commodity_type() const {
return invalid_commodity_type;
}
ManchesterFormatted Packet::symbols_formatted() const {
return format_manchester(decoder_);
FormattedSymbols Packet::symbols_formatted() const {
return format_symbols(decoder_);
}
bool Packet::crc_ok() const {

View File

@@ -68,7 +68,7 @@ public:
CommodityType commodity_type() const;
Consumption consumption() const;
ManchesterFormatted symbols_formatted() const;
FormattedSymbols symbols_formatted() const;
bool crc_ok() const;

View File

@@ -78,6 +78,11 @@ constexpr std::array<GPIO, 3> gpios_baseband_decimation {
};
constexpr GPIO gpio_baseband_q_invert = gpio[GPIO0_13];
constexpr GPIO gpio_cpld_tdo = gpio[GPIO5_18];
constexpr GPIO gpio_cpld_tck = gpio[GPIO3_0];
constexpr GPIO gpio_cpld_tms = gpio[GPIO3_4];
constexpr GPIO gpio_cpld_tdi = gpio[GPIO3_1];
/* LEDs */
constexpr LED led_usb { gpio_led_usb };

View File

@@ -22,6 +22,8 @@
#ifndef __JTAG_H__
#define __JTAG_H__
#include "jtag_target.hpp"
#include <cstdint>
#include <cstddef>
@@ -29,20 +31,6 @@
namespace jtag {
class Target {
public:
using bit_t = uint_fast8_t;
virtual ~Target() {
}
virtual void delay(const size_t n) = 0;
virtual jtag::Target::bit_t clock(
const jtag::Target::bit_t tms_value,
const jtag::Target::bit_t tdi_value
) = 0;
};
class JTAG {
public:
constexpr JTAG(
@@ -102,27 +90,6 @@ public:
return result;
}
template<size_t N>
void shift_dr(std::bitset<N>& bits) {
/* Run-Test/Idle -> Select-DR-Scan */
target.clock(1, 0);
/* Scan -> Capture -> Shift */
target.clock(0, 0);
target.clock(0, 0);
for(size_t i=0; i<bits.size(); i++) {
bits[i] = target.clock(
(i == (bits.size() - 1)) ? 1 : 0,
bits[i]
);
}
/* Exit1 -> Update */
target.clock(1, 0);
/* Update -> Run-Test/Idle */
target.clock(0, 0);
}
private:
Target& target;

View File

@@ -0,0 +1,266 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
*
* 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 "jtag_tap.hpp"
#include "utility.hpp"
#include <string>
namespace jtag {
namespace tap {
size_t bits_t::length() const {
return count;
}
bits_t::operator bool() const {
return (count > 0);
}
bool bits_t::operator[](const size_t index) const {
if( p && (index < count) ) {
const auto n = bytes() * 8 - index - 1;
const auto byte = n >> 3;
const auto bit = (n ^ 7) & 7;
return (p[byte] >> bit) & 1;
} else {
return default_value;
}
}
size_t bits_t::bytes() const {
return (count + 7) >> 3;
}
#if JTAG_TAP_DEBUG
static char nibble_to_hex_char(const uint8_t v) {
if( v < 0xa ) {
return 0x30 + v;
} else {
return 0x57 + v;
}
}
std::string to_string(const bits_t& bits) {
std::string s { std::to_string(bits.length()) + "/0x" };
for(size_t i=0; i<bytes(); i++) {
s += nibble_to_hex_char((bits.p[i] >> 4) & 0xf);
s += nibble_to_hex_char((bits.p[i] >> 0) & 0xf);
}
return s;
}
#endif
namespace {
using route_t = uint16_t;
struct entry_t {
state_t tms[2];
route_t route;
};
static_assert(sizeof(entry_t) == 4, "Unexpected size of entry_t");
using table_t = std::array<entry_t, 16>;
static_assert(sizeof(table_t) == (16 * 4), "Unexpected size of table_t");
const table_t table { {
{ state_t::run_test_idle, state_t::test_logic_reset, 0b0000000000000001 }, // test_logic_reset test_logic_reset => 1, others => 0
{ state_t::run_test_idle, state_t::select_dr_scan, 0b1111111111111101 }, // run_test_idle run_test_idle => 0, others => 1
{ state_t::capture_dr, state_t::select_ir_scan, 0b1111111000000001 }, // select_dr_scan run_test_idle..update_dr => 0, others => 1
{ state_t::shift_dr, state_t::exit1_dr, 0b1111111111101111 }, // capture_dr shift_dr => 0, others => 1
{ state_t::shift_dr, state_t::exit1_dr, 0b1111111111101111 }, // shift_dr shift_dr => 0, others => 1
{ state_t::pause_dr, state_t::update_dr, 0b1111111100111111 }, // exit1_dr pause_dr, exit2_dr => 0, others => 1
{ state_t::pause_dr, state_t::exit2_dr, 0b1111111110111111 }, // pause_dr pause_dr => 0, others => 1
{ state_t::shift_dr, state_t::update_dr, 0b1111111111101111 }, // exit2_dr shift_dr => 0, others => 1
{ state_t::run_test_idle, state_t::select_dr_scan, 0b1111111111111101 }, // update_dr run_test_idle => 0, others => 1
{ state_t::capture_ir, state_t::test_logic_reset, 0b0000000000000001 }, // select_ir_scan test_logic_reset => 1, others => 0
{ state_t::shift_ir, state_t::exit1_ir, 0b1111011111111111 }, // capture_ir shift_ir => 0, others => 1
{ state_t::shift_ir, state_t::exit1_ir, 0b1111011111111111 }, // shift_ir shift_ir => 0, others => 1
{ state_t::pause_ir, state_t::update_ir, 0b1001111111111111 }, // exit1_ir pause_ir, exit2_ir => 0, others => 1
{ state_t::pause_ir, state_t::exit2_ir, 0b1101111111111111 }, // pause_ir pause_ir => 0, others => 1
{ state_t::shift_ir, state_t::update_ir, 0b1111011111111111 }, // exit2_ir shift_ir => 0, others => 1
{ state_t::run_test_idle, state_t::select_dr_scan, 0b1111111111111101 }, // update_ir run_test_idle => 0, others => 1
} };
const std::array<const char*, 16> state_name { {
"test_logic_reset",
"run_test_idle",
"select_dr_scan",
"capture_dr",
"shift_dr",
"exit1_dr",
"pause_dr",
"exit2_dr",
"update_dr",
"select_ir_scan",
"capture_ir",
"shift_ir",
"exit1_ir",
"pause_ir",
"exit2_ir",
"update_ir",
} };
const std::array<const char*, 16> state_long_name { {
"Test-Logic-Reset",
"Run-Test/Idle",
"Select-DR-Scan",
"Capture-DR",
"Shift-DR",
"Exit1-DR",
"Pause-DR",
"Exit2-DR",
"Update-DR",
"Select-IR-Scan",
"Capture-IR",
"Shift-IR",
"Exit1-IR",
"Pause-IR",
"Exit2-IR",
"Update-IR",
} };
const entry_t& entry(const state_t state) {
return table[toUType(state)];
}
} /* namespace */
const char* c_str(const state_t state) {
return state_name[toUType(state)];
}
/* TAPState **************************************************************/
state_t TAPState::state() const {
return _state;
}
void TAPState::advance(const bool tms) {
_state = entry(_state).tms[tms];
}
bool TAPState::advance_toward(const state_t desired_state) const {
return (entry(_state).route >> toUType(desired_state)) & 1;
}
/* TAPMachine ************************************************************/
void TAPMachine::set_run_test(const uint32_t value) {
_run_test = value;
}
void TAPMachine::set_repeat(const uint8_t value) {
_repeat = value;
}
void TAPMachine::set_end_ir(const state_t state) {
_end_ir = state;
}
void TAPMachine::set_end_dr(const state_t state) {
_end_dr = state;
}
bool TAPMachine::shift_ir(const bits_t& tdi_value, const bits_t& tdo_expected, const bits_t& tdo_mask) {
return shift_data(tdi_value, tdo_expected, tdo_mask, state_t::shift_ir, _end_ir, _run_test);
}
bool TAPMachine::shift_dr(const bits_t& tdi_value, const bits_t& tdo_expected, const bits_t& tdo_mask) {
return shift_data(tdi_value, tdo_expected, tdo_mask, state_t::shift_dr, _end_dr, _run_test);
}
void TAPMachine::state(const state_t state) {
if( state == state_t::test_logic_reset ) {
for(int i=0; i<5; i++) {
clock(1);
}
} else {
advance_to_state(state);
}
}
void TAPMachine::wait(const state_t wait_state, const state_t end_state, const uint32_t wait_time) {
advance_to_state(wait_state);
delay_us(wait_time);
advance_to_state(end_state);
}
bool TAPMachine::clock(const bool tms, const bool tdi) {
tap.advance(tms);
return target.clock(tms, tdi);
}
void TAPMachine::advance_to_state(const state_t desired_state) {
while( tap.state() != desired_state ) {
const auto tms = tap.advance_toward(desired_state);
clock(tms);
}
}
void TAPMachine::delay_us(const uint32_t microseconds) {
target.delay(microseconds);
}
void TAPMachine::shift_start(const state_t state) {
advance_to_state(state);
}
bool TAPMachine::shift(const bits_t& tdi, const bits_t& tdo_expected, const bits_t& tdo_mask, const bool end_tms) {
if( tdo_expected.length() != tdo_mask.length() ) {
return false;
}
if( tdo_expected && (tdi.length() != tdo_expected.length()) ) {
return false;
}
auto tdo_error = false;
for(uint32_t i=0; i<tdi.length(); i++) {
const auto tms = end_tms & (i == (tdi.length() - 1));
const auto tdo = clock(tms, tdi[i]);
if( tdo_expected && tdo_mask ) {
tdo_error |= (tdo & tdo_mask[i]) != (tdo_expected[i] & tdo_mask[i]);
}
}
return tdo_error;
}
void TAPMachine::shift_end(const state_t end_state, const uint32_t end_delay) {
if( end_delay ) {
advance_to_state(state_t::run_test_idle);
delay_us(end_delay);
} else {
advance_to_state(end_state);
}
}
bool TAPMachine::shift_data(const bits_t& tdi, const bits_t& tdo_expected, const bits_t& tdo_mask, const state_t state, const state_t end_state, const uint32_t end_delay) {
shift_start(state);
const auto result = shift(tdi, tdo_expected, tdo_mask, true);
shift_end(end_state, end_delay);
return result;
}
} /* namespace tap */
} /* namespace jtag */

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
*
* 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 __JTAG_TAP_H__
#define __JTAG_TAP_H__
#include "jtag_target.hpp"
#include <cstdint>
#include <cstddef>
namespace jtag {
namespace tap {
class bits_t {
public:
constexpr bits_t(
) : p { nullptr },
count { 0 }
{
}
constexpr bits_t(
const size_t count,
const bool default_value = true
) : p { nullptr },
count { count },
default_value { default_value }
{
}
constexpr bits_t(
const uint8_t* const p,
const size_t count
) : p { p },
count { count }
{
}
size_t length() const;
explicit operator bool() const;
bool operator[](const size_t index) const;
private:
const uint8_t* p { nullptr };
size_t count { 0 };
bool default_value { false };
size_t bytes() const;
};
enum class state_t : uint8_t {
/* Ordinal values are important for "routes" values, and to match XSVF definitions. */
test_logic_reset = 0,
run_test_idle = 1,
select_dr_scan = 2,
capture_dr = 3,
shift_dr = 4,
exit1_dr = 5,
pause_dr = 6,
exit2_dr = 7,
update_dr = 8,
select_ir_scan = 9,
capture_ir = 10,
shift_ir = 11,
exit1_ir = 12,
pause_ir = 13,
exit2_ir = 14,
update_ir = 15,
};
class TAPState {
public:
constexpr TAPState(
) : _state { state_t::test_logic_reset }
{
}
state_t state() const;
void advance(const bool tms);
bool advance_toward(const state_t desired_state) const;
private:
state_t _state;
};
class TAPMachine {
public:
constexpr TAPMachine(
jtag::Target& target
) : target { target }
{
}
void set_run_test(const uint32_t value);
void set_repeat(const uint8_t value);
void set_end_ir(const state_t state);
void set_end_dr(const state_t state);
bool shift(const bits_t& tdi, const bool end_tms) {
return shift(tdi, {}, {}, end_tms);
}
bool shift(const bits_t& tdi, const bits_t& tdo_expected, const bits_t& tdo_mask, const bool end_tms);
bool shift_ir(const bits_t& tdi_value, const bits_t& tdo_expected = {}, const bits_t& tdo_mask = {});
bool shift_dr(const bits_t& tdi_value, const bits_t& tdo_expected = {}, const bits_t& tdo_mask = {});
void state(const state_t state);
void wait(const state_t wait_state, const state_t end_state, const uint32_t wait_time);
private:
jtag::Target& target;
TAPState tap { };
uint32_t _run_test { 0 };
uint8_t _repeat { 0 };
state_t _end_ir { };
state_t _end_dr { };
bool clock(const bool tms, const bool tdi=false);
void advance_to_state(const state_t desired_state);
void delay_us(const uint32_t microseconds);
void shift_start(const state_t state);
void shift_end(const state_t end_state, const uint32_t end_delay);
bool shift_data(const bits_t& tdi, const bits_t& tdo_expected, const bits_t& tdo_mask, const state_t state, const state_t end_state, const uint32_t end_delay);
};
} /* namespace tap */
} /* namespace jtag */
#endif/*__JTAG_TAP_H__*/

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* 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 __JTAG_TARGET_H__
#define __JTAG_TARGET_H__
#include <cstdint>
#include <cstddef>
namespace jtag {
class Target {
public:
using bit_t = uint_fast8_t;
virtual ~Target() {
}
virtual void delay(const size_t n) = 0;
virtual bit_t clock(
const bit_t tms_value,
const bit_t tdi_value
) = 0;
};
} /* namespace jtag */
#endif/*__JTAG_TARGET_H__*/

View File

@@ -22,7 +22,7 @@
#ifndef __JTAG_TARGET_GPIO_H__
#define __JTAG_TARGET_GPIO_H__
#include "jtag.hpp"
#include "jtag_target.hpp"
#include <ch.h>

View File

@@ -23,7 +23,7 @@
#include "string_format.hpp"
ManchesterDecoder::DecodedSymbol ManchesterDecoder::operator[](const size_t index) const {
DecodedSymbol ManchesterDecoder::operator[](const size_t index) const {
const size_t encoded_index = index * 2;
if( (encoded_index + 1) < packet.size() ) {
const auto value = packet[encoded_index + sense];
@@ -38,7 +38,7 @@ size_t ManchesterDecoder::symbols_count() const {
return packet.size() / 2;
}
ManchesterFormatted format_manchester(
FormattedSymbols format_symbols(
const ManchesterDecoder& decoder
) {
const size_t payload_length_decoded = decoder.symbols_count();

View File

@@ -29,13 +29,13 @@
#include "baseband_packet.hpp"
struct DecodedSymbol {
uint_fast8_t value;
uint_fast8_t error;
};
class ManchesterDecoder {
public:
struct DecodedSymbol {
uint_fast8_t value;
uint_fast8_t error;
};
constexpr ManchesterDecoder(
const baseband::Packet& packet,
const size_t sense = 0
@@ -54,16 +54,16 @@ private:
};
template<typename T>
T operator|(const T& l, const ManchesterDecoder::DecodedSymbol& r) {
T operator|(const T& l, const DecodedSymbol& r) {
return l | r.value;
}
struct ManchesterFormatted {
struct FormattedSymbols {
const std::string data;
const std::string errors;
};
ManchesterFormatted format_manchester(
FormattedSymbols format_symbols(
const ManchesterDecoder& decoder
);

View File

@@ -24,6 +24,7 @@
#include <cstdint>
#include <cstddef>
#include <cstring>
#include <array>
#include <functional>
#include <algorithm>
@@ -50,7 +51,6 @@ public:
ChannelStatistics = 2,
DisplayFrameSync = 3,
AudioStatistics = 4,
BasebandConfiguration = 5,
TPMSPacket = 6,
Shutdown = 8,
AISPacket = 7,
@@ -63,7 +63,8 @@ public:
SpectrumStreamingConfig = 15,
DisplaySleep = 16,
CaptureConfig = 17,
CaptureThreadDone = 18,
TXDone = 20,
Retune = 21,
ReadyForSwitch = 22,
@@ -198,65 +199,21 @@ public:
AudioStatistics statistics;
};
struct BasebandConfiguration {
int32_t mode;
uint32_t sampling_rate;
size_t decimation_factor;
constexpr BasebandConfiguration(
int32_t mode,
uint32_t sampling_rate,
size_t decimation_factor = 1
) : mode { mode },
sampling_rate { sampling_rate },
decimation_factor { decimation_factor }
{
}
constexpr BasebandConfiguration(
) : BasebandConfiguration { -1, 0, 1 }
{
}
};
class BasebandConfigurationMessage : public Message {
public:
constexpr BasebandConfigurationMessage(
const BasebandConfiguration& configuration
) : Message { ID::BasebandConfiguration },
configuration { configuration }
{
}
BasebandConfiguration configuration;
};
class SpectrumStreamingConfigMessage : public Message {
public:
enum class Mode : uint32_t {
Stopped = 0,
Running = 1,
};
constexpr SpectrumStreamingConfigMessage(
Mode mode
) : Message { ID::SpectrumStreamingConfig },
mode { mode },
decimation_factor { 1 }
{
}
constexpr SpectrumStreamingConfigMessage(
Mode mode,
size_t decimation_factor
) : Message { ID::SpectrumStreamingConfig },
mode { mode },
decimation_factor { decimation_factor }
mode { mode }
{
}
Mode mode { Mode::Stopped };
size_t decimation_factor = 1;
};
struct ChannelSpectrum {
@@ -430,21 +387,63 @@ public:
const iir_biquad_config_t audio_hpf_config;
};
// TODO: Put this somewhere else, or at least the implementation part.
class StreamBuffer {
uint8_t* data_;
size_t used_;
size_t capacity_;
public:
constexpr StreamBuffer(
void* const data = nullptr,
const size_t capacity = 0
) : data_ { static_cast<uint8_t*>(data) },
used_ { 0 },
capacity_ { capacity }
{
}
size_t write(const void* p, const size_t count) {
const auto copy_size = std::min(capacity_ - used_, count);
memcpy(&data_[used_], p, copy_size);
used_ += copy_size;
return copy_size;
}
bool is_full() const {
return used_ >= capacity_;
}
const void* data() const {
return data_;
}
size_t size() const {
return used_;
}
void empty() {
used_ = 0;
}
};
struct CaptureConfig {
const size_t write_size_log2;
const size_t buffer_count_log2;
const size_t write_size;
const size_t buffer_count;
uint64_t baseband_bytes_received;
uint64_t baseband_bytes_dropped;
FIFO<uint8_t>* fifo;
FIFO<StreamBuffer*>* fifo_buffers_empty;
FIFO<StreamBuffer*>* fifo_buffers_full;
constexpr CaptureConfig(
const size_t write_size_log2,
const size_t buffer_count_log2
) : write_size_log2 { write_size_log2 },
buffer_count_log2 { buffer_count_log2 },
const size_t write_size,
const size_t buffer_count
) : write_size { write_size },
buffer_count { buffer_count },
baseband_bytes_received { 0 },
baseband_bytes_dropped { 0 },
fifo { nullptr }
fifo_buffers_empty { nullptr },
fifo_buffers_full { nullptr }
{
}
@@ -539,33 +538,16 @@ public:
int8_t * data;
};
class MessageHandlerMap {
class CaptureThreadDoneMessage : public Message {
public:
using MessageHandler = std::function<void(Message* const p)>;
void register_handler(const Message::ID id, MessageHandler&& handler) {
if( map_[toUType(id)] != nullptr ) {
chDbgPanic("MsgDblReg");
}
map_[toUType(id)] = std::move(handler);
constexpr CaptureThreadDoneMessage(
uint32_t error = 0
) : Message { ID::CaptureThreadDone },
error { error }
{
}
void unregister_handler(const Message::ID id) {
map_[toUType(id)] = nullptr;
}
void send(Message* const message) {
if( message->id < Message::ID::MAX ) {
auto& fn = map_[toUType(message->id)];
if( fn ) {
fn(message);
}
}
}
private:
using MapType = std::array<MessageHandler, toUType(Message::ID::MAX)>;
MapType map_;
uint32_t error;
};
#endif/*__MESSAGE_H__*/

View File

@@ -74,6 +74,10 @@ public:
return fifo.is_empty();
}
void reset() {
fifo.reset();
}
private:
FIFO<uint8_t> fifo;
Mutex mutex_write;

View File

@@ -49,10 +49,14 @@ static constexpr std::array<uint8_t, 12> png_iend { {
0xae, 0x42, 0x60, 0x82, // CRC
} };
PNGWriter::PNGWriter(
Optional<File::Error> PNGWriter::create(
const std::string& filename
) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc }
{
) {
const auto create_error = file.create(filename);
if( create_error.is_valid() ) {
return create_error;
}
file.write(png_file_header);
file.write(png_ihdr_screen_capture);
@@ -63,6 +67,8 @@ PNGWriter::PNGWriter(
constexpr std::array<uint8_t, 2> zlib_header { 0x78, 0x01 }; // Zlib CM, CINFO, FLG.
write_chunk_content(zlib_header);
return { };
}
PNGWriter::~PNGWriter() {

View File

@@ -33,9 +33,10 @@
class PNGWriter {
public:
explicit PNGWriter(const std::string& filename);
~PNGWriter();
Optional<File::Error> create(const std::string& filename);
void write_scanline(const std::array<ui::ColorRGB888, 240>& scanline);
private:

View File

@@ -1,519 +0,0 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
*
* 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 "portapack_cpld_data.hpp"
#include <cstdint>
#include <array>
namespace portapack {
namespace cpld {
/* 2015 Aug 21 12:12 PT */
const std::array<uint16_t, 3328> block_0 { {
0x7fff, 0xffff, 0xbffc, 0xf9e7, 0x79ff, 0xfffe, 0xaf9e, 0x7cff,
0x7fff, 0xfbe7, 0xb3f7, 0xffff, 0x7f3f, 0x7dfb, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbff7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x67ff, 0xffff, 0xbfff, 0xfefd, 0x7fff, 0xff7f, 0xbfff, 0xe7f9,
0x723f, 0xfff9, 0xb77f, 0xcccf, 0x7fff, 0xb99f, 0xbccc, 0xcffe,
0x6fff, 0xffff, 0xbfff, 0xffeb, 0x77f3, 0xffff, 0xbfe6, 0xffff,
0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xfbfe,
0x7fff, 0xffff, 0xbfff, 0xfffe, 0x6fff, 0xffff, 0xbfef, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x6fff, 0xffff, 0xbfff, 0xffdb, 0x7fff, 0xffff, 0xbff7, 0xffff,
0x7dff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff5, 0xffff, 0xbffd, 0xffff,
0x7eff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x6fff, 0xffff, 0xbfff, 0xfdbb, 0x77ef, 0xbfff, 0xbfff, 0xf7ff,
0x7eef, 0xefff, 0xbfff, 0xffff, 0x7dff, 0xffff, 0xbfff, 0xffff,
0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbffd, 0xffff,
0x7dff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xff7f, 0x77ff, 0xffff, 0xbfff, 0xf7ff,
0x7dff, 0xefff, 0xbfff, 0xffff, 0x7dff, 0xffff, 0xbfff, 0xfffe,
0x7fff, 0xffff, 0xbfff, 0xfef7, 0x7ff7, 0xbfff, 0xbffd, 0xffff,
0x7ef7, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x6fff, 0xffff, 0xbffe, 0xffdf, 0x7fff, 0xffbf, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xb7ff, 0xffff, 0x7eff, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfeff,
0x7fff, 0xffff, 0xb5fd, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xadff, 0xffbf, 0x7ffe, 0xffff, 0xbfef, 0xff5f,
0x7fff, 0xffff, 0xbfff, 0xffef, 0x7fff, 0xffdf, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7dff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xf6ff, 0xbbcb, 0xffff,
0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7ff7, 0xffdf, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xfaff, 0xbfd5, 0xffff,
0x77ff, 0xffff, 0xa55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fdf, 0xdeef, 0xbfff, 0xfdff,
0x7fff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffd, 0xffff, 0xbffb, 0xffeb,
0x6bff, 0xffff, 0xb55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbdff, 0xdff5,
0x77ff, 0xffff, 0xbabf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffb, 0xf9bf, 0xbafe, 0xefff,
0x6fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffe, 0xffde, 0xbfdf, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xdfff, 0xbffd, 0x35ff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fd2, 0xffff, 0xbfbc, 0xc7ff,
0x7fff, 0xffff, 0xb7af, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xddee, 0xb9ff, 0xbdff,
0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffd, 0xea9f, 0xbefb, 0x7bff,
0x7fff, 0xffff, 0xbeaf, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7ffd, 0x0ddf, 0xb598, 0x5e74,
0x7fff, 0xffff, 0xb65f, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7ffc, 0x0ddd, 0xbd99, 0x1e6a,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f08, 0x388f, 0xb89e, 0x887f,
0x7bff, 0xffff, 0xb6f7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f0c, 0x388f, 0xb89f, 0x983b,
0x67ff, 0xffff, 0xbfff, 0x3333, 0x63e6, 0x6667, 0xb333, 0x31f3,
0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73e8, 0xc445, 0xb938, 0x88ff,
0x7fff, 0xffff, 0xb7ff, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab,
0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bcd, 0xdcca, 0xb19d, 0xddfb,
0x7bff, 0xffff, 0xbdf7, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xe66f, 0xb37f, 0xffde,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7feb, 0xeedf, 0xbfdf, 0xfcff,
0x7fff, 0xffff, 0xbfff, 0xeeee, 0x7ffb, 0xfbbf, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7dfd, 0xffff, 0xbffd, 0xdfff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffa, 0xefdf, 0xbfff, 0xdfff,
0x7fff, 0xffff, 0xbbfe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fef, 0xfeff, 0xbfdd, 0xfd7a,
0x77ff, 0xffff, 0xbebe, 0xfff7, 0x7fff, 0xfb7f, 0xbf9f, 0xefff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfef, 0xfffb,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbaff, 0xfffd,
0x7fff, 0xfdff, 0xbfff, 0xdfde, 0x7ffb, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xb7fd, 0xfff7, 0x7fff, 0xfdfb, 0xb7ff, 0xdfff,
0x7fff, 0xedff, 0xbfff, 0xffff, 0x7ffe, 0xffff, 0xbff3, 0xbbf7,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xff7f, 0xbeaf, 0xfffe,
0x7fff, 0xffff, 0xbfff, 0xbfbe, 0x7ffb, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbdee, 0xb7f7, 0x7fff, 0xfbef, 0xbfff, 0xffff,
0x7fff, 0xfbfe, 0xbfff, 0xfedf, 0x6dff, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xb7ff, 0xefdf, 0x7fef, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xfff7, 0xadbf, 0xffef, 0x7fff, 0xffff, 0xbfff, 0xfffb,
0x7fff, 0xffff, 0xbffd, 0xdfff, 0x7ff7, 0xfdff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffd7, 0x6eff, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbadf, 0x7bd7, 0x7fff, 0xffef, 0xbfff, 0xffff,
0x7fff, 0xfbf9, 0xb3ff, 0xfeff, 0x7fff, 0xffff, 0xbfff, 0xfffb,
0x7fff, 0xffff, 0xbe5f, 0xff77, 0x7fff, 0xfefd, 0xbfff, 0xffff,
0x7fff, 0xfeee, 0xbfbf, 0xfb3b, 0x77ff, 0xffff, 0xbfff, 0xffea,
0x7fff, 0xffff, 0xbbff, 0xffff, 0x6fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xd7ff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7bff, 0xffff, 0xbbaf, 0xffff, 0x7ff7, 0x7fff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbbff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff4,
0x7fff, 0xffff, 0xbdaf, 0x7bff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xf7ba, 0xb37f, 0xeeff, 0x6fff, 0xffff, 0xbfff, 0xffff,
0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xfeff, 0xbfbf, 0xfff3, 0x7eff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f7f, 0xf7ff, 0xbfff, 0xffff,
0x7fff, 0xf76f, 0xbfff, 0xffb7, 0x6eff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xff7f, 0x7fff, 0xfffd, 0xbfff, 0xffff,
0x7fff, 0xfcde, 0xbdbf, 0xdf8d, 0x7aff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xb5af, 0xbfff, 0x6ff7, 0x6f7f, 0xbfff, 0xffff,
0x7fff, 0xfbad, 0xbfdf, 0xf77b, 0x7fff, 0xffff, 0xbfff, 0xffee,
0x77ff, 0xffff, 0xbfff, 0xfbf7, 0x7f7f, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xf77b, 0xb37f, 0xecf6, 0x6dff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfaf, 0x3000, 0x67c0, 0x061f, 0xbfff, 0xffef,
0x7fff, 0xfccd, 0xbbb7, 0x7f99, 0x7cff, 0xffff, 0xb7ff, 0xfff5,
0x6bff, 0xffff, 0xb7ff, 0x3000, 0x66e0, 0x0601, 0xbfff, 0xffdf,
0x7fff, 0xfccd, 0xbbbe, 0xd519, 0x7cff, 0xffff, 0xafff, 0xffff,
0x7dff, 0xffff, 0xbd5f, 0x3000, 0x67e0, 0x061f, 0xbfff, 0xffff,
0x7fff, 0xfcc8, 0xb11f, 0xcc99, 0x78ff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbbff, 0x3000, 0x67e0, 0x0601, 0xbfff, 0xffff,
0x7fff, 0xf698, 0xb11f, 0x8033, 0x6eff, 0xffff, 0xbfff, 0xffff,
0x77ff, 0xffff, 0xbff7, 0xbbbb, 0x73ee, 0x6ee7, 0xb333, 0x31f3,
0x6666, 0x78c6, 0xaccf, 0xb318, 0x7bcc, 0xccc7, 0xb999, 0x99ff,
0x7fff, 0xffff, 0xb7ff, 0x3333, 0x6546, 0x6667, 0xb777, 0x74ab,
0x7777, 0x7d9c, 0xb995, 0x19cd, 0x79dd, 0xddd2, 0xb5dd, 0xddff,
0x7bff, 0xffff, 0xbffb, 0xfddd, 0x7fdd, 0xdfdf, 0xbfff, 0xffef,
0x7fff, 0xfff6, 0xacff, 0x337f, 0x7fff, 0xffff, 0xb7ff, 0xffff,
0x7fff, 0xffff, 0xbffd, 0x5fff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbbdf, 0xddff, 0x7bbf, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xfddf, 0xbfff, 0xffdd, 0x6fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfbf, 0xffdd, 0x6fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbbff, 0x5fff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xfedf, 0xbbff, 0xbdff, 0x77bf, 0xffff, 0xbfff, 0xffef,
0x7dff, 0xffff, 0xbfbf, 0xffef, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7ffd, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffb, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7ff7, 0xffbf, 0xbfff, 0xfdff,
0x7fff, 0xffff, 0xbff7, 0xffdf, 0x7ffe, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xeeff, 0xbfff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ffd, 0xffff, 0xbfff, 0xffff,
0x7ffd, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffbf, 0xbfff, 0xfdff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd,
0x7bff, 0xffff, 0xb77f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfbf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd,
0x79ff, 0xffff, 0xb7bf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x75ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbebf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xa59f, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfff5,
0x69ff, 0xffff, 0xab7f, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff,
0x7dff, 0xffff, 0xbddf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbabf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0x3333, 0x63e6, 0x6667, 0xb333, 0x31f3,
0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff,
0x7fff, 0xffff, 0xb7bf, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab,
0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff,
0x7fff, 0xffff, 0xbdff, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xffff,
0x7fff, 0xffff, 0xbffd, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xf7ff, 0x7fff, 0xfbff, 0xbfff, 0xf7ff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xfbff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xefff, 0x7fff, 0xffff, 0xbfff, 0xf7ff,
0x7dff, 0xffff, 0xbbbf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xdfff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbeff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffbf, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xfbff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbff7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xf7ff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xff7f, 0x7fff, 0xffff, 0xbfff, 0xefff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbeff, 0xffff,
0x7fff, 0xffff, 0xbdff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffb,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd,
0x7fff, 0xffff, 0xbeff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf,
0x7fff, 0xffff, 0xad5f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x69ff, 0xffff, 0xabff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbd9f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x69ff, 0xffff, 0xb6bf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x75ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfaf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xb6af, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfffe,
0x7bff, 0xffff, 0xb9ff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffeb,
0x7fff, 0xffff, 0xbf5f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x77ff, 0xffff, 0xbe9f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x3333, 0x63e6, 0x6667, 0xb333, 0x31f3,
0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff,
0x7fff, 0xffff, 0xbfbf, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab,
0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff,
0x7fff, 0xffff, 0xbedf, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfff7,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbefd, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfffe, 0x7ff7, 0xffbf, 0xbeff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbeff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xff5f,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbffe, 0xffff,
0x7fff, 0xffff, 0xbf7f, 0xffff, 0x6ff7, 0xffff, 0xbf7f, 0xfeff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbdff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xff7f, 0xbfff, 0xffff,
0x77ff, 0xffff, 0xbffb, 0xff7f, 0x7fff, 0xbbf7, 0xbfff, 0xbfff,
0x7fff, 0xffff, 0xbfff, 0xfffb, 0x7fff, 0xffff, 0xbfff, 0xffbf,
0x77ff, 0xffff, 0xbffe, 0xfffd, 0x6fff, 0xffff, 0xbffe, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbdfd, 0xffff, 0x6fff, 0xdff7, 0xbfff, 0x7fff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffbd, 0x7fff, 0xfdff, 0xbffe, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfffb, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfea, 0x75ff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbffd, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfdb, 0xb5ff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf,
0x7fff, 0xffff, 0xb6af, 0xefff, 0x7fff, 0x7fff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xb7af, 0xfdff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbdaf, 0xffff, 0x7ff7, 0xffdf, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffea,
0x77ff, 0xffff, 0xbbff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x4fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xdeff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbaff, 0xffff, 0x77ff, 0xffbf, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffee,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fef, 0x7fff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xa55f, 0xfebf, 0x67c6, 0x1ebf, 0xbfff, 0xffef,
0x7fff, 0xffff, 0x9fff, 0x7fff, 0x5fff, 0xffff, 0xb7ff, 0xfff5,
0x67ff, 0xffff, 0xafff, 0xc2bf, 0x47a6, 0x1ebf, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff,
0x5fff, 0xffff, 0xb55f, 0xfe7f, 0x67e6, 0x1f3f, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x67ff, 0xffff, 0x9fff, 0xc27f, 0x47e6, 0x1f3f, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0x3bb3, 0x73ee, 0xe6e7, 0xb333, 0x31f3,
0x4666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff,
0x7fff, 0xffff, 0xbfff, 0x7337, 0x4546, 0x7677, 0xb777, 0x74ab,
0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fdf, 0xdfff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x77ff, 0xffff, 0xbfff, 0xefff,
0x7fff, 0xffff, 0xbf7f, 0xfff7, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xfffd, 0x7ff7, 0xffff, 0xbfff, 0xffff,
0x7fdf, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xff7f, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x8fff, 0xfffd, 0x4ff7, 0xffff, 0xbfff, 0xffff,
0x7fbf, 0xffff, 0xbfff, 0xffef, 0x7fff, 0xff7f, 0x9fff, 0xffff,
0x5dff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xefff,
0x7fff, 0xffff, 0x9f7f, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffb,
0x77ff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xdfff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x77ee, 0xffff, 0xbfff, 0xdfff,
0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xa55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xfffd,
0x7bff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xa55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd,
0x7bff, 0xffff, 0xaaff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffb,
0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbaff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffee,
0x77ff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x855f, 0xffff, 0x5fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0x97ff, 0xfff5,
0x4bff, 0xffff, 0xafff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff,
0x7fff, 0xffff, 0xb55f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0x3333, 0x43e6, 0x6667, 0xb333, 0x31f3,
0x6666, 0x7ccc, 0xb98f, 0x9999, 0x73cc, 0xccc7, 0xb999, 0x99ff,
0x7fff, 0xffff, 0xbfff, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab,
0x7777, 0x7ddd, 0xbba5, 0x5ddd, 0x7bdd, 0xddd2, 0xb5dd, 0xddff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xfeff, 0x7fff, 0xbfff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xfff7,
0x7fff, 0xffff, 0xafff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xafff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xf7ff,
0x7fff, 0xffff, 0xbfbf, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffef, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x5fff, 0xefff, 0xbfff, 0xffef, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xf7ff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfdf, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fef, 0xffff, 0x9fff, 0xefff,
0x5fff, 0xefff, 0xbfff, 0xdfff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffbd, 0x7fff, 0xbdff, 0xbfff, 0xf7ff,
0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xfdff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xdfff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xff7e, 0x7fff, 0xdfff, 0xbfff, 0xdbff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffef, 0x7ffd, 0xdfff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xefff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfffb, 0x77ef, 0xffff, 0xbfdd, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfffe, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffef, 0x5ffd, 0xbfff, 0xbfef, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xefff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfef1, 0x67e7, 0xbfff, 0x9fed, 0xeffd,
0x53ff, 0xfff9, 0xb77f, 0xffff, 0x7fff, 0xb99f, 0xbccf, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbffc, 0xffff, 0x7ff3, 0xfffe, 0xaf9e, 0x7cff,
0x7fff, 0xffe7, 0x93e7, 0xffff, 0x5f3e, 0x79f3, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
} };
const std::array<uint16_t, 512> block_1 { {
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
} };
} /* namespace cpld */
} /* namespace portapack */

View File

@@ -27,10 +27,6 @@
#include "message_queue.hpp"
struct TouchADCFrame {
uint32_t dr[8];
};
struct JammerRange {
bool active;
int64_t center;
@@ -40,19 +36,16 @@ struct JammerRange {
/* NOTE: These structures must be located in the same location in both M4 and M0 binaries */
struct SharedMemory {
static constexpr size_t baseband_queue_k = 12;
static constexpr size_t application_queue_k = 11;
static constexpr size_t app_local_queue_k = 11;
MessageQueue baseband_queue;
uint8_t baseband_queue_data[1 << baseband_queue_k];
MessageQueue application_queue;
uint8_t application_queue_data[1 << application_queue_k];
uint8_t application_queue_data[1 << application_queue_k] { 0 };
uint8_t app_local_queue_data[1 << app_local_queue_k] { 0 };
const Message* volatile baseband_message { nullptr };
MessageQueue application_queue { application_queue_data, application_queue_k };
MessageQueue app_local_queue { app_local_queue_data, app_local_queue_k };
// TODO: M0 should directly configure and control DMA channel that is
// acquiring ADC samples.
TouchADCFrame touch_adc_frame;
int test;
char m4_panic_msg[32] { 0 };
uint8_t radio_data[256];
size_t bit_length;

View File

@@ -30,6 +30,58 @@
namespace portapack {
namespace spi_flash {
struct image_tag_t {
constexpr image_tag_t(
) : c { 0, 0, 0, 0 }
{
}
constexpr image_tag_t(
char c0, char c1, char c2, char c3
) : c { c0, c1, c2, c3 }
{
}
image_tag_t& operator=(const image_tag_t& other) {
c[0] = other.c[0];
c[1] = other.c[1];
c[2] = other.c[2];
c[3] = other.c[3];
return *this;
}
bool operator==(const image_tag_t& other) const {
return (c[0] == other.c[0]) && (c[1] == other.c[1]) && (c[2] == other.c[2]) && (c[3] == other.c[3]);
}
operator bool() const {
return (c[0] != 0) || (c[1] != 0) || (c[2] != 0) || (c[3] != 0);
}
private:
char c[4];
};
constexpr image_tag_t image_tag_ais { 'P', 'A', 'I', 'S' };
constexpr image_tag_t image_tag_am_audio { 'P', 'A', 'M', 'A' };
constexpr image_tag_t image_tag_capture { 'P', 'C', 'A', 'P' };
constexpr image_tag_t image_tag_ert { 'P', 'E', 'R', 'T' };
constexpr image_tag_t image_tag_nfm_audio { 'P', 'N', 'F', 'M' };
constexpr image_tag_t image_tag_tpms { 'P', 'T', 'P', 'M' };
constexpr image_tag_t image_tag_wfm_audio { 'P', 'W', 'F', 'M' };
constexpr image_tag_t image_tag_wideband_spectrum { 'P', 'S', 'P', 'E' };
constexpr image_tag_t image_tag_hackrf { 'H', 'R', 'F', '1' };
struct chunk_t {
const image_tag_t tag;
const uint32_t length;
const uint8_t data[];
const chunk_t* next() const {
return reinterpret_cast<const chunk_t*>(&data[length]);
}
};
struct region_t {
const size_t offset;
const size_t size;
@@ -44,14 +96,9 @@ constexpr region_t bootstrap {
.size = 0x10000,
};
constexpr region_t hackrf {
constexpr region_t images {
.offset = 0x10000,
.size = 0x8000,
};
constexpr region_t baseband {
.offset = 0x20000,
.size = 0x8000,
.size = 0x30000,
};
constexpr region_t application {

View File

@@ -29,61 +29,115 @@ Timestamp Packet::received_at() const {
return packet_.timestamp();
}
ManchesterFormatted Packet::symbols_formatted() const {
return format_manchester(decoder_);
FormattedSymbols Packet::symbols_formatted() const {
return format_symbols(decoder_);
}
Optional<Reading> Packet::reading(const SignalType signal_type) const {
if( signal_type == SignalType::FLM ) {
const auto length = crc_valid_length();
Optional<Reading> Packet::reading_fsk_19k2_schrader() const {
const auto length = crc_valid_length();
switch(length) {
case 64:
return Reading {
Reading::Type::FLM_64,
reader_.read(0, 32),
Pressure { static_cast<int>(reader_.read(32, 8)) * 4 / 3 },
Temperature { static_cast<int>(reader_.read(40, 8) & 0x7f) - 50 }
};
case 72:
return Reading {
Reading::Type::FLM_72,
reader_.read(0, 32),
Pressure { static_cast<int>(reader_.read(40, 8)) * 4 / 3 },
Temperature { static_cast<int>(reader_.read(48, 8)) - 50 }
};
case 80:
return Reading {
Reading::Type::FLM_80,
reader_.read(8, 32),
Pressure { static_cast<int>(reader_.read(48, 8)) * 4 / 3 },
Temperature { static_cast<int>(reader_.read(56, 8)) - 50 }
};
default:
return { };
}
}
if( signal_type == SignalType::Subaru ) {
switch(length) {
case 64:
return Reading {
Reading::Type::SUB_35,
reader_.read(3, 25),
Pressure { static_cast<int>(reader_.read(28, 8)) }
Reading::Type::FLM_64,
reader_.read(0, 32),
Pressure { static_cast<int>(reader_.read(32, 8)) * 4 / 3 },
Temperature { static_cast<int>(reader_.read(40, 8) & 0x7f) - 50 }
};
case 72:
return Reading {
Reading::Type::FLM_72,
reader_.read(0, 32),
Pressure { static_cast<int>(reader_.read(40, 8)) * 4 / 3 },
Temperature { static_cast<int>(reader_.read(48, 8)) - 50 }
};
case 80:
return Reading {
Reading::Type::FLM_80,
reader_.read(8, 32),
Pressure { static_cast<int>(reader_.read(48, 8)) * 4 / 3 },
Temperature { static_cast<int>(reader_.read(56, 8)) - 50 }
};
default:
return { };
}
}
Optional<Reading> Packet::reading_ook_8k192_schrader() const {
/*
* Preamble: 11*2, 01*14, 11, 10
* Function code: 3 Manchester symbols
* ID: 24 Manchester symbols (one variant seen with 21 symbols?)
* Pressure: 8 Manchester symbols
* Checksum: 2 Manchester symbols (2 LSBs of sum incl this field == 3)
*/
const auto flags = reader_.read(0, 3);
const auto checksum = reader_.read(35, 2);
uint32_t checksum_calculated = reader_.read(0, 1);
for(size_t i=1; i<37; i+=2) {
checksum_calculated += reader_.read(i, 2);
}
if( signal_type == SignalType::GMC ) {
if( (checksum_calculated & 3) == 3 ) {
return Reading {
Reading::Type::Schrader,
reader_.read(3, 24),
Pressure { static_cast<int>(reader_.read(27, 8)) * 4 / 3 },
{ },
Flags { (flags << 4) | checksum }
};
} else {
return { };
}
}
Optional<Reading> Packet::reading_ook_8k4_schrader() const {
/*
* Preamble: 01*40
* System ID: 01100101, ??*20 (not really sure what this data is)
* ID: 32 Manchester symbols
* Value: 8 Manchester symbols (temperature?)
* Value: 8 Manchester symbols (pressure?)
* Checksum: 8 Manchester symbols (uint8_t sum of bytes starting with system ID)
*/
/* NOTE: First four bits of packet are consumed in preamble detection.
* Those bits assumed to be 0b0100", which may not be entirely true...
*/
constexpr uint8_t first_nibble = 0x4;
const auto system_id = (first_nibble << 20) | reader_.read(0, 20);
const auto id = reader_.read(20, 32);
const auto value_0 = reader_.read(52, 8);
const auto value_1 = reader_.read(60, 8);
const auto checksum = reader_.read(68, 8);
uint8_t checksum_calculated = (first_nibble << 4) | reader_.read(0, 4);
for(size_t i=4; i<68; i+=8) {
checksum_calculated += reader_.read(i, 8);
}
if( checksum_calculated == checksum ) {
return Reading {
Reading::Type::GMC_96,
reader_.read(20, 32),
Pressure { static_cast<int>(reader_.read(52, 8)) }
id,
Pressure { static_cast<int>(value_1) * 4 / 3 },
Temperature { static_cast<int>(value_0) - 50 }
};
} else {
return { };
}
}
return { };
Optional<Reading> Packet::reading() const {
switch( signal_type() ) {
case SignalType::FSK_19k2_Schrader: return reading_fsk_19k2_schrader();
case SignalType::OOK_8k192_Schrader: return reading_ook_8k192_schrader();
case SignalType::OOK_8k4_Schrader: return reading_ook_8k4_schrader();
default: return { };
}
}
size_t Packet::crc_valid_length() const {

View File

@@ -37,10 +37,12 @@ using units::Pressure;
namespace tpms {
using Flags = uint8_t;
enum SignalType : uint32_t {
FLM = 1,
Subaru = 2,
GMC = 3,
FSK_19k2_Schrader = 1,
OOK_8k192_Schrader = 2,
OOK_8k4_Schrader = 3,
};
class TransponderID {
@@ -71,7 +73,7 @@ public:
FLM_64 = 1,
FLM_72 = 2,
FLM_80 = 3,
SUB_35 = 4,
Schrader = 4,
GMC_96 = 5,
};
@@ -92,11 +94,13 @@ public:
Type type,
TransponderID id,
Optional<Pressure> pressure = { },
Optional<Temperature> temperature = { }
Optional<Temperature> temperature = { },
Optional<Flags> flags = { }
) : type_ { type },
id_ { id },
pressure_ { pressure },
temperature_ { temperature }
temperature_ { temperature },
flags_ { flags }
{
}
@@ -116,37 +120,50 @@ public:
return temperature_;
}
Optional<Flags> flags() const {
return flags_;
}
private:
Type type_ { Type::None };
TransponderID id_ { 0 };
Optional<Pressure> pressure_ { };
Optional<Temperature> temperature_ { };
Optional<Flags> flags_ { };
};
class Packet {
public:
constexpr Packet(
const baseband::Packet& packet
const baseband::Packet& packet,
const SignalType signal_type
) : packet_ { packet },
signal_type_ { signal_type },
decoder_ { packet_, 0 },
reader_ { decoder_ }
{
}
SignalType signal_type() const { return signal_type_; }
Timestamp received_at() const;
ManchesterFormatted symbols_formatted() const;
FormattedSymbols symbols_formatted() const;
Optional<Reading> reading(const SignalType signal_type) const;
Optional<Reading> reading() const;
private:
using Reader = FieldReader<ManchesterDecoder, BitRemapNone>;
const baseband::Packet packet_;
const SignalType signal_type_;
const ManchesterDecoder decoder_;
const Reader reader_;
Optional<Reading> reading_fsk_19k2_schrader() const;
Optional<Reading> reading_ook_8k192_schrader() const;
Optional<Reading> reading_ook_8k4_schrader() const;
size_t crc_valid_length() const;
};

View File

@@ -238,6 +238,13 @@ std::string View::title() const {
/* Rectangle *************************************************************/
Rectangle::Rectangle(
Color c
) : Widget { },
color { c }
{
}
Rectangle::Rectangle(
Rect parent_rect,
Color c

View File

@@ -171,6 +171,7 @@ protected:
class Rectangle : public Widget {
public:
Rectangle(Color c);
Rectangle(Rect parent_rect, Color c);
void paint(Painter& painter) override;