mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-10 16:49:36 +00:00
Merged remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -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 */
|
||||
@@ -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__*/
|
||||
@@ -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__*/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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__*/
|
||||
@@ -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__*/
|
||||
|
||||
@@ -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,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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__*/
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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__*/
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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__*/
|
||||
Reference in New Issue
Block a user