mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 23:09:26 -05:00
Added support for multiple sample rates in IQ record
Support for any sample rate <= 500k in IQ replay Fixed bias-t power not activating in TX Removed RSSI pitch output option (awful code) Udated binary
This commit is contained in:
parent
57c759627d
commit
7fd987a2b4
@ -35,6 +35,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
|
|||||||
baseband::run_image(portapack::spi_flash::image_tag_capture);
|
baseband::run_image(portapack::spi_flash::image_tag_capture);
|
||||||
|
|
||||||
add_children({
|
add_children({
|
||||||
|
&labels,
|
||||||
&rssi,
|
&rssi,
|
||||||
&channel,
|
&channel,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
@ -42,6 +43,7 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
|
|||||||
&field_rf_amp,
|
&field_rf_amp,
|
||||||
&field_lna,
|
&field_lna,
|
||||||
&field_vga,
|
&field_vga,
|
||||||
|
&option_bandwidth,
|
||||||
&record_view,
|
&record_view,
|
||||||
&waterfall,
|
&waterfall,
|
||||||
});
|
});
|
||||||
@ -65,6 +67,16 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
|
|||||||
receiver_model.set_frequency_step(v);
|
receiver_model.set_frequency_step(v);
|
||||||
this->field_frequency.set_step(v);
|
this->field_frequency.set_step(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
option_bandwidth.on_change = [this](size_t, uint32_t divider) {
|
||||||
|
sampling_rate = 4000000 / divider;
|
||||||
|
|
||||||
|
waterfall.on_hide();
|
||||||
|
set_target_frequency(target_frequency());
|
||||||
|
record_view.set_sampling_rate(sampling_rate);
|
||||||
|
radio::set_baseband_rate(sampling_rate);
|
||||||
|
waterfall.on_show();
|
||||||
|
};
|
||||||
|
|
||||||
radio::enable({
|
radio::enable({
|
||||||
tuning_frequency(),
|
tuning_frequency(),
|
||||||
@ -75,8 +87,9 @@ CaptureAppView::CaptureAppView(NavigationView& nav) {
|
|||||||
static_cast<int8_t>(receiver_model.lna()),
|
static_cast<int8_t>(receiver_model.lna()),
|
||||||
static_cast<int8_t>(receiver_model.vga()),
|
static_cast<int8_t>(receiver_model.vga()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
option_bandwidth.set_selected_index(4); // 500k
|
||||||
|
|
||||||
record_view.set_sampling_rate(sampling_rate / 8);
|
|
||||||
record_view.on_error = [&nav](std::string message) {
|
record_view.on_error = [&nav](std::string message) {
|
||||||
nav.display_modal("Error", message);
|
nav.display_modal("Error", message);
|
||||||
};
|
};
|
||||||
|
@ -47,9 +47,9 @@ public:
|
|||||||
std::string title() const override { return "Capture"; };
|
std::string title() const override { return "Capture"; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr ui::Dim header_height = 2 * 16;
|
static constexpr ui::Dim header_height = 3 * 16;
|
||||||
|
|
||||||
static constexpr uint32_t sampling_rate = 4000000;
|
uint32_t sampling_rate = 0;
|
||||||
static constexpr uint32_t baseband_bandwidth = 2500000;
|
static constexpr uint32_t baseband_bandwidth = 2500000;
|
||||||
|
|
||||||
void on_target_frequency_changed(rf::Frequency f);
|
void on_target_frequency_changed(rf::Frequency f);
|
||||||
@ -59,6 +59,10 @@ private:
|
|||||||
|
|
||||||
rf::Frequency tuning_frequency() const;
|
rf::Frequency tuning_frequency() const;
|
||||||
|
|
||||||
|
Labels labels {
|
||||||
|
{ { 0 * 8, 1 * 16 }, "Rate:", Color::light_grey() },
|
||||||
|
};
|
||||||
|
|
||||||
RSSI rssi {
|
RSSI rssi {
|
||||||
{ 24 * 8, 0, 6 * 8, 4 },
|
{ 24 * 8, 0, 6 * 8, 4 },
|
||||||
};
|
};
|
||||||
@ -87,8 +91,20 @@ private:
|
|||||||
{ 21 * 8, 0 * 16 }
|
{ 21 * 8, 0 * 16 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
OptionsField option_bandwidth {
|
||||||
|
{ 5 * 8, 1 * 16 },
|
||||||
|
4,
|
||||||
|
{
|
||||||
|
{ " 25k", 20 },
|
||||||
|
{ " 50k", 10 },
|
||||||
|
{ "100k", 5 },
|
||||||
|
{ "250k", 2 },
|
||||||
|
{ "500k", 1 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
RecordView record_view {
|
RecordView record_view {
|
||||||
{ 0 * 8, 1 * 16, 30 * 8, 1 * 16 },
|
{ 0 * 8, 2 * 16, 30 * 8, 1 * 16 },
|
||||||
u"BBD_????", RecordView::FileType::RawS16, 16384, 3
|
u"BBD_????", RecordView::FileType::RawS16, 16384, 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,30 +51,40 @@ void ReplayAppView::on_file_changed(std::filesystem::path new_file_path) {
|
|||||||
|
|
||||||
file_path = new_file_path;
|
file_path = new_file_path;
|
||||||
|
|
||||||
auto file_size = data_file.size();
|
|
||||||
auto duration = (file_size * 1000) / (2 * 2 * sampling_rate / 8);
|
|
||||||
|
|
||||||
progressbar.set_max(file_size);
|
|
||||||
text_filename.set(file_path.filename().string().substr(0, 19));
|
|
||||||
text_duration.set(to_string_time_ms(duration));
|
|
||||||
|
|
||||||
// Get original record frequency if available
|
// Get original record frequency if available
|
||||||
std::filesystem::path info_file_path = file_path;
|
std::filesystem::path info_file_path = file_path;
|
||||||
info_file_path.replace_extension(u".TXT");
|
info_file_path.replace_extension(u".TXT");
|
||||||
|
|
||||||
|
sample_rate = 500000;
|
||||||
|
|
||||||
auto info_open_error = info_file.open("/" + info_file_path.string());
|
auto info_open_error = info_file.open("/" + info_file_path.string());
|
||||||
if (!info_open_error.is_valid()) {
|
if (!info_open_error.is_valid()) {
|
||||||
memset(file_data, 0, 257);
|
memset(file_data, 0, 257);
|
||||||
auto read_size = info_file.read(file_data, 256);
|
auto read_size = info_file.read(file_data, 256);
|
||||||
if (!read_size.is_error()) {
|
if (!read_size.is_error()) {
|
||||||
auto pos = strstr(file_data, "center_frequency=");
|
auto pos1 = strstr(file_data, "center_frequency=");
|
||||||
if (pos) {
|
if (pos1) {
|
||||||
pos += 17;
|
pos1 += 17;
|
||||||
field_frequency.set_value(strtoll(pos, nullptr, 10));
|
field_frequency.set_value(strtoll(pos1, nullptr, 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pos2 = strstr(file_data, "sample_rate=");
|
||||||
|
if (pos2) {
|
||||||
|
pos2 += 12;
|
||||||
|
sample_rate = strtoll(pos2, nullptr, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text_sample_rate.set(unit_auto_scale(sample_rate, 3, 0) + "Hz");
|
||||||
|
|
||||||
|
auto file_size = data_file.size();
|
||||||
|
auto duration = (file_size * 1000) / (2 * 2 * sample_rate);
|
||||||
|
|
||||||
|
progressbar.set_max(file_size);
|
||||||
|
text_filename.set(file_path.filename().string().substr(0, 12));
|
||||||
|
text_duration.set(to_string_time_ms(duration));
|
||||||
|
|
||||||
button_play.focus();
|
button_play.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +127,8 @@ void ReplayAppView::start() {
|
|||||||
|
|
||||||
if( reader ) {
|
if( reader ) {
|
||||||
button_play.set_bitmap(&bitmap_stop);
|
button_play.set_bitmap(&bitmap_stop);
|
||||||
|
baseband::set_sample_rate(sample_rate * 8);
|
||||||
|
|
||||||
replay_thread = std::make_unique<ReplayThread>(
|
replay_thread = std::make_unique<ReplayThread>(
|
||||||
std::move(reader),
|
std::move(reader),
|
||||||
read_size, buffer_count,
|
read_size, buffer_count,
|
||||||
@ -130,7 +142,7 @@ void ReplayAppView::start() {
|
|||||||
|
|
||||||
radio::enable({
|
radio::enable({
|
||||||
receiver_model.tuning_frequency(),
|
receiver_model.tuning_frequency(),
|
||||||
sampling_rate,
|
sample_rate * 8 ,
|
||||||
baseband_bandwidth,
|
baseband_bandwidth,
|
||||||
rf::Direction::Transmit,
|
rf::Direction::Transmit,
|
||||||
receiver_model.rf_amp(),
|
receiver_model.rf_amp(),
|
||||||
@ -172,6 +184,7 @@ ReplayAppView::ReplayAppView(
|
|||||||
&labels,
|
&labels,
|
||||||
&button_open,
|
&button_open,
|
||||||
&text_filename,
|
&text_filename,
|
||||||
|
&text_sample_rate,
|
||||||
&text_duration,
|
&text_duration,
|
||||||
&progressbar,
|
&progressbar,
|
||||||
&field_frequency,
|
&field_frequency,
|
||||||
|
@ -50,7 +50,7 @@ private:
|
|||||||
|
|
||||||
static constexpr ui::Dim header_height = 3 * 16;
|
static constexpr ui::Dim header_height = 3 * 16;
|
||||||
|
|
||||||
static constexpr uint32_t sampling_rate = 4000000;
|
uint32_t sample_rate = 0;
|
||||||
static constexpr uint32_t baseband_bandwidth = 2500000;
|
static constexpr uint32_t baseband_bandwidth = 2500000;
|
||||||
const size_t read_size { 16384 };
|
const size_t read_size { 16384 };
|
||||||
const size_t buffer_count { 3 };
|
const size_t buffer_count { 3 };
|
||||||
@ -76,7 +76,6 @@ private:
|
|||||||
|
|
||||||
Labels labels {
|
Labels labels {
|
||||||
{ { 10 * 8, 2 * 16 }, "LNA: A:", Color::light_grey() }
|
{ { 10 * 8, 2 * 16 }, "LNA: A:", Color::light_grey() }
|
||||||
//{ { 10 * 8, 2 * 16 }, "500ksps", Color::light_grey() }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Button button_open {
|
Button button_open {
|
||||||
@ -85,9 +84,14 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
Text text_filename {
|
Text text_filename {
|
||||||
{ 11 * 8, 0 * 16, 19 * 8, 16 },
|
{ 11 * 8, 0 * 16, 12 * 8, 16 },
|
||||||
"-"
|
"-"
|
||||||
};
|
};
|
||||||
|
Text text_sample_rate {
|
||||||
|
{ 24 * 8, 0 * 16, 6 * 8, 16 },
|
||||||
|
"-"
|
||||||
|
};
|
||||||
|
|
||||||
Text text_duration {
|
Text text_duration {
|
||||||
{ 11 * 8, 1 * 16, 6 * 8, 16 },
|
{ 11 * 8, 1 * 16, 6 * 8, 16 },
|
||||||
"-"
|
"-"
|
||||||
|
@ -97,7 +97,7 @@ private:
|
|||||||
{ 1 * 8, " Windyoona Channels", 0 },
|
{ 1 * 8, " Windyoona Channels", 0 },
|
||||||
{ 1 * 8, " F4GEV Pyr3x", 0 },
|
{ 1 * 8, " F4GEV Pyr3x", 0 },
|
||||||
{ 1 * 8, " HB3YOE", 24 },
|
{ 1 * 8, " HB3YOE", 24 },
|
||||||
{ 12 * 8, "MMXVII", -1 }
|
{ 11 * 8, "MMXVIII", -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
CreditsWidget credits_display {
|
CreditsWidget credits_display {
|
||||||
|
@ -135,9 +135,9 @@ SetRadioView::SetRadioView(
|
|||||||
|
|
||||||
form_init(model);
|
form_init(model);
|
||||||
|
|
||||||
check_bias.set_value(receiver_model.antenna_bias());
|
check_bias.set_value(portapack::get_antenna_bias());
|
||||||
check_bias.on_select = [this](Checkbox&, bool v) {
|
check_bias.on_select = [this](Checkbox&, bool v) {
|
||||||
receiver_model.set_antenna_bias(v);
|
portapack::set_antenna_bias(v);
|
||||||
StatusRefreshMessage message { };
|
StatusRefreshMessage message { };
|
||||||
EventDispatcher::send_message(message);
|
EventDispatcher::send_message(message);
|
||||||
};
|
};
|
||||||
|
@ -296,6 +296,11 @@ void spectrum_streaming_stop() {
|
|||||||
send_message(&message);
|
send_message(&message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_sample_rate(const uint32_t sample_rate) {
|
||||||
|
SamplerateConfigMessage message { sample_rate };
|
||||||
|
send_message(&message);
|
||||||
|
}
|
||||||
|
|
||||||
void capture_start(CaptureConfig* const config) {
|
void capture_start(CaptureConfig* const config) {
|
||||||
CaptureConfigMessage message { config };
|
CaptureConfigMessage message { config };
|
||||||
send_message(&message);
|
send_message(&message);
|
||||||
|
@ -87,6 +87,7 @@ void shutdown();
|
|||||||
void spectrum_streaming_start();
|
void spectrum_streaming_start();
|
||||||
void spectrum_streaming_stop();
|
void spectrum_streaming_stop();
|
||||||
|
|
||||||
|
void set_sample_rate(const uint32_t sample_rate);
|
||||||
void capture_start(CaptureConfig* const config);
|
void capture_start(CaptureConfig* const config);
|
||||||
void capture_stop();
|
void capture_stop();
|
||||||
void replay_start(ReplayConfig* const config);
|
void replay_start(ReplayConfig* const config);
|
||||||
|
@ -77,12 +77,20 @@ WM8731 audio_codec_wm8731 { i2c0, 0x1a };
|
|||||||
AK4951 audio_codec_ak4951 { i2c0, 0x12 };
|
AK4951 audio_codec_ak4951 { i2c0, 0x12 };
|
||||||
|
|
||||||
ReceiverModel receiver_model;
|
ReceiverModel receiver_model;
|
||||||
|
TransmitterModel transmitter_model;
|
||||||
|
|
||||||
TemperatureLogger temperature_logger;
|
TemperatureLogger temperature_logger;
|
||||||
|
|
||||||
TransmitterModel transmitter_model;
|
bool antenna_bias { false };
|
||||||
|
uint8_t bl_tick_counter { 0 };
|
||||||
|
|
||||||
uint8_t bl_tick_counter = 0;
|
void set_antenna_bias(const bool v) {
|
||||||
|
antenna_bias = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_antenna_bias() {
|
||||||
|
return antenna_bias;
|
||||||
|
}
|
||||||
|
|
||||||
class Power {
|
class Power {
|
||||||
public:
|
public:
|
||||||
|
@ -52,9 +52,13 @@ extern ReceiverModel receiver_model;
|
|||||||
extern TransmitterModel transmitter_model;
|
extern TransmitterModel transmitter_model;
|
||||||
|
|
||||||
extern uint8_t bl_tick_counter;
|
extern uint8_t bl_tick_counter;
|
||||||
|
extern bool antenna_bias;
|
||||||
|
|
||||||
extern TemperatureLogger temperature_logger;
|
extern TemperatureLogger temperature_logger;
|
||||||
|
|
||||||
|
void set_antenna_bias(const bool v);
|
||||||
|
bool get_antenna_bias();
|
||||||
|
|
||||||
bool init();
|
bool init();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "portapack_persistent_memory.hpp"
|
#include "portapack_persistent_memory.hpp"
|
||||||
#include "hackrf_gpio.hpp"
|
#include "hackrf_gpio.hpp"
|
||||||
|
#include "portapack.hpp"
|
||||||
using namespace hackrf::one;
|
using namespace hackrf::one;
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
|
||||||
@ -72,12 +73,7 @@ void ReceiverModel::set_frequency_step(rf::Frequency f) {
|
|||||||
frequency_step_ = f;
|
frequency_step_ = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReceiverModel::antenna_bias() const {
|
void ReceiverModel::set_antenna_bias() {
|
||||||
return antenna_bias_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReceiverModel::set_antenna_bias(bool enabled) {
|
|
||||||
antenna_bias_ = enabled;
|
|
||||||
update_antenna_bias();
|
update_antenna_bias();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +176,7 @@ void ReceiverModel::enable() {
|
|||||||
|
|
||||||
void ReceiverModel::disable() {
|
void ReceiverModel::disable() {
|
||||||
enabled_ = false;
|
enabled_ = false;
|
||||||
update_antenna_bias();
|
radio::set_antenna_bias(false);
|
||||||
|
|
||||||
// TODO: Responsibility for enabling/disabling the radio is muddy.
|
// TODO: Responsibility for enabling/disabling the radio is muddy.
|
||||||
// Some happens in ReceiverModel, some inside radio namespace.
|
// Some happens in ReceiverModel, some inside radio namespace.
|
||||||
@ -201,7 +197,8 @@ void ReceiverModel::update_tuning_frequency() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ReceiverModel::update_antenna_bias() {
|
void ReceiverModel::update_antenna_bias() {
|
||||||
radio::set_antenna_bias(antenna_bias_ && enabled_);
|
if (enabled_)
|
||||||
|
radio::set_antenna_bias(portapack::get_antenna_bias());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiverModel::update_rf_amp() {
|
void ReceiverModel::update_rf_amp() {
|
||||||
|
@ -45,9 +45,8 @@ public:
|
|||||||
rf::Frequency frequency_step() const;
|
rf::Frequency frequency_step() const;
|
||||||
void set_frequency_step(rf::Frequency f);
|
void set_frequency_step(rf::Frequency f);
|
||||||
|
|
||||||
bool antenna_bias() const;
|
void set_antenna_bias();
|
||||||
void set_antenna_bias(bool enabled);
|
|
||||||
|
|
||||||
bool rf_amp() const;
|
bool rf_amp() const;
|
||||||
void set_rf_amp(bool enabled);
|
void set_rf_amp(bool enabled);
|
||||||
|
|
||||||
@ -91,7 +90,6 @@ private:
|
|||||||
rf::Frequency frequency_step_ { 25000 };
|
rf::Frequency frequency_step_ { 25000 };
|
||||||
bool enabled_ { false };
|
bool enabled_ { false };
|
||||||
bool rf_amp_ { false };
|
bool rf_amp_ { false };
|
||||||
bool antenna_bias_ { false };
|
|
||||||
int32_t lna_gain_db_ { 32 };
|
int32_t lna_gain_db_ { 32 };
|
||||||
uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum };
|
uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum };
|
||||||
int32_t vga_gain_db_ { 32 };
|
int32_t vga_gain_db_ { 32 };
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "portapack_persistent_memory.hpp"
|
#include "portapack_persistent_memory.hpp"
|
||||||
#include "hackrf_gpio.hpp"
|
#include "hackrf_gpio.hpp"
|
||||||
|
#include "portapack.hpp"
|
||||||
using namespace hackrf::one;
|
using namespace hackrf::one;
|
||||||
using namespace portapack;
|
using namespace portapack;
|
||||||
|
|
||||||
@ -43,6 +44,10 @@ void TransmitterModel::set_tuning_frequency(rf::Frequency f) {
|
|||||||
update_tuning_frequency();
|
update_tuning_frequency();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransmitterModel::set_antenna_bias() {
|
||||||
|
update_antenna_bias();
|
||||||
|
}
|
||||||
|
|
||||||
bool TransmitterModel::rf_amp() const {
|
bool TransmitterModel::rf_amp() const {
|
||||||
return rf_amp_;
|
return rf_amp_;
|
||||||
}
|
}
|
||||||
@ -114,6 +119,7 @@ void TransmitterModel::enable() {
|
|||||||
enabled_ = true;
|
enabled_ = true;
|
||||||
radio::set_direction(rf::Direction::Transmit);
|
radio::set_direction(rf::Direction::Transmit);
|
||||||
update_tuning_frequency();
|
update_tuning_frequency();
|
||||||
|
update_antenna_bias();
|
||||||
update_rf_amp();
|
update_rf_amp();
|
||||||
update_lna();
|
update_lna();
|
||||||
update_vga();
|
update_vga();
|
||||||
@ -132,6 +138,7 @@ void TransmitterModel::enable() {
|
|||||||
|
|
||||||
void TransmitterModel::disable() {
|
void TransmitterModel::disable() {
|
||||||
enabled_ = false;
|
enabled_ = false;
|
||||||
|
radio::set_antenna_bias(false);
|
||||||
|
|
||||||
// TODO: Responsibility for enabling/disabling the radio is muddy.
|
// TODO: Responsibility for enabling/disabling the radio is muddy.
|
||||||
// Some happens in ReceiverModel, some inside radio namespace.
|
// Some happens in ReceiverModel, some inside radio namespace.
|
||||||
@ -145,6 +152,11 @@ void TransmitterModel::update_tuning_frequency() {
|
|||||||
radio::set_tuning_frequency(persistent_memory::tuned_frequency());
|
radio::set_tuning_frequency(persistent_memory::tuned_frequency());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransmitterModel::update_antenna_bias() {
|
||||||
|
if (enabled_)
|
||||||
|
radio::set_antenna_bias(portapack::get_antenna_bias());
|
||||||
|
}
|
||||||
|
|
||||||
void TransmitterModel::update_rf_amp() {
|
void TransmitterModel::update_rf_amp() {
|
||||||
radio::set_rf_amp(rf_amp_);
|
radio::set_rf_amp(rf_amp_);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ public:
|
|||||||
rf::Frequency tuning_frequency() const;
|
rf::Frequency tuning_frequency() const;
|
||||||
void set_tuning_frequency(rf::Frequency f);
|
void set_tuning_frequency(rf::Frequency f);
|
||||||
|
|
||||||
|
void set_antenna_bias();
|
||||||
|
|
||||||
bool rf_amp() const;
|
bool rf_amp() const;
|
||||||
void set_rf_amp(bool enabled);
|
void set_rf_amp(bool enabled);
|
||||||
|
|
||||||
@ -74,6 +76,7 @@ private:
|
|||||||
SignalToken signal_token_tick_second { };
|
SignalToken signal_token_tick_second { };
|
||||||
|
|
||||||
void update_tuning_frequency();
|
void update_tuning_frequency();
|
||||||
|
void update_antenna_bias();
|
||||||
void update_rf_amp();
|
void update_rf_amp();
|
||||||
void update_lna();
|
void update_lna();
|
||||||
void update_baseband_bandwidth();
|
void update_baseband_bandwidth();
|
||||||
|
@ -77,6 +77,7 @@
|
|||||||
#include "png_writer.hpp"
|
#include "png_writer.hpp"
|
||||||
|
|
||||||
using portapack::receiver_model;
|
using portapack::receiver_model;
|
||||||
|
using portapack::transmitter_model;
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ SystemStatusView::SystemStatusView(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SystemStatusView::refresh() {
|
void SystemStatusView::refresh() {
|
||||||
if (receiver_model.antenna_bias()) {
|
if (portapack::get_antenna_bias()) {
|
||||||
button_bias_tee.set_bitmap(&bitmap_icon_biast_on);
|
button_bias_tee.set_bitmap(&bitmap_icon_biast_on);
|
||||||
button_bias_tee.set_foreground(ui::Color::yellow());
|
button_bias_tee.set_foreground(ui::Color::yellow());
|
||||||
} else {
|
} else {
|
||||||
@ -171,28 +172,26 @@ void SystemStatusView::on_stealth() {
|
|||||||
bool mode = not portapack::persistent_memory::stealth_mode();
|
bool mode = not portapack::persistent_memory::stealth_mode();
|
||||||
|
|
||||||
portapack::persistent_memory::set_stealth_mode(mode);
|
portapack::persistent_memory::set_stealth_mode(mode);
|
||||||
|
|
||||||
if (mode)
|
button_stealth.set_foreground(mode ? ui::Color::green() : ui::Color::light_grey());
|
||||||
button_stealth.set_foreground(ui::Color::green());
|
|
||||||
else
|
|
||||||
button_stealth.set_foreground(ui::Color::light_grey());
|
|
||||||
|
|
||||||
button_stealth.set_dirty();
|
button_stealth.set_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemStatusView::on_bias_tee() {
|
void SystemStatusView::on_bias_tee() {
|
||||||
bool antenna_bias = receiver_model.antenna_bias();
|
if (!portapack::antenna_bias) {
|
||||||
|
|
||||||
if (!antenna_bias) {
|
|
||||||
nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector ?", YESNO, [this](bool v) {
|
nav_.display_modal("Bias voltage", "Enable DC voltage on\nantenna connector ?", YESNO, [this](bool v) {
|
||||||
if (v) {
|
if (v) {
|
||||||
receiver_model.set_antenna_bias(true);
|
portapack::set_antenna_bias(true);
|
||||||
|
receiver_model.set_antenna_bias();
|
||||||
|
transmitter_model.set_antenna_bias();
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
receiver_model.set_antenna_bias(false);
|
portapack::set_antenna_bias(false);
|
||||||
|
receiver_model.set_antenna_bias();
|
||||||
|
transmitter_model.set_antenna_bias();
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ using namespace portapack;
|
|||||||
#include "io_file.hpp"
|
#include "io_file.hpp"
|
||||||
#include "io_wave.hpp"
|
#include "io_wave.hpp"
|
||||||
|
|
||||||
|
#include "baseband_api.hpp"
|
||||||
#include "rtc_time.hpp"
|
#include "rtc_time.hpp"
|
||||||
|
|
||||||
#include "string_format.hpp"
|
#include "string_format.hpp"
|
||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ using namespace portapack;
|
|||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
|
||||||
void RecordView::toggle_pitch_rssi() {
|
/*void RecordView::toggle_pitch_rssi() {
|
||||||
pitch_rssi_enabled = !pitch_rssi_enabled;
|
pitch_rssi_enabled = !pitch_rssi_enabled;
|
||||||
|
|
||||||
// Send to RSSI widget
|
// Send to RSSI widget
|
||||||
@ -51,7 +51,7 @@ void RecordView::toggle_pitch_rssi() {
|
|||||||
} else {
|
} else {
|
||||||
button_pitch_rssi.set_foreground(Color::green());
|
button_pitch_rssi.set_foreground(Color::green());
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
RecordView::RecordView(
|
RecordView::RecordView(
|
||||||
const Rect parent_rect,
|
const Rect parent_rect,
|
||||||
@ -67,18 +67,18 @@ RecordView::RecordView(
|
|||||||
{
|
{
|
||||||
add_children({
|
add_children({
|
||||||
&rect_background,
|
&rect_background,
|
||||||
&button_pitch_rssi,
|
//&button_pitch_rssi,
|
||||||
&button_record,
|
&button_record,
|
||||||
&text_record_filename,
|
&text_record_filename,
|
||||||
&text_record_dropped,
|
&text_record_dropped,
|
||||||
&text_time_available,
|
&text_time_available,
|
||||||
});
|
});
|
||||||
|
|
||||||
rect_background.set_parent_rect({ { 0, 0 }, size() });
|
rect_background.set_parent_rect({ { 0, 0 }, size() });
|
||||||
|
|
||||||
button_pitch_rssi.on_select = [this](ImageButton&) {
|
/*button_pitch_rssi.on_select = [this](ImageButton&) {
|
||||||
this->toggle_pitch_rssi();
|
this->toggle_pitch_rssi();
|
||||||
};
|
};*/
|
||||||
|
|
||||||
button_record.on_select = [this](ImageButton&) {
|
button_record.on_select = [this](ImageButton&) {
|
||||||
this->toggle();
|
this->toggle();
|
||||||
@ -100,7 +100,9 @@ void RecordView::focus() {
|
|||||||
void RecordView::set_sampling_rate(const size_t new_sampling_rate) {
|
void RecordView::set_sampling_rate(const size_t new_sampling_rate) {
|
||||||
if( new_sampling_rate != sampling_rate ) {
|
if( new_sampling_rate != sampling_rate ) {
|
||||||
stop();
|
stop();
|
||||||
|
|
||||||
sampling_rate = new_sampling_rate;
|
sampling_rate = new_sampling_rate;
|
||||||
|
baseband::set_sample_rate(sampling_rate);
|
||||||
|
|
||||||
button_record.hidden(sampling_rate == 0);
|
button_record.hidden(sampling_rate == 0);
|
||||||
text_record_filename.hidden(sampling_rate == 0);
|
text_record_filename.hidden(sampling_rate == 0);
|
||||||
@ -214,7 +216,7 @@ Optional<File::Error> RecordView::write_metadata_file(const std::filesystem::pat
|
|||||||
if( create_error.is_valid() ) {
|
if( create_error.is_valid() ) {
|
||||||
return create_error;
|
return create_error;
|
||||||
} else {
|
} else {
|
||||||
const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate));
|
const auto error_line1 = file.write_line("sample_rate=" + to_string_dec_uint(sampling_rate / 8));
|
||||||
if( error_line1.is_valid() ) {
|
if( error_line1.is_valid() ) {
|
||||||
return error_line1;
|
return error_line1;
|
||||||
}
|
}
|
||||||
@ -237,13 +239,13 @@ void RecordView::update_status_display() {
|
|||||||
text_record_dropped.set(s);
|
text_record_dropped.set(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pitch_rssi_enabled) {
|
/*if (pitch_rssi_enabled) {
|
||||||
button_pitch_rssi.invert_colors();
|
button_pitch_rssi.invert_colors();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if( sampling_rate ) {
|
if( sampling_rate ) {
|
||||||
const auto space_info = std::filesystem::space(u"");
|
const auto space_info = std::filesystem::space(u"");
|
||||||
const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate * 4);
|
const uint32_t bytes_per_second = file_type == FileType::WAV ? (sampling_rate * 2) : (sampling_rate / 8 * 4);
|
||||||
const uint32_t available_seconds = space_info.free / bytes_per_second;
|
const uint32_t available_seconds = space_info.free / bytes_per_second;
|
||||||
const uint32_t seconds = available_seconds % 60;
|
const uint32_t seconds = available_seconds % 60;
|
||||||
const uint32_t available_minutes = available_seconds / 60;
|
const uint32_t available_minutes = available_seconds / 60;
|
||||||
|
@ -64,7 +64,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void toggle();
|
void toggle();
|
||||||
void toggle_pitch_rssi();
|
//void toggle_pitch_rssi();
|
||||||
Optional<File::Error> write_metadata_file(const std::filesystem::path& filename);
|
Optional<File::Error> write_metadata_file(const std::filesystem::path& filename);
|
||||||
|
|
||||||
void on_tick_second();
|
void on_tick_second();
|
||||||
@ -73,7 +73,7 @@ private:
|
|||||||
void handle_capture_thread_done(const File::Error error);
|
void handle_capture_thread_done(const File::Error error);
|
||||||
void handle_error(const File::Error error);
|
void handle_error(const File::Error error);
|
||||||
|
|
||||||
bool pitch_rssi_enabled = false;
|
//bool pitch_rssi_enabled = false;
|
||||||
const std::filesystem::path filename_stem_pattern;
|
const std::filesystem::path filename_stem_pattern;
|
||||||
const FileType file_type;
|
const FileType file_type;
|
||||||
const size_t write_size;
|
const size_t write_size;
|
||||||
@ -85,15 +85,16 @@ private:
|
|||||||
Color::black()
|
Color::black()
|
||||||
};
|
};
|
||||||
|
|
||||||
ImageButton button_pitch_rssi {
|
/*ImageButton button_pitch_rssi {
|
||||||
{ 2, 0 * 16, 3 * 8, 1 * 16 },
|
{ 2, 0 * 16, 3 * 8, 1 * 16 },
|
||||||
&bitmap_rssipwm,
|
&bitmap_rssipwm,
|
||||||
Color::orange(),
|
Color::orange(),
|
||||||
Color::black()
|
Color::black()
|
||||||
};
|
};*/
|
||||||
|
|
||||||
ImageButton button_record {
|
ImageButton button_record {
|
||||||
{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 },
|
//{ 4 * 8, 0 * 16, 2 * 8, 1 * 16 },
|
||||||
|
{ 0 * 8, 0 * 16, 2 * 8, 1 * 16 },
|
||||||
&bitmap_record,
|
&bitmap_record,
|
||||||
Color::red(),
|
Color::red(),
|
||||||
Color::black()
|
Color::black()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
|
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2018 Furrtek
|
||||||
*
|
*
|
||||||
* This file is part of PortaPack.
|
* This file is part of PortaPack.
|
||||||
*
|
*
|
||||||
@ -28,23 +29,9 @@
|
|||||||
#include "utility.hpp"
|
#include "utility.hpp"
|
||||||
|
|
||||||
CaptureProcessor::CaptureProcessor() {
|
CaptureProcessor::CaptureProcessor() {
|
||||||
const auto& decim_0_filter = taps_200k_decim_0;
|
decim_0.configure(taps_200k_decim_0.taps, 33554432);
|
||||||
constexpr size_t decim_0_input_fs = baseband_fs;
|
decim_1.configure(taps_200k_decim_1.taps, 131072);
|
||||||
constexpr size_t decim_0_output_fs = decim_0_input_fs / decim_0.decimation_factor;
|
|
||||||
|
|
||||||
const auto& decim_1_filter = taps_200k_decim_1;
|
|
||||||
constexpr size_t decim_1_input_fs = decim_0_output_fs;
|
|
||||||
constexpr size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor;
|
|
||||||
|
|
||||||
decim_0.configure(decim_0_filter.taps, 33554432);
|
|
||||||
decim_1.configure(decim_1_filter.taps, 131072);
|
|
||||||
|
|
||||||
channel_filter_pass_f = decim_1_filter.pass_frequency_normalized * decim_1_input_fs; // 162760.416666667
|
|
||||||
channel_filter_stop_f = decim_1_filter.stop_frequency_normalized * decim_1_input_fs; // 337239.583333333
|
|
||||||
|
|
||||||
spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz;
|
|
||||||
spectrum_samples = 0;
|
|
||||||
|
|
||||||
channel_spectrum.set_decimation_factor(1);
|
channel_spectrum.set_decimation_factor(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,6 +63,10 @@ void CaptureProcessor::on_message(const Message* const message) {
|
|||||||
channel_spectrum.on_message(message);
|
channel_spectrum.on_message(message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Message::ID::SamplerateConfig:
|
||||||
|
samplerate_config(*reinterpret_cast<const SamplerateConfigMessage*>(message));
|
||||||
|
break;
|
||||||
|
|
||||||
case Message::ID::CaptureConfig:
|
case Message::ID::CaptureConfig:
|
||||||
capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message));
|
capture_config(*reinterpret_cast<const CaptureConfigMessage*>(message));
|
||||||
break;
|
break;
|
||||||
@ -85,6 +76,22 @@ void CaptureProcessor::on_message(const Message* const message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CaptureProcessor::samplerate_config(const SamplerateConfigMessage& message) {
|
||||||
|
baseband_fs = message.sample_rate;
|
||||||
|
baseband_thread.set_sampling_rate(baseband_fs);
|
||||||
|
|
||||||
|
size_t decim_0_output_fs = baseband_fs / decim_0.decimation_factor;
|
||||||
|
|
||||||
|
size_t decim_1_input_fs = decim_0_output_fs;
|
||||||
|
size_t decim_1_output_fs = decim_1_input_fs / decim_1.decimation_factor;
|
||||||
|
|
||||||
|
channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * decim_1_input_fs; // 162760.416666667
|
||||||
|
channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * decim_1_input_fs; // 337239.583333333
|
||||||
|
|
||||||
|
spectrum_interval_samples = decim_1_output_fs / spectrum_rate_hz;
|
||||||
|
spectrum_samples = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void CaptureProcessor::capture_config(const CaptureConfigMessage& message) {
|
void CaptureProcessor::capture_config(const CaptureConfigMessage& message) {
|
||||||
if( message.config ) {
|
if( message.config ) {
|
||||||
stream = std::make_unique<StreamInput>(message.config);
|
stream = std::make_unique<StreamInput>(message.config);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
|
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
* Copyright (C) 2018 Furrtek
|
||||||
*
|
*
|
||||||
* This file is part of PortaPack.
|
* This file is part of PortaPack.
|
||||||
*
|
*
|
||||||
@ -45,7 +46,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// TODO: Repeated value needs to be transmitted from application side.
|
// TODO: Repeated value needs to be transmitted from application side.
|
||||||
static constexpr size_t baseband_fs = 4000000;
|
size_t baseband_fs = 0;
|
||||||
static constexpr auto spectrum_rate_hz = 50.0f;
|
static constexpr auto spectrum_rate_hz = 50.0f;
|
||||||
|
|
||||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive };
|
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Receive };
|
||||||
@ -68,6 +69,7 @@ private:
|
|||||||
size_t spectrum_interval_samples = 0;
|
size_t spectrum_interval_samples = 0;
|
||||||
size_t spectrum_samples = 0;
|
size_t spectrum_samples = 0;
|
||||||
|
|
||||||
|
void samplerate_config(const SamplerateConfigMessage& message);
|
||||||
void capture_config(const CaptureConfigMessage& message);
|
void capture_config(const CaptureConfigMessage& message);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ ReplayProcessor::ReplayProcessor() {
|
|||||||
channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000; // 162760.416666667
|
channel_filter_pass_f = taps_200k_decim_1.pass_frequency_normalized * 1000000; // 162760.416666667
|
||||||
channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000; // 337239.583333333
|
channel_filter_stop_f = taps_200k_decim_1.stop_frequency_normalized * 1000000; // 337239.583333333
|
||||||
|
|
||||||
spectrum_interval_samples = baseband_fs / spectrum_rate_hz;
|
|
||||||
spectrum_samples = 0;
|
spectrum_samples = 0;
|
||||||
|
|
||||||
channel_spectrum.set_decimation_factor(1);
|
channel_spectrum.set_decimation_factor(1);
|
||||||
@ -86,6 +85,10 @@ void ReplayProcessor::on_message(const Message* const message) {
|
|||||||
channel_spectrum.on_message(message);
|
channel_spectrum.on_message(message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Message::ID::SamplerateConfig:
|
||||||
|
samplerate_config(*reinterpret_cast<const SamplerateConfigMessage*>(message));
|
||||||
|
break;
|
||||||
|
|
||||||
case Message::ID::ReplayConfig:
|
case Message::ID::ReplayConfig:
|
||||||
configured = false;
|
configured = false;
|
||||||
bytes_read = 0;
|
bytes_read = 0;
|
||||||
@ -102,8 +105,15 @@ void ReplayProcessor::on_message(const Message* const message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReplayProcessor::samplerate_config(const SamplerateConfigMessage& message) {
|
||||||
|
baseband_fs = message.sample_rate;
|
||||||
|
baseband_thread.set_sampling_rate(baseband_fs);
|
||||||
|
spectrum_interval_samples = baseband_fs / spectrum_rate_hz;
|
||||||
|
}
|
||||||
|
|
||||||
void ReplayProcessor::replay_config(const ReplayConfigMessage& message) {
|
void ReplayProcessor::replay_config(const ReplayConfigMessage& message) {
|
||||||
if( message.config ) {
|
if( message.config ) {
|
||||||
|
|
||||||
stream = std::make_unique<StreamOutput>(message.config);
|
stream = std::make_unique<StreamOutput>(message.config);
|
||||||
|
|
||||||
// Tell application that the buffers and FIFO pointers are ready, prefill
|
// Tell application that the buffers and FIFO pointers are ready, prefill
|
||||||
|
@ -42,7 +42,7 @@ public:
|
|||||||
void on_message(const Message* const message) override;
|
void on_message(const Message* const message) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr size_t baseband_fs = 4000000;
|
size_t baseband_fs = 0;
|
||||||
static constexpr auto spectrum_rate_hz = 50.0f;
|
static constexpr auto spectrum_rate_hz = 50.0f;
|
||||||
|
|
||||||
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Transmit };
|
BasebandThread baseband_thread { baseband_fs, this, NORMALPRIO + 20, baseband::Direction::Transmit };
|
||||||
@ -66,6 +66,7 @@ private:
|
|||||||
bool configured { false };
|
bool configured { false };
|
||||||
uint32_t bytes_read { 0 };
|
uint32_t bytes_read { 0 };
|
||||||
|
|
||||||
|
void samplerate_config(const SamplerateConfigMessage& message);
|
||||||
void replay_config(const ReplayConfigMessage& message);
|
void replay_config(const ReplayConfigMessage& message);
|
||||||
|
|
||||||
TXProgressMessage txprogress_message { };
|
TXProgressMessage txprogress_message { };
|
||||||
|
@ -75,6 +75,7 @@ public:
|
|||||||
ReplayThreadDone = 21,
|
ReplayThreadDone = 21,
|
||||||
AFSKRxConfigure = 22,
|
AFSKRxConfigure = 22,
|
||||||
StatusRefresh = 23,
|
StatusRefresh = 23,
|
||||||
|
SamplerateConfig = 24,
|
||||||
|
|
||||||
TXProgress = 30,
|
TXProgress = 30,
|
||||||
Retune = 31,
|
Retune = 31,
|
||||||
@ -751,6 +752,18 @@ public:
|
|||||||
uint32_t range = 0;
|
uint32_t range = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SamplerateConfigMessage : public Message {
|
||||||
|
public:
|
||||||
|
constexpr SamplerateConfigMessage(
|
||||||
|
const uint32_t sample_rate
|
||||||
|
) : Message { ID::SamplerateConfig },
|
||||||
|
sample_rate(sample_rate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t sample_rate = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class AudioLevelReportMessage : public Message {
|
class AudioLevelReportMessage : public Message {
|
||||||
public:
|
public:
|
||||||
constexpr AudioLevelReportMessage(
|
constexpr AudioLevelReportMessage(
|
||||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user