Merged remote-tracking branch 'upstream/master'

This commit is contained in:
furrtek
2015-11-18 22:01:48 +01:00
135 changed files with 8512 additions and 7734 deletions
+376
View File
@@ -0,0 +1,376 @@
/*
* Copyright (C) 2015 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 "ais_baseband.hpp"
#include <cstdint>
#include <cstddef>
#include <cstdlib>
#include <string>
#include "crc.hpp"
// TODO: Move string formatting elsewhere!!!
#include "ui_widget.hpp"
namespace baseband {
template<typename T, typename BitRemap>
class FieldReader {
public:
constexpr FieldReader(
const T& data
) : data { data }
{
}
uint32_t read(const size_t start_bit, const size_t length) const {
uint32_t value = 0;
for(size_t i=start_bit; i<(start_bit + length); i++) {
value = (value << 1) | data[bit_remap(i)];
}
return value;
}
private:
const T& data;
const BitRemap bit_remap { };
};
namespace ais {
struct BitRemap {
size_t operator()(const size_t bit_index) const {
return bit_index ^ 7;
}
};
struct CRCBitRemap {
size_t operator()(const size_t bit_index) const {
return bit_index;
}
};
using FieldReader = baseband::FieldReader<std::bitset<1024>, BitRemap>;
using CRCFieldReader = baseband::FieldReader<std::bitset<1024>, CRCBitRemap>;
struct PacketLengthRange {
constexpr PacketLengthRange(
) : min_bytes { 0 },
max_bytes { 0 }
{
}
constexpr PacketLengthRange(
const uint16_t min_bits,
const uint16_t max_bits
) : min_bytes { static_cast<uint8_t>(min_bits / 8U) },
max_bytes { static_cast<uint8_t>(max_bits / 8U) }
{
// static_assert((min_bits & 7) == 0, "minimum bits not a multiple of 8");
// static_assert((max_bits & 7) == 0, "minimum bits not a multiple of 8");
}
bool contains(const size_t bit_count) const {
return !is_above(bit_count) && !is_below(bit_count);
}
bool is_above(const size_t bit_count) const {
return (min() > bit_count);
}
bool is_below(const size_t bit_count) const {
return (max() < bit_count);
}
size_t min() const {
return min_bytes * 8;
}
size_t max() const {
return max_bytes * 8;
}
private:
const uint8_t min_bytes;
const uint8_t max_bytes;
};
static constexpr std::array<PacketLengthRange, 64> packet_length_range { {
{ 0, 0 }, // 0
{ 168, 168 }, // 1
{ 168, 168 }, // 2
{ 168, 168 }, // 3
{ 168, 168 }, // 4
{ 424, 424 }, // 5
{ 0, 0 }, // 6
{ 0, 0 }, // 7
{ 0, 1008 }, // 8
{ 0, 0 }, // 9
{ 0, 0 }, // 10
{ 0, 0 }, // 11
{ 0, 0 }, // 12
{ 0, 0 }, // 13
{ 0, 0 }, // 14
{ 0, 0 }, // 15
{ 0, 0 }, // 16
{ 0, 0 }, // 17
{ 168, 168 }, // 18
{ 0, 0 }, // 19
{ 72, 160 }, // 20
{ 272, 360 }, // 21
{ 168, 168 }, // 22
{ 160, 160 }, // 23
{ 160, 168 }, // 24
{ 0, 168 }, // 25
{ 0, 0 }, // 26
{ 0, 0 }, // 27
{ 0, 0 }, // 28
{ 0, 0 }, // 29
{ 0, 0 }, // 30
{ 0, 0 }, // 31
} };
struct PacketLengthValidator {
bool operator()(const uint_fast8_t message_id, const size_t length) {
return packet_length_range[message_id].contains(length);
}
};
struct PacketTooLong {
bool operator()(const uint_fast8_t message_id, const size_t length) {
return packet_length_range[message_id].is_below(length);
}
};
struct CRCCheck {
bool operator()(const std::bitset<1024>& payload, const size_t data_length) {
CRCFieldReader field_crc { payload };
CRC<uint16_t> ais_fcs { 0x1021 };
uint16_t crc_calculated = 0xffff;
for(size_t i=0; i<data_length + 16; i+=8) {
if( i == data_length ) {
crc_calculated ^= 0xffff;
}
const uint8_t byte = field_crc.read(i, 8);
crc_calculated = ais_fcs.calculate_byte(crc_calculated, byte);
}
return crc_calculated == 0x0000;
}
};
static int32_t ais_latitude_normalized(
const FieldReader& field,
const size_t start_bit
) {
// Shifting and dividing is to sign-extend the source field.
// TODO: There's probably a more elegant way to do it.
return static_cast<int32_t>(field.read(start_bit, 27) << 5) / 32;
}
static int32_t ais_longitude_normalized(
const FieldReader& field,
const size_t start_bit
) {
// Shifting and dividing is to sign-extend the source field.
// TODO: There's probably a more elegant way to do it.
return static_cast<int32_t>(field.read(start_bit, 28) << 4) / 16;
}
static std::string ais_format_latlon_normalized(const int32_t normalized) {
const int32_t t = (normalized * 5) / 3;
const int32_t degrees = t / (100 * 10000);
const int32_t fraction = std::abs(t) % (100 * 10000);
return ui::to_string_dec_int(degrees) + "." + ui::to_string_dec_int(fraction, 6, '0');
}
static std::string ais_format_latitude(
const FieldReader& field,
const size_t start_bit
) {
const auto value = static_cast<int32_t>(field.read(start_bit, 27) << 5) / 32;
return ais_format_latlon_normalized(value);
}
static std::string ais_format_longitude(
const FieldReader& field,
const size_t start_bit
) {
const auto value = static_cast<int32_t>(field.read(start_bit, 28) << 4) / 16;
return ais_format_latlon_normalized(value);
}
struct ais_datetime {
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
static ais_datetime ais_get_datetime(
const FieldReader& field,
const size_t start_bit
) {
return {
static_cast<uint16_t>(field.read(start_bit + 0, 14)),
static_cast<uint8_t >(field.read(start_bit + 14, 4)),
static_cast<uint8_t >(field.read(start_bit + 18, 5)),
static_cast<uint8_t >(field.read(start_bit + 23, 5)),
static_cast<uint8_t >(field.read(start_bit + 28, 6)),
static_cast<uint8_t >(field.read(start_bit + 34, 6)),
};
}
static std::string ais_format_datetime(
const FieldReader& field,
const size_t start_bit
) {
const auto datetime = ais_get_datetime(field, start_bit);
return ui::to_string_dec_uint(datetime.year, 4) + "/" +
ui::to_string_dec_uint(datetime.month, 2, '0') + "/" +
ui::to_string_dec_uint(datetime.day, 2, '0') + " " +
ui::to_string_dec_uint(datetime.hour, 2, '0') + ":" +
ui::to_string_dec_uint(datetime.minute, 2, '0') + ":" +
ui::to_string_dec_uint(datetime.second, 2, '0');
}
static char ais_char_to_ascii(const uint8_t c) {
return (c ^ 32) + 32;
}
static std::string ais_read_text(
const FieldReader& field,
const size_t start_bit,
const size_t character_count
) {
std::string result;
const size_t character_length = 6;
const size_t end_bit = start_bit + character_count * character_length;
for(size_t i=start_bit; i<end_bit; i+=character_length) {
result += ais_char_to_ascii(field.read(i, character_length));
}
return result;
}
static std::string ais_format_navigational_status(const unsigned int value) {
switch(value) {
case 0: return "under way w/engine";
case 1: return "at anchor";
case 2: return "not under command";
case 3: return "restricted maneuv";
case 4: return "constrained draught";
case 5: return "moored";
case 6: return "aground";
case 7: return "fishing";
case 8: return "sailing";
case 9: case 10: case 13: return "reserved";
case 11: return "towing astern";
case 12: return "towing ahead/along";
case 14: return "SART/MOB/EPIRB";
case 15: return "undefined";
default: return "unexpected";
}
}
decoded_packet packet_decode(const std::bitset<1024>& payload, const size_t payload_length) {
// TODO: Unstuff here, not in baseband!
// Subtract end flag (8 bits) - one unstuffing bit (occurs during end flag).
const size_t data_and_fcs_length = payload_length - 7;
if( data_and_fcs_length < 38 ) {
return { "short " + ui::to_string_dec_uint(data_and_fcs_length, 3), "" };
}
const size_t extra_bits = data_and_fcs_length & 7;
if( extra_bits != 0 ) {
return { "extra bits " + ui::to_string_dec_uint(data_and_fcs_length, 3), "" };
}
FieldReader field { payload };
const auto message_id = field.read(0, 6);
const size_t data_length = data_and_fcs_length - 16;
PacketLengthValidator packet_length_valid;
if( !packet_length_valid(message_id, data_length) ) {
return { "bad length " + ui::to_string_dec_uint(data_length, 3), "" };
}
CRCCheck crc_ok;
if( !crc_ok(payload, data_length) ) {
return { "crc", "" };
}
const auto source_id = field.read(8, 30);
std::string result { ui::to_string_dec_uint(message_id, 2) + " " + ui::to_string_dec_uint(source_id, 10) };
switch(message_id) {
case 1:
case 2:
case 3:
{
const auto navigational_status = field.read(38, 4);
result += " " + ais_format_navigational_status(navigational_status);
result += " " + ais_format_latlon_normalized(ais_latitude_normalized(field, 89));
result += " " + ais_format_latlon_normalized(ais_longitude_normalized(field, 61));
}
break;
case 4:
{
result += " " + ais_format_datetime(field, 38);
result += " " + ais_format_latlon_normalized(ais_latitude_normalized(field, 107));
result += " " + ais_format_latlon_normalized(ais_longitude_normalized(field, 79));
}
break;
case 5:
{
const auto call_sign = ais_read_text(field, 70, 7);
const auto name = ais_read_text(field, 112, 20);
const auto destination = ais_read_text(field, 302, 20);
result += " \"" + call_sign + "\" \"" + name + "\" \"" + destination + "\"";
}
break;
case 21:
{
const auto name = ais_read_text(field, 43, 20);
result += " \"" + name + "\" " + ais_format_latitude(field, 192) + " " + ais_format_longitude(field, 164);
}
break;
default:
break;
}
return { "OK", result };
}
} /* namespace ais */
} /* namespace baseband */
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2015 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 __AIS_BASEBAND_H__
#define __AIS_BASEBAND_H__
#include <cstdint>
#include <cstddef>
#include <complex>
#include <array>
#include <bitset>
#include <utility>
namespace baseband {
namespace ais {
// RRC length should be about 4 x the symbol length (4T) to do a good job of
// cleaning up ISI.
// Translate+RRC filter
// sample=76.8k, deviation=2400, b=0.5, symbol=9600
// Length: 32 taps, 4 symbols, 1 cycle of sinusoid
constexpr std::array<std::complex<float>, 32> rrc_taps_76k8_4t_p { {
{ 5.3368736990e-03f, 0.0000000000e+00f }, { 4.6850211151e-03f, 9.3190864122e-04f },
{ 1.7970187432e-03f, 7.4434953528e-04f }, { -2.5478608559e-03f, -1.7024261963e-03f },
{ -6.6710920858e-03f, -6.6710920858e-03f }, { -8.6960320791e-03f, -1.3014531722e-02f },
{ -7.5474785839e-03f, -1.8221225159e-02f }, { -3.8115552023e-03f, -1.9161981995e-02f },
{ -8.1697309033e-19f, -1.3342183083e-02f }, { 3.6940784220e-05f, -1.8571386338e-04f },
{ -7.5474785839e-03f, 1.8221225159e-02f }, { -2.4954265902e-02f, 3.7346698152e-02f },
{ -5.1450054092e-02f, 5.1450054092e-02f }, { -8.3018814119e-02f, 5.5471398140e-02f },
{ -1.1321218147e-01f, 4.6894020990e-02f }, { -1.3498960022e-01f, 2.6851100952e-02f },
{ -1.4292666316e-01f, 1.7503468055e-17f }, { -1.3498960022e-01f, -2.6851100952e-02f },
{ -1.1321218147e-01f, -4.6894020990e-02f }, { -8.3018814119e-02f, -5.5471398140e-02f },
{ -5.1450054092e-02f, -5.1450054092e-02f }, { -2.4954265902e-02f, -3.7346698152e-02f },
{ -7.5474785839e-03f, -1.8221225159e-02f }, { 3.6940784220e-05f, 1.8571386338e-04f },
{ 2.4509192710e-18f, 1.3342183083e-02f }, { -3.8115552023e-03f, 1.9161981995e-02f },
{ -7.5474785839e-03f, 1.8221225159e-02f }, { -8.6960320791e-03f, 1.3014531722e-02f },
{ -6.6710920858e-03f, 6.6710920858e-03f }, { -2.5478608559e-03f, 1.7024261963e-03f },
{ 1.7970187432e-03f, -7.4434953528e-04f }, { 4.6850211151e-03f, -9.3190864122e-04f },
} };
using decoded_packet = std::pair<std::string, std::string>;
decoded_packet packet_decode(const std::bitset<1024>& data, const size_t data_length);
} /* namespace ais */
} /* namespace baseband */
#endif/*__AIS_BASEBAND_H__*/
+73
View File
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2015 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 __BIT_PATTERN_H__
#define __BIT_PATTERN_H__
#include <cstdint>
#include <cstddef>
class BitHistory {
public:
void add(const uint_fast8_t bit) {
history = (history << 1) | (bit & 1);
}
uint32_t value() const {
return history;
}
private:
uint32_t history { 0 };
};
class BitPattern {
public:
constexpr BitPattern(
) : code_ { 0 },
mask_ { 0 },
maximum_hanning_distance_ { 0 }
{
}
constexpr BitPattern(
const uint32_t code,
const size_t code_length,
const size_t maximum_hanning_distance = 0
) : code_ { code },
mask_ { (1U << code_length) - 1U },
maximum_hanning_distance_ { maximum_hanning_distance }
{
}
bool operator()(const BitHistory& history, const size_t) const {
const auto delta_bits = (history.value() ^ code_) & mask_;
const size_t count = __builtin_popcountl(delta_bits);
return (count <= maximum_hanning_distance_);
}
private:
uint32_t code_;
uint32_t mask_;
size_t maximum_hanning_distance_;
};
#endif/*__BIT_PATTERN_H__*/
+40
View File
@@ -0,0 +1,40 @@
/*
* 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 "chibios_cpp.hpp"
#include <ch.h>
void* operator new(size_t size) {
return chHeapAlloc(0x0, size);
}
void* operator new[](size_t size) {
return chHeapAlloc(0x0, size);
}
void operator delete(void* p) noexcept {
chHeapFree(p);
}
void operator delete[](void* p) noexcept {
chHeapFree(p);
}
+34
View File
@@ -0,0 +1,34 @@
/*
* 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 __CHIBIOS_CPP_H__
#define __CHIBIOS_CPP_H__
#include <cstddef>
/* Override new/delete to use Chibi/OS heap functions */
/* NOTE: Do not inline these, it doesn't work. ;-) */
void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void* p);
void operator delete[](void* p);
#endif/*__CHIBIOS_CPP_H__*/
-18
View File
@@ -26,8 +26,6 @@
#include <complex>
#include <cmath>
#include <hal.h>
constexpr float pi { 3.141592653589793238462643383279502884f };
namespace std {
@@ -124,20 +122,4 @@ static_assert(sizeof(complex8_t) == 2, "complex8_t size wrong");
static_assert(sizeof(complex16_t) == 4, "complex16_t size wrong");
static_assert(sizeof(complex32_t) == 8, "complex32_t size wrong");
#if defined(LPC43XX_M4)
static inline complex32_t multiply_conjugate_s16_s32(const complex16_t::rep_type a, const complex16_t::rep_type b) {
// conjugate: conj(a + bj) = a - bj
// multiply: (a + bj) * (c + dj) = (ac - bd) + (bc + ad)j
// conjugate-multiply: (ac + bd) + (bc - ad)j
//return { a.real() * b.real() + a.imag() * b.imag(), a.imag() * b.real() - a.real() * b.imag() };
const int32_t rr = __SMULBB(a, b);
const int32_t ii = __SMULTT(a, b);
const int32_t r = __QADD(rr, ii);
const int32_t ir = __SMULTB(a, b);
const int32_t ri = __SMULBT(a, b);
const int32_t i = __QSUB(ir, ri);
return { r, i };
}
#endif
#endif/*__COMPLEX_H__*/
+104
View File
@@ -0,0 +1,104 @@
/*
* 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 __CRC_H__
#define __CRC_H__
#include <cstddef>
#include <cstdint>
template<typename T>
class CRC {
public:
constexpr CRC(
const T polynomial/*,
const T initial*/
) : polynomial { polynomial }/*,
initial { initial }*/
{
// CRC LSB must always be 1
}
/*
template<typename U>
T calculate(const U& bits, const size_t length) {
if( length > bits.size() ) {
// Exception.
return 0;
}
T crc = 0;
for(size_t i=0; i<length; i++) {
crc = feed_bit(crc, bits[i]);
}
return crc;
}
*/
T calculate_byte(const T crc_in, const uint8_t data) {
/* Inspired by
* http://www.barrgroup.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
*/
T remainder = crc_in;
remainder ^= data << (width() - 8);
for(size_t bit=8; bit>0; --bit) {
if( remainder & top_bit() ) {
remainder = (remainder << 1) ^ polynomial;
} else {
remainder = (remainder << 1);
}
}
return remainder;
}
/*
T calculate(const uint8_t* const data, const size_t length) {
T remainder = initial;
for(size_t byte=0; byte<length; ++byte) {
remainder = calculate_byte(remainder, data[byte]);
}
return remainder;
}
*/
private:
const T polynomial;
// const T initial;
static constexpr size_t width() {
return 8 * sizeof(T);
}
static constexpr T top_bit() {
return 1U << (width() - 1);
}
/*
T feed_bit(const T crc_in, const uint_fast8_t bit) {
T crc_out = crc_in ^ (bit & 1);
if( crc_in & top_bit() ) {
return ((crc_in << 1) | (bit & 1)) ^ polynomial;
} else {
return (crc_in << 1) | (bit & 1);
}
}
*/
};
#endif/*__CRC_H__*/
+29 -3
View File
@@ -29,7 +29,9 @@
#include <type_traits>
#include <array>
#include "dsp_types.hpp"
#include "complex.hpp"
#include "sine_table.hpp"
#include "hal.h"
namespace std {
@@ -54,6 +56,20 @@ constexpr size_t log_2(const size_t n, const size_t p = 0) {
return (n <= 1) ? p : log_2(n / 2, p + 1);
}
template<typename T, size_t N>
void fft_swap(const buffer_c16_t src, std::array<T, N>& dst) {
static_assert(power_of_two(N), "only defined for N == power of two");
for(size_t i=0; i<N; i++) {
const size_t i_rev = __RBIT(i) >> (32 - log_2(N));
const auto s = src.p[i];
dst[i_rev] = {
static_cast<typename T::value_type>(s.real()),
static_cast<typename T::value_type>(s.imag())
};
}
}
template<typename T, size_t N>
void fft_swap(const std::array<complex16_t, N>& src, std::array<T, N>& dst) {
static_assert(power_of_two(N), "only defined for N == power of two");
@@ -69,10 +85,20 @@ void fft_swap(const std::array<complex16_t, N>& src, std::array<T, N>& dst) {
}
template<typename T, size_t N>
void fft_swap_in_place(std::array<T, N>& data) {
void fft_swap(const std::array<T, N>& src, std::array<T, N>& dst) {
static_assert(power_of_two(N), "only defined for N == power of two");
for(size_t i=0; i<N; i++) {
const size_t i_rev = __RBIT(i) >> (32 - log_2(N));
dst[i_rev] = src[i];
}
}
template<typename T, size_t N>
void fft_swap_in_place(std::array<T, N>& data) {
static_assert(power_of_two(N), "only defined for N == power of two");
for(size_t i=0; i<N/2; i++) {
const size_t i_rev = __RBIT(i) >> (32 - log_2(N));
std::swap(data[i], data[i_rev]);
}
@@ -88,10 +114,10 @@ void fft_c_preswapped(std::array<T, N>& data) {
/* Provide data to this function, pre-swapped. */
for(size_t mmax = 1; N > mmax; mmax <<= 1) {
const float theta = -pi / mmax;
const float wtemp = std::sin(0.5f * theta);
const float wtemp = sin_f32(0.5f * theta);
const T wp {
-2.0f * wtemp * wtemp,
std::sin(theta)
sin_f32(theta)
};
T w { 1.0f, 0.0f };
for(size_t m = 0; m < mmax; ++m) {
+3 -1
View File
@@ -25,6 +25,8 @@
#include <algorithm>
#include <cstring>
#include <hal.h>
/* FIFO implementation inspired by Linux kfifo. */
template<typename T, size_t K>
@@ -139,7 +141,7 @@ private:
}
void smp_wmb() {
/*__DMB();*/
__DMB();
}
size_t peek_n() {
+2 -2
View File
@@ -49,8 +49,8 @@ constexpr ClockFrequency ssp1_pclk_f = base_m4_clk_f;
constexpr ClockFrequency max5864_spi_f = 20000000U;
constexpr ClockFrequency max2837_spi_f = 20000000U;
constexpr ClockFrequency rffc5072_reference_f = 50000000U;
constexpr ClockFrequency max2837_reference_f = 50000000U;
constexpr ClockFrequency rffc5072_reference_f = 40000000U;
constexpr ClockFrequency max2837_reference_f = 40000000U;
constexpr ClockFrequency mcu_clkin_f = 40000000U;
constexpr uint8_t si5351_i2c_address = 0x60;
+86
View File
@@ -0,0 +1,86 @@
/*
* Copyright (C) 2015 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 __MEMORY_MAP_H__
#define __MEMORY_MAP_H__
#include <cstddef>
#include <cstdint>
#include "lpc43xx_cpp.hpp"
using namespace lpc43xx;
#include "utility.hpp"
namespace portapack {
namespace memory {
struct region_t {
public:
constexpr region_t(
const uint32_t base,
const size_t size
) : base_ { base },
size_ { size } {
}
constexpr uint32_t base() {
return base_;
}
constexpr uint32_t end() {
return base_ + size_;
}
constexpr size_t size() {
return size_;
}
private:
const uint32_t base_;
const size_t size_;
};
namespace map {
constexpr region_t local_sram_0 { 0x10000000, 96_KiB };
constexpr region_t local_sram_1 { 0x10080000, 40_KiB };
constexpr region_t ahb_ram_0 { 0x20000000, 32_KiB };
constexpr region_t ahb_ram_1 { 0x20008000, 16_KiB };
constexpr region_t ahb_ram_2 { 0x2000c000, 16_KiB };
constexpr region_t spifi_uncached { LPC_SPIFI_DATA_BASE, 1_MiB };
constexpr region_t spifi_cached { LPC_SPIFI_DATA_CACHED_BASE, spifi_uncached.size() };
/////////////////////////////////
constexpr region_t m4_code { local_sram_1.base(), 32_KiB };
constexpr region_t shared_memory { m4_code.end(), 8_KiB };
constexpr region_t m4_code_hackrf = local_sram_0;
} /* namespace map */
} /* namespace memory */
} /* namespace portapack */
#endif/*__MEMORY_MAP_H__*/
+86 -72
View File
@@ -29,8 +29,12 @@
#include "utility.hpp"
#include "ch.h"
class Message {
public:
static constexpr size_t MAX_SIZE = 276;
enum class ID : uint16_t {
/* Assign consecutive IDs. IDs are used to index array. */
RSSIStatistics = 0,
@@ -39,32 +43,22 @@ public:
ChannelSpectrum = 3,
AudioStatistics = 4,
BasebandConfiguration = 5,
FSKConfiguration = 6,
FSKPacket = 7,
TestResults = 8,
TPMSPacket = 6,
Shutdown = 8,
AISPacket = 7,
TXDone = 9,
Retune = 10,
SDCardStatus = 10,
Retune = 11,
MAX
};
constexpr Message(
ID id
) : id { id },
state { State::Free }
) : id { id }
{
}
enum class State : uint16_t {
Free,
InUse,
};
bool is_free() const {
return state == State::Free;
}
const ID id;
volatile State state;
};
struct RSSIStatistics {
@@ -77,8 +71,9 @@ struct RSSIStatistics {
class RSSIStatisticsMessage : public Message {
public:
constexpr RSSIStatisticsMessage(
const RSSIStatistics& statistics
) : Message { ID::RSSIStatistics },
statistics { }
statistics { statistics }
{
}
@@ -87,6 +82,8 @@ public:
struct BasebandStatistics {
uint32_t idle_ticks { 0 };
uint32_t main_ticks { 0 };
uint32_t rssi_ticks { 0 };
uint32_t baseband_ticks { 0 };
bool saturation { false };
};
@@ -94,8 +91,9 @@ struct BasebandStatistics {
class BasebandStatisticsMessage : public Message {
public:
constexpr BasebandStatisticsMessage(
const BasebandStatistics& statistics
) : Message { ID::BasebandStatistics },
statistics { }
statistics { statistics }
{
}
@@ -107,14 +105,8 @@ struct ChannelStatistics {
size_t count;
constexpr ChannelStatistics(
) : max_db { -120 },
count { 0 }
{
}
constexpr ChannelStatistics(
int32_t max_db,
size_t count
int32_t max_db = -120,
size_t count = 0
) : max_db { max_db },
count { count }
{
@@ -124,8 +116,7 @@ struct ChannelStatistics {
class ChannelStatisticsMessage : public Message {
public:
constexpr ChannelStatisticsMessage(
) : Message { ID::ChannelStatistics },
statistics { }
) : Message { ID::ChannelStatistics }
{
}
@@ -166,19 +157,20 @@ public:
AudioStatistics statistics;
};
/*enum bbmode {
RxNBAM = 1,
RxNBFM = 2,
RxWBFM = 3,
RxFSK = 4,
TxRDS = 15,
BBOff = 255
};*/
struct BasebandConfiguration {
int32_t mode;
uint32_t sampling_rate;
size_t decimation_factor;
constexpr BasebandConfiguration(
int32_t mode = -1,
uint32_t sampling_rate = 0,
size_t decimation_factor = 1
) : mode { mode },
sampling_rate { sampling_rate },
decimation_factor { decimation_factor }
{
}
};
class BasebandConfigurationMessage : public Message {
@@ -194,7 +186,7 @@ public:
};
struct ChannelSpectrum {
std::array<uint8_t, 256>* db { nullptr };
std::array<uint8_t, 256> db { { 0 } };
size_t db_count { 256 };
uint32_t sampling_rate { 0 };
uint32_t channel_filter_pass_frequency { 0 };
@@ -211,46 +203,56 @@ public:
ChannelSpectrum spectrum;
};
struct FSKConfiguration {
uint32_t symbol_rate;
uint32_t access_code;
size_t access_code_length;
size_t access_code_tolerance;
size_t packet_length;
};
class FSKConfigurationMessage : public Message {
public:
constexpr FSKConfigurationMessage(
FSKConfiguration configuration
) : Message { ID::FSKConfiguration },
configuration(configuration)
{
}
FSKConfiguration configuration;
};
#include <bitset>
struct FSKPacket {
std::bitset<256> payload;
size_t bits_received;
struct AISPacket {
std::bitset<1024> payload;
size_t bits_received { 0 };
};
FSKPacket(
) : bits_received { 0 }
class AISPacketMessage : public Message {
public:
constexpr AISPacketMessage(
) : Message { ID::AISPacket }
{
}
AISPacket packet;
};
struct TPMSPacket {
std::bitset<1024> payload;
size_t bits_received { 0 };
};
class TPMSPacketMessage : public Message {
public:
constexpr TPMSPacketMessage(
) : Message { ID::TPMSPacket }
{
}
TPMSPacket packet;
};
class ShutdownMessage : public Message {
public:
constexpr ShutdownMessage(
) : Message { ID::Shutdown }
{
}
};
class FSKPacketMessage : public Message {
class SDCardStatusMessage : public Message {
public:
FSKPacketMessage(
) : Message { ID::FSKPacket }
constexpr SDCardStatusMessage(
bool is_mounted
) : Message { ID::SDCardStatus },
is_mounted { is_mounted }
{
}
FSKPacket packet;
const bool is_mounted;
};
class TXDoneMessage : public Message {
@@ -275,14 +277,26 @@ public:
class MessageHandlerMap {
public:
using MessageHandler = std::function<void(const Message* const p)>;
using MessageHandler = std::function<void(Message* const p)>;
MessageHandler& operator[](Message::ID n) {
return map_[toUType(n)];
void register_handler(const Message::ID id, MessageHandler&& handler) {
if( map_[toUType(id)] != nullptr ) {
chDbgPanic("MsgDblReg");
}
map_[toUType(id)] = std::move(handler);
}
const MessageHandler& operator[](Message::ID n) const {
return map_[toUType(n)];
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:
-60
View File
@@ -20,63 +20,3 @@
*/
#include "message_queue.hpp"
#include "ch.h"
#include "lpc43xx_cpp.hpp"
using namespace lpc43xx;
bool MessageQueue::push(Message* const message) {
/* Returns true if success:
* - Message not in use.
* - FIFO wasn't full.
*/
if( message->state == Message::State::Free ) {
message->state = Message::State::InUse;
if( enqueue(message) ) {
signal();
return true;
} else {
// Roll back message state.
message->state = Message::State::Free;
}
}
return false;
}
Message* MessageQueue::pop() {
/* TODO: Because of architecture characteristics, the two LSBs of the
* message pointer will always be 0. Other (non-pointer) message types
* could be encoded by setting these two bits to non-zero values.
* One of the bits could also be used as an "ack" flag... In fact, a
* pointer message could be turned into an "ack" message, or something
* like that...
* Might be better though to use formal operating structures in the
* message to do synchronization between processors.
*/
Message* message { nullptr };
const auto success = fifo.out(&message, 1);
return success ? message : nullptr;
}
#if defined(LPC43XX_M0)
bool MessageQueue::enqueue(Message* const message) {
return fifo.in(&message, 1);
}
void MessageQueue::signal() {
creg::m0apptxevent::assert();
}
#endif
#if defined(LPC43XX_M4)
bool MessageQueue::enqueue(Message* const message) {
return fifo.in(&message, 1);
}
void MessageQueue::signal() {
creg::m4txevent::assert();
}
#endif
+47 -5
View File
@@ -27,11 +27,30 @@
#include "message.hpp"
#include "fifo.hpp"
#include "lpc43xx_cpp.hpp"
using namespace lpc43xx;
#include <ch.h>
template<size_t K>
class MessageQueue {
public:
bool push(Message* const message);
MessageQueue() {
chMtxInit(&mutex_write);
}
Message* pop();
template<typename T>
bool push(const T& message) {
static_assert(sizeof(T) <= Message::MAX_SIZE, "Message::MAX_SIZE too small for message type");
static_assert(std::is_base_of<Message, T>::value, "type is not based on Message");
return push(&message, sizeof(message));
}
Message* pop(std::array<uint8_t, Message::MAX_SIZE>& buf) {
Message* const p = reinterpret_cast<Message*>(buf.data());
return fifo.out_r(buf.data(), buf.size()) ? p : nullptr;
}
size_t len() const {
return fifo.len();
@@ -42,10 +61,33 @@ public:
}
private:
FIFO<Message*, 8> fifo;
FIFO<uint8_t, K> fifo;
Mutex mutex_write;
bool enqueue(Message* const message);
void signal();
bool push(const void* const buf, const size_t len) {
chMtxLock(&mutex_write);
const auto result = fifo.in_r(buf, len);
chMtxUnlock();
const bool success = (result == len);
if( success ) {
signal();
}
return success;
}
#if defined(LPC43XX_M0)
void signal() {
creg::m0apptxevent::assert();
}
#endif
#if defined(LPC43XX_M4)
void signal() {
creg::m4txevent::assert();
}
#endif
};
#endif/*__MESSAGE_QUEUE_H__*/
+5 -5
View File
@@ -69,7 +69,7 @@ constexpr Pin pins[] = {
[P2_2] = { 2, 2, PinConfig::sgpio_inout_fast(0) }, /* SGPIO6/BANK2F3M16: CPLD.61/HOST_DATA6(IO) */
[P2_3] = { 2, 3, { .mode=4, .pd=0, .pu=0, .fast=0, .input=1, .ifilt=1 } }, /* I2C1_SDA: PortaPack P2_3/LCD_TE */
[P2_4] = { 2, 4, { .mode=4, .pd=0, .pu=0, .fast=0, .input=1, .ifilt=1 } }, /* I2C1_SCL: PortaPack P2_4/<unused> */
[P2_5] = { 2, 5, { .mode=4, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* RX/P43: U7.VCTL1(I), U10.VCTL1(I), U2.VCTL1(I) */
[P2_5] = { 2, 5, { .mode=4, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* RX/P43: U7.VCTL1(I), U10.VCTL1(I), U2.VCTL1(I) */
[P2_6] = { 2, 6, { .mode=4, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* MIXER_SCLK/P31: 33pF, RFFC5072.SCLK(I) */
[P2_7] = { 2, 7, { .mode=0, .pd=0, .pu=0, .fast=0, .input=1, .ifilt=1 } }, /* ISP: 10K PU, Unused */
[P2_8] = { 2, 8, { .mode=4, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* P2_8: 10K PD, BOOT2, DFU switch, PortaPack P2_8/LCD_RD */
@@ -87,7 +87,7 @@ constexpr Pin pins[] = {
//[P3_6] = { 3, 6, { .mode=3, .pd=0, .pu=1, .fast=1, .input=1, .ifilt=0 } }, /* SPIFI_MISO: W25Q80BV.DO(IO) */
//[P3_7] = { 3, 7, { .mode=3, .pd=0, .pu=1, .fast=1, .input=1, .ifilt=0 } }, /* SPIFI_MOSI: W25Q80BV.DI(IO) */
//[P3_8] = { 3, 8, { .mode=3, .pd=0, .pu=1, .fast=1, .input=0, .ifilt=1 } }, /* SPIFI_CS/P68: W25Q80BV.CS(I) */
[P4_0] = { 4, 0, { .mode=0, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* HP/P44: U6.VCTL1(I), U5.VCTL2(I) */
[P4_0] = { 4, 0, { .mode=0, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* HP/P44: U6.VCTL1(I), U5.VCTL2(I) */
[P4_1] = { 4, 1, PinConfig::gpio_led(0) }, /* LED1: LED1.A(I) */
[P4_2] = { 4, 2, PinConfig::gpio_led(0) }, /* LED2: LED2.A(I) */
[P4_3] = { 4, 3, PinConfig::sgpio_in_fast(7) }, /* SGPIO9/P77/BANK2F3M1: CPLD.91/HOST_CAPTURE(O) */
@@ -100,8 +100,8 @@ constexpr Pin pins[] = {
[P4_10] = { 4, 10, PinConfig::gpio_out_with_pullup(4) }, /* SGPIO15/BANK2F3M6: CPLD.78/HOST_DECIM_SEL2(I) */
[P5_0] = { 5, 0, { .mode=0, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* !VAA_ENABLE: 10K PU, Q3.G(I), power to VAA */
[P5_1] = { 5, 1, { .mode=0, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* LP/P45: U6.VCTL2(I), U5.VCTL1(I) */
[P5_2] = { 5, 2, { .mode=0, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* TX_MIX_BP/P46: U9.V1(I) */
[P5_3] = { 5, 3, { .mode=0, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* RX_MIX_BP/P47: U9.V3(I) */
[P5_2] = { 5, 2, { .mode=0, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* TX_MIX_BP/P46: U9.V1(I) */
[P5_3] = { 5, 3, { .mode=0, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* RX_MIX_BP/P47: U9.V3(I) */
[P5_4] = { 5, 4, { .mode=0, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* MIXER_ENX/P32: 10K PU, 33pF, RFFC5072.ENX(I) */
[P5_5] = { 5, 5, { .mode=0, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* MIXER_RESETX/P33: 10K PU, 33pF, RFFC5072.RESETX(I) */
[P5_6] = { 5, 6, { .mode=0, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* TX_AMP/P48: U12.V3(I), U14.V1(I) */
@@ -113,7 +113,7 @@ constexpr Pin pins[] = {
[P6_4] = { 6, 4, { .mode=0, .pd=0, .pu=0, .fast=0, .input=1, .ifilt=1 } }, /* MIXER_SDATA/P27: 33pF, RFFC5072.SDATA(IO) */
[P6_5] = { 6, 5, { .mode=0, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* CPLD_TMS: CPLD.TMS(I) */
[P6_6] = { 6, 6, PinConfig::sgpio_inout_fast(2) }, /* SGPIO5/BANK2F3M15: CPLD.64/HOST_DATA5(IO) */
[P6_7] = { 6, 7, { .mode=4, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* TX/P42: U7.VCTL2(I), U10.VCTL2(I), U2.VCTL2(I) */
[P6_7] = { 6, 7, { .mode=4, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* TX/P42: U7.VCTL2(I), U10.VCTL2(I), U2.VCTL2(I) */
[P6_8] = { 6, 8, { .mode=4, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* MIX_BYPASS/P34: U1.VCTL2(I), U11.VCTL1(I) */
[P6_9] = { 6, 9, { .mode=0, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* !TX_AMP_PWR/P51: 10K PU, Q2.G(I), power to U25 (TX amp) */
[P6_10] = { 6, 10, { .mode=0, .pd=0, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* EN1V8/P70: 10K PD, TPS62410.EN2(I), 1V8LED.A(I) */
+121 -121
View File
@@ -27,7 +27,7 @@
namespace portapack {
namespace cpld {
/* 2015 Apr 23 19:34 PT */
/* 2015 Aug 21 12:12 PT */
const std::array<uint16_t, 3328> block_0 { {
0x7fff, 0xffff, 0xbffc, 0xf9e7, 0x79ff, 0xfffe, 0xaf9e, 0x7cff,
@@ -35,39 +35,39 @@ const std::array<uint16_t, 3328> block_0 { {
0x7fff, 0xffff, 0xbff7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x67ff, 0xffff, 0xbfff, 0xfefd, 0x7fff, 0xff7f, 0xbfff, 0xe7f9,
0x623f, 0xfff9, 0xb77f, 0xcccf, 0x7fff, 0xb99f, 0xbccc, 0xcffe,
0x723f, 0xfff9, 0xb77f, 0xcccf, 0x7fff, 0xb99f, 0xbccc, 0xcffe,
0x6fff, 0xffff, 0xbfff, 0xffeb, 0x77f3, 0xffff, 0xbfe6, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xfbfe,
0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xfbfe,
0x7fff, 0xffff, 0xbfff, 0xfffe, 0x6fff, 0xffff, 0xbfef, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x6fff, 0xffff, 0xbfff, 0xffdb, 0x7fff, 0xffff, 0xbff7, 0xffff,
0x7eff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff5, 0xffff, 0xbffd, 0xffff,
0x6fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x6fff, 0xffff, 0xbfff, 0xfdbb, 0x77ef, 0xbfff, 0xbfff, 0xffff,
0x7eef, 0xefff, 0xbfff, 0xffff, 0x7dff, 0xffff, 0xbfff, 0xfffe,
0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbffd, 0xdfff,
0x7dff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x7fff, 0xffff, 0xbfff, 0xff7f, 0x77ff, 0xffff, 0xbfff, 0xefff,
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, 0xefff, 0xbfff, 0xffff, 0x7eff, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xb7ff, 0xffff, 0x7eff, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xfebf, 0xbfff, 0xfeff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfeff,
0x7fff, 0xffff, 0xb5fd, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbdff, 0xffbf, 0x7ffe, 0xffff, 0xbfef, 0xff5f,
0x7fff, 0xefff, 0xadff, 0xffbf, 0x7ffe, 0xffff, 0xbfef, 0xff5f,
0x7fff, 0xffff, 0xbfff, 0xffef, 0x7fff, 0xffdf, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7dff, 0xfd7f, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfdf, 0xffff, 0x7fff, 0xffff, 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, 0xf6ef, 0xbfcb, 0xffff,
0x77ff, 0xffff, 0xbfdf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xfdff, 0xbbff, 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, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xfbff, 0xbfd5, 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,
@@ -82,23 +82,23 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xb70f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
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, 0xbeff, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbeaf, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7ffd, 0x0ddf, 0xb598, 0x5e74,
0x7fff, 0xffff, 0xb6ff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xb65f, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7ffc, 0x0ddd, 0xbd99, 0x1e6a,
0x7fff, 0xffff, 0xbfaf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f08, 0x388f, 0xb89e, 0x887f,
0x7bff, 0xffff, 0xb7f7, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
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, 0xbff7, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
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,
@@ -108,83 +108,83 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xffff,
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, 0xedff, 0xbfff, 0xffde, 0x7ffb, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xb7fd, 0xfff7, 0x7fff, 0xfdfb, 0xb7ff, 0xffff,
0x7fff, 0xfdff, 0xbfff, 0xffff, 0x7ffe, 0xffff, 0xbff3, 0xbbf7,
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, 0xffbe, 0x7ffb, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfee, 0xf7f7, 0x7fff, 0xfbef, 0xbfff, 0xffff,
0x7fff, 0xfbfe, 0xbdff, 0xfadf, 0x7dff, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xb7ff, 0x6fff, 0x77ff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xfff7, 0xafff, 0xbfef, 0x7fff, 0xffff, 0xbfff, 0xfffb,
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, 0x7eff, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbbdf, 0xbbf7, 0x7fff, 0xffef, 0xbfff, 0xffff,
0x7fff, 0xfbf9, 0xb5ff, 0xfcff, 0x7fff, 0xffff, 0xbfff, 0xfffb,
0x7fff, 0xffff, 0xbeff, 0xff77, 0x7fff, 0xf7fd, 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, 0xbbaf, 0xffff, 0x6fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xf77f, 0xbfff, 0xd7f7, 0x6eff, 0xffff, 0xbfff, 0xffff,
0x7bff, 0xffff, 0xbb5f, 0xffff, 0x7ff7, 0x7fff, 0xbfff, 0xffff,
0x7fff, 0xfff7, 0xaaff, 0xf77f, 0x7fff, 0xffff, 0xbfff, 0xfff4,
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, 0xf7be, 0xbbff, 0xffff, 0x6dff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xf7ba, 0xb37f, 0xeeff, 0x6fff, 0xffff, 0xbfff, 0xffff,
0x7bff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xfeff, 0xbfbf, 0xfff3, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7f7f, 0xff7f, 0xbfff, 0xffff,
0x7fff, 0xffef, 0xbfff, 0xffbf, 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, 0x7bff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xb5af, 0xbfff, 0x6ff7, 0x76ff, 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, 0x6cff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbf5f, 0x3000, 0x67c0, 0x007f, 0xbfff, 0xffef,
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, 0xb7af, 0x3000, 0x66e0, 0x0061, 0xbfff, 0xffdf,
0x6bff, 0xffff, 0xb7ff, 0x3000, 0x66e0, 0x0601, 0xbfff, 0xffdf,
0x7fff, 0xfccd, 0xbbbe, 0xd519, 0x7cff, 0xffff, 0xafff, 0xffff,
0x7dff, 0xffff, 0xbdff, 0x3000, 0x67e0, 0x007f, 0xbfff, 0xffff,
0x7fff, 0xfcc8, 0xb11f, 0xcc99, 0x7cff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbbbf, 0x3000, 0x67e0, 0x0061, 0xbfff, 0xffff,
0x7fff, 0xf698, 0xb11f, 0x8033, 0x66ff, 0xffff, 0xbfff, 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, 0xb77f, 0x3333, 0x6546, 0x6667, 0xb777, 0x74ab,
0x7fff, 0xffff, 0xb7ff, 0x3333, 0x6546, 0x6667, 0xb777, 0x74ab,
0x7777, 0x7d9c, 0xb995, 0x19cd, 0x79dd, 0xddd2, 0xb5dd, 0xddff,
0x7bff, 0xffff, 0xbffb, 0xfddd, 0x7fdd, 0xddff, 0xbfff, 0xffef,
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, 0xfff9, 0xbbdf, 0xddff, 0x7bbf, 0xbfff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfff7, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xfdff, 0xbfff, 0xfffd, 0x6fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbffe, 0xfffb, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfbf, 0xfffd, 0x6fff, 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, 0xfef5, 0xbbff, 0xbdff, 0x77bf, 0xbfff, 0xbfff, 0xffef,
0x7fff, 0xfedf, 0xbbff, 0xbdff, 0x77bf, 0xffff, 0xbfff, 0xffef,
0x7dff, 0xffff, 0xbfbf, 0xffef, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7ffd, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xdfff, 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, 0xdfbf, 0xbfff, 0xfdff,
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, 0xbf7f, 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, 0xbfbf, 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, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffd,
0x7bff, 0xffff, 0xb7ff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7bff, 0xffff, 0xb77f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbf7f, 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,
@@ -198,17 +198,17 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xa95f, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xa59f, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfff5,
0x69ff, 0xffff, 0xa7ff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x69ff, 0xffff, 0xab7f, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff,
0x7dff, 0xffff, 0xbd9f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbddf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbaff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
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, 0xb7ff, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab,
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,
@@ -220,29 +220,29 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xffff,
0x7dff, 0xffff, 0xbbbf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xdfff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbeff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xefff,
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, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xefff,
0x7fff, 0xffff, 0xbfff, 0xff7f, 0x7fff, 0xffff, 0xbfff, 0xefff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbeff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 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, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbeff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf,
0x7fff, 0xffff, 0xaddf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xad5f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x69ff, 0xffff, 0xab7f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x69ff, 0xffff, 0xabff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbddf, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xbd9f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x69ff, 0xffff, 0xb63f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
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,
@@ -250,55 +250,55 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xbf0f, 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, 0xb6ff, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xb6af, 0xffff, 0x7fdf, 0xffff, 0xbfff, 0xffef,
0x7fff, 0xffff, 0xbfff, 0x7fff, 0x7fff, 0xffff, 0xb7ff, 0xfffe,
0x7bff, 0xffff, 0xb95f, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7bff, 0xffff, 0xb9ff, 0xffff, 0x7fbf, 0xffff, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffeb,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbf5f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfffe,
0x77ff, 0xffff, 0xb69f, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
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, 0xb7bf, 0x7777, 0x6957, 0x7777, 0xb777, 0x74ab,
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, 0xbeff, 0xffff,
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, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xff5f,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x6ff7, 0xffff, 0xbf7f, 0xfeff,
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, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfffb, 0x7ff7, 0xffff, 0xbfff, 0xffbf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xbffe, 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, 0x7fff, 0xdff7, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbdfd, 0xffff, 0x6fff, 0xdff7, 0xbfff, 0x7fff,
0x7fff, 0xefff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffbf, 0x7fff, 0xfdff, 0xbffe, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfffb, 0x7ffb, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfee, 0x75ff, 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, 0xb7ff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff,
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, 0xb7df, 0xb5ff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfdb, 0xb5ff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffbf,
0x7fff, 0xffff, 0xb65f, 0xefff, 0x7fff, 0x7fff, 0xbfff, 0xffff,
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, 0xb7ff, 0xfdff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7dff, 0xffff, 0xb7af, 0xfdff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xfff5,
0x6bff, 0xffff, 0xbd0f, 0xffff, 0x7ff7, 0xffdf, 0xbfff, 0xffff,
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,
@@ -307,14 +307,14 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xfffe,
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,
0x65ff, 0xffff, 0xafff, 0xc2bf, 0x47a6, 0x1ebf, 0xbfff, 0xffdf,
0x67ff, 0xffff, 0xafff, 0xc2bf, 0x47a6, 0x1ebf, 0xbfff, 0xffdf,
0x7fff, 0xffff, 0xbffe, 0xffff, 0x7fff, 0xffff, 0xafff, 0xffff,
0x5dff, 0xffff, 0xb55f, 0xfe7f, 0x67e6, 0x1f3f, 0xbfff, 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,
@@ -324,11 +324,11 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xfeff, 0x77ff, 0xffff, 0xbfff, 0xefff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x77ff, 0xffff, 0xbfff, 0xefff,
0x7fff, 0xffff, 0xbf7f, 0xfff7, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xffff, 0x7ff7, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x9fff, 0xfffd, 0x7ff7, 0xffff, 0xbfff, 0xffff,
0x7fdf, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xff7f, 0xbfff, 0xffff,
0x7fff, 0xffff, 0x8fff, 0xfdff, 0x4ff7, 0xffff, 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,
@@ -383,7 +383,7 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xffbf, 0x9fff, 0xfff7,
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,
@@ -391,18 +391,18 @@ const std::array<uint16_t, 3328> block_0 { {
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, 0xffbf, 0x9fff, 0xffff,
0x5fff, 0xefff, 0xbfff, 0xffef, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xf7ff,
0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fff, 0xffff, 0xbfff, 0xffff,
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, 0xe7ff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7fef, 0xffff, 0x9fff, 0xefff,
0x5fff, 0xefff, 0xbfff, 0xdfff, 0x7fff, 0xffff, 0x9fff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffbe, 0x7fff, 0xbdff, 0xbfff, 0xffff,
0x5fff, 0xffff, 0xbfff, 0xffbd, 0x7fff, 0xbdff, 0xbfff, 0xf7ff,
0x7fff, 0xefff, 0x9fff, 0xffff, 0x5fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xfffd, 0x7ff7, 0xfdff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xffff, 0x7ff7, 0xfdff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xdfff, 0x7fff, 0xffff, 0xbfff, 0xffff,
0x7fff, 0xffff, 0xbfff, 0xff7f, 0x7fff, 0xdfff, 0xbfff, 0xd7ff,
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,
+2 -2
View File
@@ -36,8 +36,8 @@ namespace portapack {
constexpr GPIO gpio_io_stbx = gpio[GPIO5_0]; /* P2_0 */
constexpr GPIO gpio_addr = gpio[GPIO5_1]; /* P2_1 */
constexpr GPIO gpio_lcd_te = gpio[GPIO5_3]; /* P2_3 */
constexpr GPIO gpio_unused = gpio[GPIO5_4]; /* P2_4 */
constexpr GPIO gpio_lcd_rd = gpio[GPIO5_7]; /* P2_8 */
constexpr GPIO gpio_unused = gpio[GPIO5_7]; /* P2_8 */
constexpr GPIO gpio_lcd_rd = gpio[GPIO5_4]; /* P2_4 */
constexpr GPIO gpio_lcd_wr = gpio[GPIO1_10]; /* P2_9 */
constexpr GPIO gpio_dir = gpio[GPIO1_13]; /* P2_13 */
constexpr std::array<GPIO, 8> gpios_data {
+10 -1
View File
@@ -21,4 +21,13 @@
#include "portapack_shared_memory.hpp"
SharedMemory& shared_memory = *reinterpret_cast<SharedMemory*>(0x10088000);
#include "memory_map.hpp"
SharedMemory& shared_memory = *reinterpret_cast<SharedMemory*>(
portapack::memory::map::shared_memory.base()
);
static_assert(
sizeof(SharedMemory) <= portapack::memory::map::shared_memory.size(),
"SharedMemory is too large"
);
+4 -4
View File
@@ -39,8 +39,8 @@ struct JammerRange {
/* NOTE: These structures must be located in the same location in both M4 and M0 binaries */
struct SharedMemory {
MessageQueue baseband_queue;
MessageQueue application_queue;
MessageQueue<12> baseband_queue;
MessageQueue<11> application_queue;
// TODO: M0 should directly configure and control DMA channel that is
// acquiring ADC samples.
@@ -65,8 +65,8 @@ extern SharedMemory& shared_memory;
#if defined(LPC43XX_M0)
inline void init_message_queues() {
new (&shared_memory.baseband_queue) MessageQueue();
new (&shared_memory.application_queue) MessageQueue();
new (&shared_memory.baseband_queue) MessageQueue<12>();
new (&shared_memory.application_queue) MessageQueue<11>();
}
#endif
+149
View File
@@ -0,0 +1,149 @@
/*
* Copyright (C) 2015 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 __SINE_TABLE_H__
#define __SINE_TABLE_H__
// TODO: Including only for pi. Need separate math.hpp...
#include "complex.hpp"
#include <array>
#include <cmath>
/*
import numpy
length = 256
w = numpy.arange(length, dtype=numpy.float64) * (2 * numpy.pi / length)
v = numpy.sin(w)
print(v)
*/
constexpr size_t sine_table_f32_period_log2 = 8;
constexpr size_t sine_table_f32_period = 1 << sine_table_f32_period_log2;
constexpr uint32_t sine_table_f32_index_mask = sine_table_f32_period - 1;
constexpr std::array<float, sine_table_f32_period + 1> sine_table_f32 { {
0.00000000e+00, 2.45412285e-02, 4.90676743e-02,
7.35645636e-02, 9.80171403e-02, 1.22410675e-01,
1.46730474e-01, 1.70961889e-01, 1.95090322e-01,
2.19101240e-01, 2.42980180e-01, 2.66712757e-01,
2.90284677e-01, 3.13681740e-01, 3.36889853e-01,
3.59895037e-01, 3.82683432e-01, 4.05241314e-01,
4.27555093e-01, 4.49611330e-01, 4.71396737e-01,
4.92898192e-01, 5.14102744e-01, 5.34997620e-01,
5.55570233e-01, 5.75808191e-01, 5.95699304e-01,
6.15231591e-01, 6.34393284e-01, 6.53172843e-01,
6.71558955e-01, 6.89540545e-01, 7.07106781e-01,
7.24247083e-01, 7.40951125e-01, 7.57208847e-01,
7.73010453e-01, 7.88346428e-01, 8.03207531e-01,
8.17584813e-01, 8.31469612e-01, 8.44853565e-01,
8.57728610e-01, 8.70086991e-01, 8.81921264e-01,
8.93224301e-01, 9.03989293e-01, 9.14209756e-01,
9.23879533e-01, 9.32992799e-01, 9.41544065e-01,
9.49528181e-01, 9.56940336e-01, 9.63776066e-01,
9.70031253e-01, 9.75702130e-01, 9.80785280e-01,
9.85277642e-01, 9.89176510e-01, 9.92479535e-01,
9.95184727e-01, 9.97290457e-01, 9.98795456e-01,
9.99698819e-01, 1.00000000e+00, 9.99698819e-01,
9.98795456e-01, 9.97290457e-01, 9.95184727e-01,
9.92479535e-01, 9.89176510e-01, 9.85277642e-01,
9.80785280e-01, 9.75702130e-01, 9.70031253e-01,
9.63776066e-01, 9.56940336e-01, 9.49528181e-01,
9.41544065e-01, 9.32992799e-01, 9.23879533e-01,
9.14209756e-01, 9.03989293e-01, 8.93224301e-01,
8.81921264e-01, 8.70086991e-01, 8.57728610e-01,
8.44853565e-01, 8.31469612e-01, 8.17584813e-01,
8.03207531e-01, 7.88346428e-01, 7.73010453e-01,
7.57208847e-01, 7.40951125e-01, 7.24247083e-01,
7.07106781e-01, 6.89540545e-01, 6.71558955e-01,
6.53172843e-01, 6.34393284e-01, 6.15231591e-01,
5.95699304e-01, 5.75808191e-01, 5.55570233e-01,
5.34997620e-01, 5.14102744e-01, 4.92898192e-01,
4.71396737e-01, 4.49611330e-01, 4.27555093e-01,
4.05241314e-01, 3.82683432e-01, 3.59895037e-01,
3.36889853e-01, 3.13681740e-01, 2.90284677e-01,
2.66712757e-01, 2.42980180e-01, 2.19101240e-01,
1.95090322e-01, 1.70961889e-01, 1.46730474e-01,
1.22410675e-01, 9.80171403e-02, 7.35645636e-02,
4.90676743e-02, 2.45412285e-02, 1.22464680e-16,
-2.45412285e-02, -4.90676743e-02, -7.35645636e-02,
-9.80171403e-02, -1.22410675e-01, -1.46730474e-01,
-1.70961889e-01, -1.95090322e-01, -2.19101240e-01,
-2.42980180e-01, -2.66712757e-01, -2.90284677e-01,
-3.13681740e-01, -3.36889853e-01, -3.59895037e-01,
-3.82683432e-01, -4.05241314e-01, -4.27555093e-01,
-4.49611330e-01, -4.71396737e-01, -4.92898192e-01,
-5.14102744e-01, -5.34997620e-01, -5.55570233e-01,
-5.75808191e-01, -5.95699304e-01, -6.15231591e-01,
-6.34393284e-01, -6.53172843e-01, -6.71558955e-01,
-6.89540545e-01, -7.07106781e-01, -7.24247083e-01,
-7.40951125e-01, -7.57208847e-01, -7.73010453e-01,
-7.88346428e-01, -8.03207531e-01, -8.17584813e-01,
-8.31469612e-01, -8.44853565e-01, -8.57728610e-01,
-8.70086991e-01, -8.81921264e-01, -8.93224301e-01,
-9.03989293e-01, -9.14209756e-01, -9.23879533e-01,
-9.32992799e-01, -9.41544065e-01, -9.49528181e-01,
-9.56940336e-01, -9.63776066e-01, -9.70031253e-01,
-9.75702130e-01, -9.80785280e-01, -9.85277642e-01,
-9.89176510e-01, -9.92479535e-01, -9.95184727e-01,
-9.97290457e-01, -9.98795456e-01, -9.99698819e-01,
-1.00000000e+00, -9.99698819e-01, -9.98795456e-01,
-9.97290457e-01, -9.95184727e-01, -9.92479535e-01,
-9.89176510e-01, -9.85277642e-01, -9.80785280e-01,
-9.75702130e-01, -9.70031253e-01, -9.63776066e-01,
-9.56940336e-01, -9.49528181e-01, -9.41544065e-01,
-9.32992799e-01, -9.23879533e-01, -9.14209756e-01,
-9.03989293e-01, -8.93224301e-01, -8.81921264e-01,
-8.70086991e-01, -8.57728610e-01, -8.44853565e-01,
-8.31469612e-01, -8.17584813e-01, -8.03207531e-01,
-7.88346428e-01, -7.73010453e-01, -7.57208847e-01,
-7.40951125e-01, -7.24247083e-01, -7.07106781e-01,
-6.89540545e-01, -6.71558955e-01, -6.53172843e-01,
-6.34393284e-01, -6.15231591e-01, -5.95699304e-01,
-5.75808191e-01, -5.55570233e-01, -5.34997620e-01,
-5.14102744e-01, -4.92898192e-01, -4.71396737e-01,
-4.49611330e-01, -4.27555093e-01, -4.05241314e-01,
-3.82683432e-01, -3.59895037e-01, -3.36889853e-01,
-3.13681740e-01, -2.90284677e-01, -2.66712757e-01,
-2.42980180e-01, -2.19101240e-01, -1.95090322e-01,
-1.70961889e-01, -1.46730474e-01, -1.22410675e-01,
-9.80171403e-02, -7.35645636e-02, -4.90676743e-02,
-2.45412285e-02, 0.00000000e+00,
} };
inline float sin_f32(const float w) {
constexpr float normalize = 1.0 / (2 * pi);
const float x = w * normalize;
const int32_t x_int = std::floor(x);
const float x_frac = x - x_int;
const float n = x_frac * sine_table_f32_period;
const int32_t n_int = static_cast<uint32_t>(n) & sine_table_f32_index_mask;
const float n_frac = n - n_int;
const float p0 = sine_table_f32[n_int + 0];
const float p1 = sine_table_f32[n_int + 1];
const float diff = p1 - p0;
const float result = p0 + n_frac * diff;
return result;
}
#endif/*__SINE_TABLE_H__*/
+4 -7
View File
@@ -25,7 +25,7 @@
#include <cstdint>
#include <cstddef>
#include "hal.h"
#include "memory_map.hpp"
namespace portapack {
namespace spi_flash {
@@ -34,8 +34,8 @@ struct region_t {
const size_t offset;
const size_t size;
constexpr const void* base_address() {
return reinterpret_cast<void*>(LPC_SPIFI_DATA_CACHED_BASE + offset);
constexpr const void* base() {
return reinterpret_cast<void*>(portapack::memory::map::spifi_cached.base() + offset);
}
};
@@ -45,7 +45,7 @@ constexpr region_t bootstrap {
};
constexpr region_t hackrf {
.offset = 0x10010, // Image starts at 0x10 into .dfu file.
.offset = 0x10000,
.size = 0x8000,
};
@@ -59,9 +59,6 @@ constexpr region_t application {
.size = 0x40000,
};
// TODO: Refactor into another header that defines memory regions.
constexpr void* m4_text_ram_base = reinterpret_cast<void*>(0x10080000);
} /* namespace spi_flash */
} /* namespace portapack */
+34
View File
@@ -21,6 +21,8 @@
#include "ui_painter.hpp"
#include "ui_widget.hpp"
#include "portapack.hpp"
using namespace portapack;
@@ -71,4 +73,36 @@ void Painter::fill_rectangle(const Rect r, const Color c) {
display.fill_rectangle(r, c);
}
void Painter::paint_widget_tree(Widget* const w) {
if( ui::is_dirty() ) {
paint_widget(w);
ui::dirty_clear();
}
}
void Painter::paint_widget(Widget* const w) {
if( w->hidden() ) {
// Mark widget (and all children) as invisible.
w->visible(false);
} else {
// Mark this widget as visible and recurse.
w->visible(true);
if( w->dirty() ) {
w->paint(*this);
// Force-paint all children.
for(const auto child : w->children()) {
child->set_dirty();
paint_widget(child);
}
w->set_clean();
} else {
// Selectively paint all children.
for(const auto child : w->children()) {
paint_widget(child);
}
}
}
}
} /* namespace ui */
+6
View File
@@ -37,6 +37,8 @@ struct Style {
Style invert() const;
};
class Widget;
class Painter {
public:
Painter() { };
@@ -51,9 +53,13 @@ public:
void draw_rectangle(const Rect r, const Color c);
void fill_rectangle(const Rect r, const Color c);
void paint_widget_tree(Widget* const w);
private:
void draw_hline(Point p, size_t width, const Color c);
void draw_vline(Point p, size_t height, const Color c);
void paint_widget(Widget* const w);
};
} /* namespace ui */
+31 -13
View File
@@ -29,6 +29,20 @@
namespace ui {
static bool ui_dirty = true;
void dirty_set() {
ui_dirty = true;
}
void dirty_clear() {
ui_dirty = false;
}
bool is_dirty() {
return ui_dirty;
}
constexpr size_t to_string_max_length = 16;
static char* to_string_dec_uint_internal(
@@ -156,7 +170,7 @@ void Widget::set_parent(Widget* const widget) {
void Widget::set_dirty() {
flags.dirty = true;
dirty_event();
dirty_set();
}
bool Widget::dirty() const {
@@ -187,7 +201,7 @@ void Widget::hidden(bool hide) {
}
void Widget::focus() {
context().focus_manager.set_focus_widget(this);
context().focus_manager().set_focus_widget(this);
}
void Widget::on_focus() {
@@ -195,7 +209,7 @@ void Widget::on_focus() {
}
void Widget::blur() {
context().focus_manager.set_focus_widget(nullptr);
context().focus_manager().set_focus_widget(nullptr);
}
void Widget::on_blur() {
@@ -207,7 +221,7 @@ bool Widget::focusable() const {
}
bool Widget::has_focus() {
return (context().focus_manager.focus_widget() == this);
return (context().focus_manager().focus_widget() == this);
}
Widget* Widget::last_child_focus() const {
@@ -291,10 +305,12 @@ void View::paint(Painter& painter) {
}
void View::add_child(Widget* const widget) {
if( widget->parent() == nullptr ) {
widget->set_parent(this);
children_.push_back(widget);
widget->set_dirty();
if( widget ) {
if( widget->parent() == nullptr ) {
widget->set_parent(this);
children_.push_back(widget);
widget->set_dirty();
}
}
}
@@ -305,11 +321,13 @@ void View::add_children(const std::vector<Widget*>& children) {
}
void View::remove_child(Widget* const widget) {
children_.erase(std::remove(children_.begin(), children_.end(), widget), children_.end());
dirty_screen_rect += widget->screen_rect();
widget->set_parent(nullptr);
if( dirty_screen_rect ) {
set_dirty();
if( widget ) {
children_.erase(std::remove(children_.begin(), children_.end(), widget), children_.end());
dirty_screen_rect += widget->screen_rect();
widget->set_parent(nullptr);
if( dirty_screen_rect ) {
set_dirty();
}
}
}
+16 -4
View File
@@ -37,7 +37,9 @@
namespace ui {
extern void dirty_event();
void dirty_set();
void dirty_clear();
bool is_dirty();
// TODO: Move these somewhere else!
// TODO: Allow l=0 to not fill/justify? Already using this way in ui_spectrum.hpp...
@@ -45,9 +47,19 @@ std::string to_string_dec_uint(const uint32_t n, const int32_t l = 0, const char
std::string to_string_dec_int(const int32_t n, const int32_t l = 0, const char fill = 0);
std::string to_string_hex(const uint32_t n, const int32_t l = 0);
struct Context {
FocusManager focus_manager;
MessageHandlerMap message_map;
class Context {
public:
FocusManager& focus_manager() {
return focus_manager_;
}
MessageHandlerMap& message_map() {
return message_map_;
}
private:
FocusManager focus_manager_;
MessageHandlerMap message_map_;
};
class Widget {
-21
View File
@@ -19,8 +19,6 @@
* Boston, MA 02110-1301, USA.
*/
#include <ch.h>
#include "utility.hpp"
#include <cstdint>
@@ -115,22 +113,3 @@ static constexpr uint32_t gcd_top(const uint32_t u, const uint32_t v) {
uint32_t gcd(const uint32_t u, const uint32_t v) {
return gcd_top(u, v);
}
/* Memory management, overriding toolchain new, which uses malloc */
/* TODO: Move to something like "memory.cpp"! Not utility.cpp. */
void* operator new(size_t size) {
return chHeapAlloc(0x0, size);
}
void* operator new[](size_t size) {
return chHeapAlloc(0x0, size);
}
void operator delete(void* p) noexcept {
chHeapFree(p);
}
void operator delete[](void* p) noexcept {
chHeapFree(p);
}
+8 -21
View File
@@ -28,10 +28,16 @@
#include <complex>
#include <memory>
#include <hal.h>
#define LOCATE_IN_RAM __attribute__((section(".ramtext")))
constexpr size_t operator "" _KiB(unsigned long long v) {
return v * 1024;
}
constexpr size_t operator "" _MiB(unsigned long long v) {
return v * 1024 * 1024;
}
template<typename E>
constexpr typename std::underlying_type<E>::type toUType(E enumerator) noexcept {
/* Thanks, Scott Meyers! */
@@ -54,18 +60,6 @@ inline constexpr T pow(const T base, unsigned const exponent) {
return (exponent == 0) ? 1 : (base * pow(base, exponent - 1));
}
#if defined(LPC43XX_M4)
static inline bool m4_flag_saturation() {
return __get_APSR() & (1U << 27);
}
static inline void clear_m4_flag_saturation() {
uint32_t flags = 1;
__asm volatile ("MSR APSR_nzcvqg, %0" : : "r" (flags));
}
#endif
float complex16_mag_squared_to_dbv_norm(const float c16_mag_squared);
inline float magnitude_squared(const std::complex<float> c) {
@@ -76,13 +70,6 @@ inline float magnitude_squared(const std::complex<float> c) {
return r2 + i2;
}
/* Override new/delete to use Chibi/OS heap functions */
/* NOTE: Do not inline these, it doesn't work. ;-) */
void* operator new(size_t size);
void* operator new[](size_t size);
void operator delete(void* p);
void operator delete[](void* p);
namespace std {
/*! Stephan T Lavavej (STL!) implementation of make_unique, which has been accepted into the C++14 standard.
+53
View File
@@ -0,0 +1,53 @@
/*
* 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 __UTILITY_M4_H__
#define __UTILITY_M4_H__
#if defined(LPC43XX_M4)
#include <hal.h>
static inline bool m4_flag_saturation() {
return __get_APSR() & (1U << 27);
}
static inline void clear_m4_flag_saturation() {
uint32_t flags = 1;
__asm volatile ("MSR APSR_nzcvqg, %0" : : "r" (flags));
}
static inline complex32_t multiply_conjugate_s16_s32(const complex16_t::rep_type a, const complex16_t::rep_type b) {
// conjugate: conj(a + bj) = a - bj
// multiply: (a + bj) * (c + dj) = (ac - bd) + (bc + ad)j
// conjugate-multiply: (ac + bd) + (bc - ad)j
//return { a.real() * b.real() + a.imag() * b.imag(), a.imag() * b.real() - a.real() * b.imag() };
const int32_t rr = __SMULBB(a, b);
const int32_t ii = __SMULTT(a, b);
const int32_t r = __QADD(rr, ii);
const int32_t ir = __SMULTB(a, b);
const int32_t ri = __SMULBT(a, b);
const int32_t i = __QSUB(ir, ri);
return { r, i };
}
#endif /* defined(LPC43XX_M4) */
#endif/*__UTILITY_M4_H__*/